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

时间:2009-05-12 14:07:28

标签: java spring tomcat rest jax-rs

我正在尝试公开一个REST全服务(由Tomcat托管),并且无法弄清楚Spring 3(M3)所需的配置是什么。

这是(示例)服务的样子:

@Controller
@Scope("prototype")
public class UsersController
{
    @RequestMapping(value="/users/hello", method=RequestMethod.GET)
    public String hello()
    {
        return "hello, user!";
    }
}

我的Spring配置看起来像这样(为简单起见,我省略了完整的类名):

<beans ...>
    <context:annotation-config />
    <bean class="...AutowiredAnnotationBeanPostProcessor"/>
    <bean class="...DefaultAnnotationHandlerMapping">
    <context:component-scan base-package="com.mycompany.myserver"/>
</beans>

这就是我将Spring配置插入web.xml的方法:

    <listener>
            <listener-class>...RequestContextListener</listener-class>
    </listener>
    <!-- Servlets -->
    <servlet>
        <servlet-name>dispatcher</servlet-name>
        <servlet-class>...DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:*:dispatcher-servlet.xml</param-value>  
        </init-param>
        <load-on-startup>2</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>dispatcher</servlet-name>
        <url-pattern>/services/*</url-pattern>
    </servlet-mapping>

请注意,我正在尝试创建一个最小配置(没有额外的servlet-config.xml文件)。这就是为什么我将Dispatcher指向内置配置。

这是对的吗?

启动Tomcat并加载所有bean后,我将导航到以下URL:

http://localhost:8080/myserver/services/users/hello

而不是“你好,用户!”回答,令我沮丧的是,我在日志文件中看到以下错误:

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!

知道出了什么问题吗?我错过了什么?

1 个答案:

答案 0 :(得分:1)

问题是你的hello()方法被注释为Spring的handlerMethod,根据@RequestMapping文档,处理程序方法可以返回任意数量的对象,但是如果它返回一个String,那么:

@Request Documentation

  

一个String值,它被解释为视图名称,模型通过命令对象和ModelAttribute注释的引用数据访问器方法隐式确定。处理程序方法还可以通过声明ModelMap参数(参见上文)

以编程方式丰富模型

所以它基本上寻找你返回'hello,user'的String的映射 - 它不存在。你可能让你的方法返回void,并在方法内部自己写出HttpServletResponse。

进一步回答:

@RequestMapping(value="/users/hello", method=RequestMethod.GET) 
public void hello(Writer w) { 
   w.write("hello, user!"); 
   w.flush(); 
   return; 
} 

您可能希望获得整个HttpServletResponse,而不仅仅是Writer,这样您就可以设置相应的Http Headers。

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