【问题标题】:spring and vaadin integrationspring 和 vaadin 集成
【发布时间】:2014-11-27 06:59:51
【问题描述】:

我正在尝试使用多个uis - vaadin、jsp 等实现一个应用程序。

它使用简单的jsp,但后来我决定使用 vaadin 作为 ui。

我创建了 vaadin servlet(还有 spring servlet)。 我的web.xml 看起来像这样

<?xml version="1.0"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
         version="2.5">

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            classpath:/pmc-web-context.xml
        </param-value>
    </context-param>

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <servlet>
        <servlet-name>another-pmc-servlet</servlet-name>
        <servlet-class>com.vaadin.server.VaadinServlet</servlet-class>
        <init-param>
            <param-name>UI</param-name>
            <param-value>com.xxxx.app.pmc.vaadin.PmcUi</param-value>
        </init-param>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value></param-value>
        </init-param>
    </servlet>

    <servlet>
        <servlet-name>pmc-servlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value></param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>another-pmc-servlet</servlet-name>
        <url-pattern>/VAADIN/*</url-pattern>
    </servlet-mapping>

    <servlet-mapping>
        <servlet-name>pmc-servlet</servlet-name>
        <url-pattern>/JSP/*</url-pattern>
    </servlet-mapping>

    <servlet>
        <servlet-name>jsp</servlet-name>
        <servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>jsp</servlet-name>
        <url-pattern>/WEB-INF/jsp/*</url-pattern>
    </servlet-mapping>

</web-app>

我创建了 vaadin table 组件并根据我的需要对其进行了调整。我使用自动装配服务。

package com.xxxx.app.pmc.vaadin.components;

import com.xxxx.app.pmc.model.Project;
import com.xxxx.app.pmc.service.project.ProjectService;
import com.vaadin.data.util.IndexedContainer;
import com.vaadin.ui.Table;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.List;

@Component("projectTable")
public class ProjectTable extends Table {

    private static final String CAPTION = "Projects";
    private static final String[] headers = { "Project name", "Project owner", "ID" };

    @Autowired
    private ProjectService projectService;

    public Table createTable() {
        this.setContainerDataSource(projectDatasource());
        this.setVisibleColumns(headers);
        this.setSelectable(true);
        this.setImmediate(true);

        return this;
    }

    public IndexedContainer projectDatasource() {
        IndexedContainer indexedContainer = new IndexedContainer();

        for(String header: headers) {
            indexedContainer.addContainerProperty(header, String.class, "");
        }

        List<Project> projects = projectService.findAllProjects();

        for(int i = 0; i < projects.size(); i++) {
            Object id = indexedContainer.addItem();
            Project item = projects.get(i);
            indexedContainer.getContainerProperty(id, headers[0]).setValue(item.getProjectName());
            indexedContainer.getContainerProperty(id, headers[1]).setValue(item.getProjectOwner());
            indexedContainer.getContainerProperty(id, headers[1]).setValue(item.getProjectId());
        }

        return indexedContainer;
    }

}

ProjectService 也是春豆。

@Service("projectService")
public class ProjectService {

    @Autowired
    private ProjectRepository projectRepository;

    public void insertProject(Project project) {
        projectRepository.store(project);
    }

    public List<Project> findAllProjects() {
        return projectRepository.getAllItems();
    }

    public Project getProject(String id) {
        return projectRepository.get(id);
    }

}

ProjectRepository 是另一个spring bean。它使用来自 MyBatis 的 SqlSessionTemplate bean。

@Repository("projectRepository")
public class ProjectRepository implements IRepository<Project> {

    private static final String STORE_PROJECT = "Project.insertProject";
    private static final String GET_PROJECT_BY_ID = "Project.getProjectById";
    private static final String GET_PROJECT_LIST = "Project.getProjectList";

    @Autowired
    private SqlSessionTemplate sqlSessionTemplate;

    @Override
    public void store(Project object) {
        sqlSessionTemplate.insert(STORE_PROJECT, object);
    }

    @Override
    public Project get(String id) {
        return sqlSessionTemplate.selectOne(GET_PROJECT_BY_ID, id);
    }

    @Override
    public List<Project> getAllItems() {
        return sqlSessionTemplate.selectList(GET_PROJECT_LIST);
    }

} 

当我使用 spring controller(使用 JSP)编写应用程序时,它运行良好。 但是当我添加 vaadin - JSP 停止工作并且 vaadin 应用程序为 ProjectServiceProjectRepository 抛出 NullPointerException... 我使用的所有 bean。

有什么问题? 我所有的上下文xml 上下文文件都很简单。

<import resource="classpath:com/xxxx/app/pmc/pmc-service-context.xml"/>
<context:component-scan base-package="com.xxx.app.pmc"/>

我的pmc-web-context.xml 也有这行。

<mvc:annotation-driven/>
<context:annotation-config/>

它在 JSP 上运行良好,所以我认为问题不在于 spring 声明本身,而是将 spring 集成到我的 vaadin 中。

如何解决? 例如,当我手动创建ProjectTable 对象时,它会为ProjectService 抛出NullPointerException。当我手动创建ProjectService 时,它会为ProjectRepository 抛出NullPointerException 等等。似乎自动装配根本不起作用。

P.S 忘记添加我的 UI 代码

package com.xxxx.app.pmc.vaadin;

import com.xxxx.app.pmc.vaadin.components.ProjectTable;
import com.vaadin.annotations.Title;
import com.vaadin.server.VaadinRequest;
import com.vaadin.ui.UI;
import com.vaadin.ui.VerticalLayout;

import org.springframework.stereotype.Component;

@Title("PMC")
@Component("pmcVaadin")
public class PmcUi extends UI {

    @Override
    protected void init(VaadinRequest request) {
        VerticalLayout mainLayout = new VerticalLayout();
        ProjectTable projectTable = new ProjectTable();
        mainLayout.addComponent(projectTable.createTable());
        mainLayout.setSizeFull();
        setContent(mainLayout);
    }

}

【问题讨论】:

    标签: java spring servlets vaadin


    【解决方案1】:

    就像您怀疑您的 Spring bean 是在应用程序和 Spring 的 servlet 上下文中创建的一样。您的 Vaadin servlet 无权访问其中任何一个。

    对于带有代码的详细(手动)解决方案,请查看 Vaadin's wiki 或搜索合适的 Vaadin's add ons 来为您完成这项工作(我个人推荐 SpringVaadinIntegration)。

    典型的想法是以编程方式将 Vaadin servlet 传递给 Spring 的实用程序类之一(例如:WebApplicationContextUtils)并检索应用程序上下文(由 ContextLoaderListener 加载)。如果您需要 servlet 上下文,那么从我看到的代码示例中,您可以执行与上述相同的操作,但还要手动读取上下文(例如:使用 XmlWebApplicationContext)并将应用程序上下文设置为父级。

    【讨论】:

      【解决方案2】:

      非常简单的选择是使用可配置支持。它会做一些方面的魔法,所有由@Configurable 注释的java 对象都将自动集成到Spring 中。您可以在Spring documentation 中找到更多详细信息。另请注意,要在 GUI 中表示上下文信息,您必须使用会话 bean。这会导致会话大小问题,并且在更大的应用程序中无法进行集群。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-02-11
        • 2015-10-05
        • 2011-12-29
        • 1970-01-01
        • 2015-05-27
        • 2012-12-29
        • 1970-01-01
        相关资源
        最近更新 更多