有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java GWT+Spring Boot@Autowired不工作

我已经在GWT+Spring Boot中创建了一个应用程序,当我尝试使用@Autowired-我得到NullPointerException。显然@Autowired不起作用,也没有将bean插入正确的位置。我怎样才能解决这个问题

分派传入RPC调用时发生异常

com.google.gwt.user.server.rpc.UnexpectedException: Service method 'public abstract java.util.List com.myGWT.springbootapp.client.UserService.list()' threw an unexpected exception: java.lang.NullPointerException

文件web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">

    <servlet>
        <servlet-name>userService</servlet-name>
        <servlet-class>com.myGWT.springbootapp.server.UserServiceImpl</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>userService</servlet-name>
        <url-pattern>/gwtApp/service</url-pattern>
    </servlet-mapping>


    <welcome-file-list>
        <welcome-file>GWTApp.html</welcome-file>
    </welcome-file-list>
</web-app>

波姆。xml

<name>spring-boot-app</name>
    <description>Demo project for Spring Boot</description>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.3.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->

    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <gwt.version>2.7.0</gwt.version>
    </properties>

    <dependencies>
        <!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-api -->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-api</artifactId>
            <version>2.8</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-core -->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>2.8</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.apache.logging.log4j</groupId>
                    <artifactId>log4j-api</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-tomcat</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>


        <dependency>
            <groupId>com.oracle</groupId>
            <artifactId>ojdbc6</artifactId>
            <version>11.2.0.4</version>
        </dependency>

        <!-- GWT -->
        <dependency>
            <groupId>com.google.gwt</groupId>
            <artifactId>gwt-user</artifactId>
            <version>${gwt.version}</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>com.google.gwt</groupId>
            <artifactId>gwt-servlet</artifactId>
            <version>${gwt.version}</version>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>com.google.gwt</groupId>
            <artifactId>gwt-codeserver</artifactId>
            <version>${gwt.version}</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>com.google.gwt</groupId>
            <artifactId>gwt-dev</artifactId>
            <version>${gwt.version}</version>
            <scope>provided</scope>
            <exclusions>
            <exclusion>
                <artifactId>apache-jsp</artifactId>
                <groupId>org.eclipse.jetty</groupId>
            </exclusion>
            </exclusions>
        </dependency>
    </dependencies>



    <build>
        <pluginManagement>
            <plugins>
                <plugin>
                    <groupId>org.codehaus.mojo</groupId>
                    <artifactId>gwt-maven-plugin</artifactId>
                    <version>${gwt.version}</version>
                </plugin>
                <plugin>
                    <artifactId>maven-war-plugin</artifactId>
                    <version>2.5</version>
                </plugin>
                <plugin>
                    <artifactId>maven-clean-plugin</artifactId>
                    <version>2.4.1</version>
                </plugin>
            </plugins>
        </pluginManagement>
        <plugins>
            <plugin>
                <artifactId>maven-clean-plugin</artifactId>
                <configuration>
                    <filesets>
                        <fileset>
                            <directory>target</directory>
                        </fileset>
                        <fileset>
                            <directory>builds</directory>
                            <includes>
                                <include>**/*.*</include>
                            </includes>
                        </fileset>
                    </filesets>
                </configuration>
            </plugin>
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.2</version>
                <configuration>
                    <source>1.7</source>
                    <target>1.7</target>
                </configuration>
            </plugin>
            <plugin>
                <artifactId>maven-source-plugin</artifactId>
                <version>2.4</version>
                <executions>
                    <execution>
                        <id>attach-sources</id>
                        <phase>deploy</phase>
                        <goals>
                            <goal>jar-no-fork</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <artifactId>maven-deploy-plugin</artifactId>
                <version>2.8.2</version>
                <executions>
                    <execution>
                        <id>deploy</id>
                        <phase>deploy</phase>
                        <goals><goal>deploy</goal></goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

文件UserServiceImpl.java

package com.myGWT.springbootapp.server;

import com.myGWT.springbootapp.client.UserService;
import com.myGWT.springbootapp.entities.User;
import com.myGWT.springbootapp.repositories.UserRepository;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class UserServiceImpl extends RemoteServiceServlet implements UserService {

AnnotationConfigWebApplicationContext();

    @Autowired
    private UserRepository repository ;

    @Override
    public List<User> list() {
        return repository.findAll();
    }
}

文件UserRepository.java

package com.myGWT.springbootapp.repositories;


import com.myGWT.springbootapp.entities.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;

import java.util.List;
@Repository
public interface UserRepository extends JpaRepository<User, Long> {

}

文件UserService.java

package com.myGWT.springbootapp.client;

import com.myGWT.springbootapp.entities.User;
import com.google.gwt.user.client.rpc.RemoteService;
import com.google.gwt.user.client.rpc.RemoteServiceRelativePath;


import java.util.List;

@RemoteServiceRelativePath("service")
public interface UserService extends RemoteService {

  List<User> list();
}

文件GWTApp.java

package com.myGWT.springbootapp.client;

import com.myGWT.springbootapp.entities.User;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.cellview.client.CellTable;
import com.google.gwt.user.cellview.client.TextColumn;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.*;
import com.google.gwt.view.client.ListDataProvider;

import java.util.List;

public class GWTApp implements EntryPoint {

    private  UserServiceAsync userService = GWT.create(UserService.class);

    private ListDataProvider<User> createTable (CellTable<User> table){
        TextColumn<User> idColumn =new TextColumn<User>() {
            @Override
            public String getValue(User object) {
                return object.getId().toString();
            }
        };
        TextColumn<User> loginColumn =new TextColumn<User>() {
            @Override
            public String getValue(User object) {
                return object.getLogin();
            }
        };
        table.addColumn(idColumn, "Id");
        table.addColumn(loginColumn, "Login");
        final ListDataProvider<User> dataProvider = new ListDataProvider<>();
        dataProvider.addDataDisplay(table);
        this.userService.list(new AsyncCallback<List<User>>() {
            @Override
            public void onFailure(Throwable caught) {
                Window.alert("Error: " + caught.getMessage());
            }

            @Override
            public void onSuccess(List<User> result) {
                dataProvider.getList().addAll(result);

            }
        });
        return dataProvider;
    }

    public void onModuleLoad() {
        CellTable<User> table = new CellTable<>();
        ListDataProvider<User> dataProvider = createTable(table);

        RootPanel.get().add(table);
    }
}

项目的目录结构

enter image description here


共 (1) 个答案

  1. # 1 楼答案

    简单的回答是:Spring没有实例化您的GWT服务;因此,它无法将任何内容自动连接到其中

    Jetty容器实际上负责创建和映射UserServiceImpl的实例。这就是你的web.xml所描述的

    您的@Service注释确实像您预期的那样在Spring上下文中创建了一个Servlet实例,但Jetty并不知道它。过去,我从基于RemoteServiceServlet的服务中删除了@Service注释,并添加了以下方法来提供@Autowire支持:

    public class UserServiceImpl extends RemoteServiceServlet implements UserService {
    
    ...
    
         @Override
         public void init() throws ServletException {
              super.init();
              SpringBeanAutowiringSupport.processInjectionBasedOnServletContext(this, getServletContext());
         }
    
    ...
    
    }
    

    SpringBeanAutowiringSupport{a1}

    Process @Autowired injection for the given target object, based on the current root web application context as stored in the ServletContext.

    Jetty将在Servlet创建和boom期间调用init(),您就是Bean的集合。这是一个令人不快的方面,因为它连接了两个不相关的过程,但它目前正在生产中为我工作

    使用与Servlet 3.0+兼容的容器,您可能会找到一种方法,在映射Servlet之前,使用WebApplicationInitializerjavadoc)通过AnnotationConfigWebApplicationContextjavadoc)启动Spring上下文,从而允许您从那里使用实例(这将取代web.xml

    编辑:

    因为您使用的是Spring Boot,所以可以浏览一下这个线程,它展示了如何通过ServletRegistrationBeanHow can I register a secondary servlet with Spring Boot?映射servlet(参见checketts的答案)