我有一个弹簧组件,它曾被用作flex blazeds端点(使用@RemotingDestination
),现在我需要将其重新用作REST端点。
我所做的是除了现有的blaze dsservlet之外,还创建了一个额外的rest servlet(courser的类型为DispatcherServlet
)。
然后我想使用REST访问相同的组件(因此我之前的问题),我发现我得到了404。
我的rest-servlet.xml配置文件看起来像:
<mvc:annotation-driven />
<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" />
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="messageConverters">
<list>
<ref bean="jsonConverter" />
</list>
</property>
</bean>
<bean id="jsonConverter" class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
<property name="supportedMediaTypes" value="application/json" />
</bean>
我的ContextLoaderListener
使用了我所有的spring上下文文件,其中包括这些组件的组件扫描。
由于flex servlet访问全局上下文扫描的@Component bean没有问题,我假设rest servlet也可以访问它们,我只需要向组件添加注释。
奇怪的是,当我明确地为这些组件所在的包添加组件扫描时,rest调用就工作了。
这意味着这些组件bean被创建了两次,一次用于全局上下文(因为它扫描了一个包含flex servlet扫描的配置文件),另一次用于rest servlet上下文(我用一个简单的静态计数器和类上的锁验证了这一点)。
我的问题是,为什么rest servlet不能看到flex servlet所能看到的bean?
虽然servlet appcontext确实可以从ContextLoaderListener
appcontext访问bean,但在将HTTP调用映射到控制器时,不会咨询这些bean。所有控制器bean必须直接在servlet的appcontext中声明(或扫描),否则它们将被忽略。
我建议您将REST入口点注释(即@RequestMapping
)与BlazeDS注释分开。例如,以另一篇文章中的UserService
类为例:创建一个UserController
类,在上面放置REST注释,然后从UserController
委托给UserService
。UserController
将在servlet应用程序上下文中声明,并从ContextLoaderListener
上下文注入UserService
。
您需要使用SpringWeb上下文并定义DispatcherServlet,它将是ContextLoaderListener加载的子上下文。
应该加载rest-servlet.xml的是DistpatcherServlet,而不是ContextLoaderListener。否则,那些你称之为"servlet"的人,事实上,我认为他们是控制器,就是不会从你的客户端收到请求。
你可以在这里阅读所有这些内容:http://static.springsource.org/spring/docs/3.1.0.RC1/spring-framework-reference/html/mvc.html
这是在Spring中做与Web相关的事情的标准方法,您显然需要遵循它