有 Java 编程相关的问题?

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

java RESTEasy不会将我的SpringBean映射到定制SpringContextLoader

  • RESTEasy 2.0.1GA
  • Java 1.6
  • Spring 3.0.3

我已经尽了我所能,但对所发生的一切一无所知。我有一个springmvc应用程序,但是我希望在springmvc应用程序之外有一些RESTEasy端点可用,但是在同一个容器中,最终能够连接到同一个bean中

作为第一步,我只是尝试在容器中使用RESTEasy,为来自Spring配置的bean的请求提供服务。我试过使用说明书中的样板文件,也试过手动设置,但都没有用

豆子

@Resource
@Path("/")
public class NeighborComparison {

    private String foo;

    @GET @Path(value="customer") @Produces("text/plain")
    public String getNeighborComparison() {
        return "foo";
    }
}

web.xml

<context-param>
    <param-name>resteasy.servlet.mapping.prefix</param-name>
    <param-value>/api</param-value>
</context-param>

<listener>
    <listener-class>org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap</listener-class>
</listener>

<!-- NOT configuring SpringContextLoaderListener because I declare my own, so if I do, everything
     blows up, plus  all it actually does is sanity check configuration -->
<listener>
    <listener-class>com.example.MyCustomContextLoaderListener</listener-class>
</listener>

<servlet>
    <servlet-name>Resteasy</servlet-name>
    <servlet-class>org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher</servlet-class>
</servlet>

<servlet-mapping>
    <servlet-name>Resteasy</servlet-name>
    <url-pattern>/api/*</url-pattern>
</servlet-mapping>

applicationContext.xml

<bean id="resteasy.providerFactory" class="org.jboss.resteasy.spi.ResteasyProviderFactory"
      factory-method="getInstance">
</bean>

<bean id="resteasy.dispatcher" class="org.jboss.resteasy.core.SynchronousDispatcher">
    <constructor-arg ref="resteasy.providerFactory"/>
</bean>

<bean id="resteasy.spring.bean.processor" class="org.jboss.resteasy.plugins.spring.SpringBeanProcessor">
    <description>
        Add Resources and @Providers to the appropriate places
        in Resteasy's infrastructure
    </description>
    <constructor-arg ref="resteasy.dispatcher"/>
</bean>

<bean id="neighborComparison" class="opower.api.customer.neighbor_comparison.NeighborComparison">
</bean>

根据文档,我所要做的就是“通过分配org.jboss.RESTeasy.plugins.spring.SpringBeanProcessor的实例手动注册RESTeasy BeanFactory后处理器”。我相信这个spring配置可以做到这一点

Jetty启动,应用程序上下文启动,没有任何问题。应用程序正常工作,但是当我

> curl -H"Accept: text/plain" localhost:8080/ei/api/customer

(“ei”是应用程序上下文)。日志显示(此项和仅此项):

2011-03-29 16:44:24,153 DEBUG [qtp-575315405-0] [EI] [] [asy.core.SynchronousDispatcher] PathInfo: /customer
2011-03-29 16:44:24,156 DEBUG [qtp-575315405-0] [EI] [] [asy.core.SynchronousDispatcher] Failed executing GET /customer
org.jboss.resteasy.spi.NotFoundException: Could not find resource for relative : /customer of full path: http://localhost:8080/ei/api/customer

即使我能让RESTEasy向我展示映射,它似乎也没有发现我的bean

如果我通过resteasy.resources上下文参数显式地映射它,它就可以工作,尽管显然无法访问自动连接的Springbean

还有什么我可以试试的吗?我在整个RESTEasy代码库上都有调试日志,没有收到任何消息。我还确认Spring实际上正在创建我的bean,所以RESTEasy没有找到它


共 (1) 个答案

  1. # 1 楼答案

    您的资源类需要使用@Path注释进行注释,以便在引导过程中轻松获取:

    @Path("/customer")
    @Resource
    public class NeighborComparison {
    
        @GET @Path("/{customerId}") @Produces("text/plain")
        public String getNeighborComparison(@PathParam("customerId") long customerId) {
            return "foo";
        }
    }
    

    请注意@Path("/{customerId}}注释,如果没有它,@PathParam参数将无法正确映射,从而导致非常详细的异常(以及客户端附带的500响应)。当然,假设服务是由RESTeasy提供的

    此外,如果不使用RESTeasy的SpringContextLoader,则必须确保SpringBeanProcessor实例已注册到ApplicationContext。RESTeasy通过在SpringContextLoader中注册一个ApplicationListener来委托它:

      ApplicationListener listener = new ApplicationListener() {
         public void onApplicationEvent(ApplicationEvent event) {
            if (event instanceof ContextRefreshedEvent) {
               ContextRefreshedEvent cre = (ContextRefreshedEvent) event;
               ConfigurableListableBeanFactory autowireCapableBeanFactory = (ConfigurableListableBeanFactory) cre
                     .getApplicationContext().getAutowireCapableBeanFactory();
               new SpringBeanProcessor(dispatcher, registry, providerFactory)
                     .postProcessBeanFactory(autowireCapableBeanFactory);
            }
         }
      };
      configurableWebApplicationContext.addApplicationListener(listener);
    

    如果使用自定义上下文加载器而不是RESTEasy提供的而不是,则此代码必须出现在上下文加载器中的某个位置,以便将所有内容连接起来。有点复杂,是的。是SpringBeanProcessor遍历了所有springbean和RESTeasy寄存器,这些bean和寄存器在其层次结构(类型和相应的接口)中的某处具有@Path注释