【问题标题】:Spring bean injection not working properlySpring bean 注入无法正常工作
【发布时间】:2015-09-09 09:30:36
【问题描述】:

我正在尝试在 maven 3.3.3 中创建一个 Spring + jersey 项目。战争部署成功。但在 Rest 服务类中,bean 注入不起作用。我正在使用二传手注入。 我收到错误

Sep 09, 2015 1:49:23 PM com.sun.jersey.spi.container.ContainerResponse mapMappableContainerException
SEVERE: The RuntimeException could not be mapped to a response, re-throwing to the HTTP container
java.lang.NullPointerException
    at com.marvel.scheduler.services.rest.impl.SchedulerWebServiceImpl.authenticate(SchedulerWebServiceImpl.java:308)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at com.sun.jersey.spi.container.JavaMethodInvokerFactory$1.invoke(JavaMethodInvokerFactory.java:60)
    at com.sun.jersey.server.impl.model.method.dispatch.AbstractResourceMethodDispatchProvider$ResponseOutInvoker._dispatch(AbstractResourceMethodDispatchProvider.java:205)
    at com.sun.jersey.server.impl.model.method.dispatch.ResourceJavaMethodDispatcher.dispatch(ResourceJavaMethodDispatcher.java:75)
    at com.sun.jersey.server.impl.uri.rules.HttpMethodRule.accept(HttpMethodRule.java:288)
    at com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:147)
    at com.sun.jersey.server.impl.uri.rules.ResourceClassRule.accept(ResourceClassRule.java:108)
    at com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:147)
    at com.sun.jersey.server.impl.uri.rules.RootResourceClassesRule.accept(RootResourceClassesRule.java:84)
    at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1469)
    at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1400)
    at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1349)
    at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1339)
    at com.sun.jersey.spi.container.servlet.WebComponent.service(WebComponent.java:416)
    at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:537)
    at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:699)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:504)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:421)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1074)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:611)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:316)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Unknown Source)

我的 web.xml 是

<?xml version="1.0" encoding="UTF-8"?>
<!-- This web.xml file is not required when using Servlet 3.0 container, 
 see implementation details http://jersey.java.net/nonav/documentation/latest/jax-rs.html#d4e194 -->
<web-app version="2.5" 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">

<display-name>Marvel Health Scheduler</display-name>
<description>Appointments Scheduler Software for Marvel-Health</description>
<!--
  - Key of the system property that should specify the root directory of this
  - web app. Applied by WebAppRootListener or Log4jConfigListener.
  -->
<context-param>
    <param-name>webAppRootKey</param-name>
    <param-value>aFSchedulerMaven.root</param-value>
</context-param>
<!--
  - Location of the Log4J config file, for initialization and refresh checks.
  - Applied by Log4jConfigListener.
  -->
<context-param>
    <param-name>log4jConfigLocation</param-name>
    <param-value>/WEB-INF/classes/log4j.properties</param-value>
</context-param>


<listener>
    <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/classes/marvemr-servlet.xml /WEB-INF/classes/dataAccessContext-local.xml /WEB-INF/classes/dataAccessContext-Extra.xml
    </param-value>
</context-param>

<servlet>
    <servlet-name>context</servlet-name>
    <servlet-class>org.springframework.web.context.ContextLoaderServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>


<servlet>
    <servlet-name>JerseyRESTServlet</servlet-name>
    <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
    <init-param>
        <param-name>com.sun.jersey.config.property.packages</param-name>
        <param-value>com.marv.scheduler.services.rest.impl</param-value>
    </init-param>

    <init-param>
        <param-name>com.sun.jersey.spi.container.ContainerResponseFilters</param-name>
        <param-value>com.marv.scheduler.services.rest.responsefilter.ResponseCorsFilter</param-value>
    </init-param>

    <init-param>
        <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
        <param-value>true</param-value>
    </init-param>

    <load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>JerseyRESTServlet</servlet-name>
    <url-pattern>/rest/*</url-pattern>
</servlet-mapping>

<session-config>
    <session-timeout>60</session-timeout>
</session-config>

<welcome-file-list>
    <!-- Redirects to "welcome.htm" for dispatcher handling -->
    <welcome-file>index.html</welcome-file>
</welcome-file-list>

<error-page>
    <error-code>404</error-code>
    <location>/errorpage.html</location>
</error-page>

我的休息服务层类是:

@Path("schedulerservices")
@Produces(MediaType.APPLICATION_JSON)
public class SchedulerWebServiceImpl{
private ErrorMessage errorMessage;
private Logger logger;
private SchedulerService schedulerService;
private CommonService commonService;
private PerformanceLogger performanceLogger;    

public void setErrorMessage(ErrorMessage errorMessage) {
    this.errorMessage = errorMessage;
}

public void setLogger(Logger logger) {
    this.logger = logger;
}

public void setAdminService(SchedulerService schedulerService) {
    this.schedulerService = schedulerService;
}

public void setCommonService(CommonService commonService) {
    this.commonService = commonService;
}

public void setPerformanceLogger(PerformanceLogger performanceLogger) {
    this.performanceLogger = performanceLogger;
}

我的 pom.xml 是

<dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring</artifactId>
        <version>2.5.6</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-support</artifactId>
        <version>2.0.6</version>
    </dependency>

我的 bean 注入 xml 是:

<bean id="restRootWebService" class="com.marvel.scheduler.services.rest.impl.SchedulerWebServiceImpl" >
    <property name="errorMessage"><ref bean="errorMessage" /></property>
    <property name="logger"><ref bean="logger" /></property>
    <property name="schedulerService"><ref bean="adminService" /></property>
    <property name="commonService"><ref bean="commonService" /></property>
    <property name="performanceLogger"><ref bean="performanceLogger" /></property>
</bean>

请帮我找出解决办法...

  @POST 
    @Path("login") 
    @Consumes(MediaType.APPLICATION_JSON) 
    public Response authenticate(AuthenticateInputParam authenticateInputParam) throws java.rmi.RemoteException {
    AuthenticateOutput authenticateOutput = schedulerService.authenticate(authenticateInputParam); // this is the code 308
    if (authenticateOutput !=null) 
        return Response.ok(authenticateOutput).status(200).build();
    }

【问题讨论】:

  • 我可以在您的堆栈跟踪中看到NullPointerException。请使用调试器找到确切的行。确定问题。创建minimal reproducible example 来描述您的问题。
  • 对于初学者来说,停止混合来自不同弹簧版本的罐子......
  • com.marvel.scheduler.services.rest.impl.SchedulerWebServiceImpl 你的班级吗?如果可以,您能否发布 authenticate 方法并标记哪一行是 308?
  • Spring 无法控制您的 bean,您的 bean 配置是无用的,因为 Jersey 控制着 bean 的生命周期。正确设置 Spring Jersey 集成。
  • @user902383 @POST @Path("login") @Consumes(MediaType.APPLICATION_JSON) public Response authenticate(AuthenticateInputParam authenticateInputParam) throws java.rmi.RemoteException { AuthenticateOutput authenticateOutput = schedulerService.authenticate(authenticateInputParam); // 这是代码 308 ` if (authenticateOutput !=null) return Response.ok(authenticateOutput).status(200).build(); }`

标签: java xml spring maven jersey


【解决方案1】:

您是否考虑过构造函数注入而不是 setter 注入?这使得滥用您的服务变得更加困难,因为在提供所有依赖项之前您无法拥有实例。

private final ErrorMessage errorMessage;
private final Logger logger;
private final SchedulerService schedulerService;
private final CommonService commonService;
private final PerformanceLogger performanceLogger; 

public SchedulerWebServiceImpl( 
     ErrorMessage errorMessage,
     Logger logger,
     SchedulerService schedulerService,
     CommonService commonService,
     PerformanceLogger performanceLogger
) {
     // set all final fields
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-12
    • 2019-09-12
    相关资源
    最近更新 更多