You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

非Boot Spring项目迁移至Spring 6+Jakarta后RESTEasy注入空指针问题

问题描述

将非Spring Boot的Spring Framework项目迁移至Spring 6、Java 17及Jakarta规范后,更换兼容Spring 6的RESTEasy依赖,RESTEasy API可正常访问,但@Autowired注解注入的类出现java.lang.NullPointerException。

错误日志

RESTEASY002375: Error processing request POST /application/api/rest/rjob/startjob - com.application.rest.server.JobServerProvider.startJob --- o.j.r.c.p.DefaultExceptionMapper:90 --- [http-nio-8080-exec-1]
java.lang.NullPointerException: Cannot invoke "com.application.rest.server.RequestValidator.isRequestValid(jakarta.servlet.http.HttpServletRequest)" because "this.requestValidator" is null

依赖变更

旧RESTEasy依赖

  • groupId: org.jboss.resteasy,artifactId: resteasy-jaxrs
  • groupId: org.jboss.resteasy,artifactId: resteasy-spring

新RESTEasy依赖

  • groupId: org.jboss.resteasy,artifactId: resteasy-core
  • groupId: org.jboss.resteasy,artifactId: resteasy-servlet-initializer
  • groupId: org.jboss.resteasy,artifactId: resteasy-client
  • groupId: org.jboss.resteasy,artifactId: resteasy-client-api

配置变更

旧配置

web.xml

<servlet>
    <servlet-name>rest</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/appContext.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

appContext.xml

<import resource="classpath:springmvc-resteasy.xml"/>

<context:component-scan base-package="com.application.ws"/>
<context:component-scan base-package="com.application.rest"/>

新配置

web.xml

<!-- Resteasy JAX-RS Servlet -->
<servlet>
    <servlet-name>resteasy-servlet</servlet-name>
    <servlet-class>org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/appContext.xml</param-value>
    </init-param>
    <init-param>
        <param-name>jakarta.ws.rs.Application</param-name>
        <param-value>com.application.rest.server.RestServerApplication</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>resteasy-servlet</servlet-name>
    <url-pattern>/rest/*</url-pattern>
</servlet-mapping>

<servlet>
    <servlet-name>rest</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/appContext.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

appContext.xml

<bean class="org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter"/>

<!-- <import resource="classpath:springmvc-resteasy.xml"/> -->
<bean id="resteasyDispatcher"
      class="org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher"/>

<context:component-scan base-package="com.application.ws"/>
<context:component-scan base-package="com.application.rest"/>

解决方案

1. 补充RESTEasy与Spring整合的核心依赖

新依赖中缺少了适配Spring 6的resteasy-spring6组件,它是实现RESTEasy与Spring上下文打通的关键。没有该依赖时,RESTEasy会自行创建JAX-RS资源实例,无法访问Spring容器中的Bean,导致@Autowired注入失效。

添加以下依赖(版本与其他RESTEasy组件保持一致):

<dependency>
    <groupId>org.jboss.resteasy</groupId>
    <artifactId>resteasy-spring6</artifactId>
    <version>${resteasy.version}</version>
</dependency>

2. 调整配置,确保RESTEasy复用Spring上下文

当前配置同时启动了RESTEasy的HttpServletDispatcher和Spring的DispatcherServlet,两者上下文完全隔离,导致RESTEasy管理的资源无法获取Spring Bean。可选择以下两种方案:

方案一:恢复基于Spring DispatcherServlet的配置

移除web.xml中独立的resteasy-servlet配置,保留原有的Spring DispatcherServlet处理所有REST请求,同时恢复Spring与RESTEasy的整合配置:

修改后的web.xml

<servlet>
    <servlet-name>rest</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/appContext.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>rest</servlet-name>
    <url-pattern>/rest/*</url-pattern>
</servlet-mapping>

修改后的appContext.xml

<import resource="classpath:springmvc-resteasy.xml"/>

<bean class="org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter"/>

<context:component-scan base-package="com.application.ws"/>
<context:component-scan base-package="com.application.rest"/>

方案二:让RESTEasy Servlet使用Spring管理的资源

如果要保留HttpServletDispatcher,需配置RESTEasy从Spring容器中获取资源实例:

  1. 在appContext.xml中添加RESTEasy Spring整合处理器:
<bean class="org.jboss.resteasy.plugins.spring.SpringBeanProcessor"/>
  1. 确保JobServerProvider等JAX-RS资源类添加了@Component(或@Service)注解,被Spring的component-scan扫描到:
@Component
@Path("/rjob")
public class JobServerProvider {

    @Autowired
    private RequestValidator requestValidator;

    // 业务方法
}

3. 验证初始化日志

启动项目后,检查日志确认Spring容器成功初始化RequestValidator和JobServerProvider,且RESTEasy正确识别了Spring管理的资源实例。


内容的提问来源于stack exchange,提问作者Amaan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 10:25:06