Java 构建在Spring3(m3)上的REST全注释服务的最小配置是什么?

Java 构建在Spring3(m3)上的REST全注释服务的最小配置是什么?,java,spring,tomcat,rest,jax-rs,Java,Spring,Tomcat,Rest,Jax Rs,我试图公开一个REST完整服务(由Tomcat托管),但无法确定Spring3(M3)需要什么配置 这是(示例)服务的外观: @Controller @Scope("prototype") public class UsersController { @RequestMapping(value="/users/hello", method=RequestMethod.GET) public String hello() { return "hello, u

我试图公开一个REST完整服务(由Tomcat托管),但无法确定Spring3(M3)需要什么配置

这是(示例)服务的外观:

@Controller
@Scope("prototype")
public class UsersController
{
    @RequestMapping(value="/users/hello", method=RequestMethod.GET)
    public String hello()
    {
        return "hello, user!";
    }
}
我的Spring配置如下所示(为了简单起见,我省略了完整的类名):

令我沮丧的是,我在日志文件中看到的不是“hello,user!”的回复,而是以下错误:

09:54:45,140 DEBUG RequestContextListener:69 - Bound request context to thread: org.apache.catalina.connector.RequestFacade@19299f5
09:54:45,140 DEBUG DispatcherServlet:834 - DispatcherServlet with name 'dispatcher' determining Last-Modified value for [/myserver/services/users/hello]
09:54:45,156 DEBUG DefaultAnnotationHandlerMapping:178 - Mapping [/users/hello] to handler 'com.symantec.repserver.myserver.UsersController@21447f'
09:54:45,171 DEBUG DispatcherServlet:850 - Last-Modified value for [/myserver/services/users/hello] is: -1
09:54:45,171 DEBUG DispatcherServlet:683 - DispatcherServlet with name 'dispatcher' processing GET request for [/myserver/services/users/hello]
09:54:45,218 DEBUG HandlerMethodInvoker:148 - Invoking request handler method: public java.lang.String com.symantec.repserver.myserver.UsersController.hello()
09:54:45,218 DEBUG DefaultListableBeanFactory:1366 - Invoking afterPropertiesSet() on bean with name 'hello, user!'
09:54:45,218 DEBUG DispatcherServlet:1060 - Rendering view [org.springframework.web.servlet.view.InternalResourceView: name 'hello, user!'; URL [hello, user!]] in DispatcherServlet with name 'dispatcher'
09:54:45,234 DEBUG InternalResourceView:237 - Forwarding to resource [hello, user!] in InternalResourceView 'hello, user!'
09:54:45,250 DEBUG DispatcherServlet:834 - DispatcherServlet with name 'dispatcher' determining Last-Modified value for [/myserver/services/users/hello, user!]
09:54:45,250 DEBUG DispatcherServlet:842 - No handler found in getLastModified
09:54:45,250 DEBUG DispatcherServlet:683 - DispatcherServlet with name 'dispatcher' processing GET request for [/myserver/services/users/hello, user!]
09:54:45,250  WARN PageNotFound:959 - No mapping found for HTTP request with URI [/myserver/services/users/hello, user!] in DispatcherServlet with name 'dispatcher'
09:54:45,250 DEBUG DispatcherServlet:643 - Successfully completed request
09:54:45,250 DEBUG DispatcherServlet:643 - Successfully completed request
09:54:45,250 DEBUG RequestContextListener:89 - Cleared thread-bound request context: org.apache.catalina.connector.RequestFacade@19299f5
正如您所注意到的,我的当前配置正在尝试将此请求作为新请求重新路由:

/myserver/services/users/hello, user!
你知道怎么了吗?我遗漏了什么?

问题是您的hello()方法被注释为Spring的handlerMethod,根据@RequestMapping文档,handler方法可以返回任意数量的对象,但如果它返回字符串,则:

解释为视图名称的字符串值,模型通过命令对象和带ModelAttribute注释的引用数据访问器方法隐式确定。handler方法还可以通过声明ModelMap参数以编程方式丰富模型(请参见上文)

因此,它基本上是在寻找您返回的字符串“hello,user”的映射,该字符串不存在。您可以让您的方法返回void,并在方法内部自己将其写入HttpServletResponse

进一步答复:

@RequestMapping(value="/users/hello", method=RequestMethod.GET) 
public void hello(Writer w) { 
   w.write("hello, user!"); 
   w.flush(); 
   return; 
} 
您可能希望获得整个HttpServletResponse,而不仅仅是编写器,这样您就可以设置适当的Http头


很抱歉,我下面的评论很混乱,我是这个网站的新手。

嗯。。。但是它打破了整个JAX-RS的想法,即将方法的返回值发送给请求方。有没有一种方法可以对我的方法进行注释,从而使上述要求成立?根据javadoc Is,您的方法接受一个参数OutputStream或Writer,RequestMapper将传入ServletOutputStream/Writer供您写入。我不确定这是否真的是最好的方法,但它会起作用@RequestMapping(value=“/users/hello”,method=RequestMethod.GET)public void hello(Writer w){w.write(“hello,user!”);w.flush();return;}您可能希望获取整个HttpServletResponse,而不仅仅是Writer,通过这种方式,您可以设置适当的Http头。您可以按照上面的建议将响应直接写入流,也可以返回执行此操作的ModelAndView对象。效果差不多。如果Spring3使用新的HttpMessageConverter模式来处理方法返回值,那就太好了,但实际上它们只适用于@RequestBody。方法返回值的解释仍然与Spring2.5中的解释相同,请记住SpringRESTMVC不是JAX-RS兼容的,这是他们做出的明确选择。JAX-RS不适合SpringMVC。看起来这在某种程度上已经被解决了。您可以实现ModelAndViewResolver接口,并将bean添加到您的上下文中,它将能够解析字符串“视图名称”,并将其写入您的响应中。它还没有准备好被称为JAX-RS兼容,因为它从未打算被称为JAX-RS兼容。它是SpringMVC的扩展。SpringSource已经说过,已经有至少3个JAX-RS实现了,他们不想再增加第四个。
09:54:45,140 DEBUG RequestContextListener:69 - Bound request context to thread: org.apache.catalina.connector.RequestFacade@19299f5
09:54:45,140 DEBUG DispatcherServlet:834 - DispatcherServlet with name 'dispatcher' determining Last-Modified value for [/myserver/services/users/hello]
09:54:45,156 DEBUG DefaultAnnotationHandlerMapping:178 - Mapping [/users/hello] to handler 'com.symantec.repserver.myserver.UsersController@21447f'
09:54:45,171 DEBUG DispatcherServlet:850 - Last-Modified value for [/myserver/services/users/hello] is: -1
09:54:45,171 DEBUG DispatcherServlet:683 - DispatcherServlet with name 'dispatcher' processing GET request for [/myserver/services/users/hello]
09:54:45,218 DEBUG HandlerMethodInvoker:148 - Invoking request handler method: public java.lang.String com.symantec.repserver.myserver.UsersController.hello()
09:54:45,218 DEBUG DefaultListableBeanFactory:1366 - Invoking afterPropertiesSet() on bean with name 'hello, user!'
09:54:45,218 DEBUG DispatcherServlet:1060 - Rendering view [org.springframework.web.servlet.view.InternalResourceView: name 'hello, user!'; URL [hello, user!]] in DispatcherServlet with name 'dispatcher'
09:54:45,234 DEBUG InternalResourceView:237 - Forwarding to resource [hello, user!] in InternalResourceView 'hello, user!'
09:54:45,250 DEBUG DispatcherServlet:834 - DispatcherServlet with name 'dispatcher' determining Last-Modified value for [/myserver/services/users/hello, user!]
09:54:45,250 DEBUG DispatcherServlet:842 - No handler found in getLastModified
09:54:45,250 DEBUG DispatcherServlet:683 - DispatcherServlet with name 'dispatcher' processing GET request for [/myserver/services/users/hello, user!]
09:54:45,250  WARN PageNotFound:959 - No mapping found for HTTP request with URI [/myserver/services/users/hello, user!] in DispatcherServlet with name 'dispatcher'
09:54:45,250 DEBUG DispatcherServlet:643 - Successfully completed request
09:54:45,250 DEBUG DispatcherServlet:643 - Successfully completed request
09:54:45,250 DEBUG RequestContextListener:89 - Cleared thread-bound request context: org.apache.catalina.connector.RequestFacade@19299f5
/myserver/services/users/hello, user!
@RequestMapping(value="/users/hello", method=RequestMethod.GET) 
public void hello(Writer w) { 
   w.write("hello, user!"); 
   w.flush(); 
   return; 
}