基于 Spring 3 (m3) 构建的 REST 完全注释服务的最低配置是什么?

发布于 2024-07-21 07:24:51 字数 4053 浏览 6 评论 0原文

我试图公开一个 REST-full 服务(由 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 文件)。 这就是为什么我将调度程序指向内置配置。

它是否正确?

启动 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!

知道出了什么问题吗? 我缺少什么?

I'm trying to expose a REST-full service (hosted by Tomcat) and can't figure out what is the required configuration for Spring 3 (M3).

This is how (example) the service looks like:

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

The Spring configuration that I have looks like this (I omit the full class names for simplicity):

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

This is how I've plugged-in my Spring configuration into 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>

Note that I'm trying to create a minimal configuration (no extra servlet-config.xml files). This is why I'm pointing the Dispatcher to a built-in configuration.

Is this correct?

After I start Tomcat and all the beans are loaded I'm navigating to the following URL:

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

And, instead of the "hello, user!" reply, to my dismay, I see the following errors in the log file:

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

As you notice, my current configuration is trying to reroute this request as a new request:

/myserver/services/users/hello, user!

Any idea what is wrong? What am I missing?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

岁月静好 2024-07-28 07:24:51

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

@Request 文档

一个字符串值,被解释为视图名称,模型通过命令对象和 ModelAttribute 注释的引用数据访问器方法隐式确定。 处理程序方法还可以通过声明 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 而不仅仅是 Writer,这样您就可以设置适当的 Http Headers。

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

The issue is your hello() method is annotated as a handlerMethod to Spring and per the @RequestMapping documentation, handler methods may return any number of objects but if it returns a String then :

@Request Documentation

A String value which is interpreted as view name, with the model implicitly determined through command objects and ModelAttribute annotated reference data accessor methods. The handler method may also programmatically enrich the model by declaring a ModelMap argument (see above)

So it's basically looking for the mapping for that String you return 'hello, user' - which doesn't exist. You may have your method return void and inside the method write out to the HttpServletResponse yourself.

Further answer:

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

You may want to get the entire HttpServletResponse rather then just the Writer, that way you can set the appropriate Http Headers.

Sorry my comment below is jumbled, I'm new to this site.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文