【问题标题】:How do I get RESTful URLS in Spring 3 MVC?如何在 Spring 3 MVC 中获取 RESTful URL?
【发布时间】:2011-03-06 22:56:58
【问题描述】:

我对 Spring 3 MVC 尝试构建 RESTful Web 服务感到沮丧。

我想要 RESTful URL,例如“my.domain.com/items”,而不是“my.domain.com/items.do”或任何其他包含扩展名的内容。我的 web.xml 包括以下内容。注意 URL 模式:

<servlet>
    <servlet-name>addictedWebServices</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>addictedWebServices</servlet-name>
    <url-pattern>/*</url-pattern>
</servlet-mapping>

我的 addictedWebServices-servlet.xml 包含以下视图解析器:

<bean id="viewResolver2" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
 <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
 <property name="prefix" value="/WEB-INF/jsp/"/>
 <property name="suffix" value=".jsp"/>

我的控制器之一包括以下方法:

 @RequestMapping(value = "/shoutouts", method = RequestMethod.POST) 
 public String post(@RequestBody ShoutOut shoutOut) {

  logger.info("In shout outs controller: post().");

  shoutOutDao.save(shoutOut);

  return "OK";

 }

当我发布到此 URL 时,该方法中的所有内容都执行得很好,但是当 Spring 显示 /WEB-INF/jsp/OK.jsp 时,我收到以下警告:

 2010-06-22 18:34:51,993  WARN [http-8080-2] org.springframework.web.servlet.PageNotFound (DispatcherServlet.java:965) - No mapping found for HTTP request with URI [/addicted/WEB-INF/jsp/OK.jsp] in DispatcherServlet with name 'addictedWebServices'

Tomcat 抛出 404。似乎 DispatcherServlet 处理了 URL,因为我的 servlet-mapping 的 url-pattern 设置为 /**。我怎样才能解决这个问题?如果我将 servlet-mapping url-pattern 更改为 **.do,然后对我的 Spring MVC 注释进行所有相关更改,一切都会正常执行。

感谢您的帮助!

【问题讨论】:

标签: java model-view-controller spring rest


【解决方案1】:

使用 ViewResolver Spring 将为每个视图添加前缀 /WEB-INF/jsp" 和后缀 .jsp,并且由于您返回一个字符串,它假定您正在返回一个视图名称。

您需要摆脱该 InternalResourveViewResolver 并在您的 servlet-xml 文件中使用 mvc-annotation-driven 标记。

更新:

既然你想要 RESTful,你根本不应该返回任何 jsps,所以摆脱它。将“”添加到您的 servlet-xml 文件,删除 JstlView bean 和您定义的任何其他视图 bean。并将@ResponseBody 注解添加到您的控制器中。

【讨论】:

    【解决方案2】:

    将 URL 模式更改为仅“/”。

    web.xml:

    <servlet>
        <servlet-name>addictedWebServices</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    
    <servlet-mapping>
        <servlet-name>addictedWebServices</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
    

    addictedWebServices-servlet.xml

    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
        <property name="prefix" value="/WEB-INF/jsp/" />
        <property name="suffix" value=".jsp" />
    </bean>
    

    唯一的缺点是您需要为您希望容器在没有 Spring 干预的情况下处理的任何资源添加映射,例如:

    <servlet-mapping>
        <servlet-name>default</servlet-name>
        <url-pattern>*.css</url-pattern>
    </servlet-mapping>
    

    【讨论】:

      【解决方案3】:

      如果“OK”是你想要的实际结果,那么你必须在这个方法中添加@ResponseBody注解

      【讨论】:

      • 对不起,这不是我要找的。我希望“OK”解析为“WEB-INF/jsp/OK.jsp”,这就是正在发生的事情。但是春天DispatcherServlet 正在捕获请求,因为 servlet-mapping url-pattern 设置为“/*”
      • 那么这不是 RESTful Web 服务。要以这种基本方式实现 RESTful,您的 POST 请求应使用 @ResponseStatus(HttpMethod.CREATED) 返回 201(已创建)响应代码。
      • 谢谢,我仍然想知道如何拥有 RESTful URL,但也能够解析为 .jps、.ftl 等。我在这里问了一个类似的问题:stackoverflow.com/questions/3212746/…
      【解决方案4】:

      感谢您的回复。如果我理解正确,我可能已经尝试过了。我注释掉了 InternalResourveViewResolver 并将以下内容放入 addictedWebServices-servlet.xml:

      <bean id="OK" class="org.springframework.web.servlet.view.JstlView"> 
         <property name="url" value="/WEB-INF/jsp/OK.jsp"/> 
      </bean>
      

      我从 Tomcat 收到了同样的警告和 404。 Spring DispatcherServlet 似乎仍在处理该 URL

      【讨论】:

        【解决方案5】:

        基本上举个例子

        @RequestMapping(value = "/{shoutouts}", method = RequestMethod.POST)
        public @RequestBody String post(@PathVariable("shoutOut") String shoutOut) {
        logger.info("In shout outs controller: post().");
        shoutOutDao.save(shoutOut);
        return "OK";
        }

        因为 @RequestBody 在 String post 之前 然后返回 "OK" 视为普通响应

        并且如果您删除了@ResponseBody 注释,则返回“OK”,将其视为视图而不是普通响应,因此它将在/WEB 中查找“OK.jsp” -INF/jsp/ 在您设置路径时 “..-servlet.xml”文件

        【讨论】:

          猜你喜欢
          • 2014-06-21
          • 2011-11-12
          • 2011-07-15
          • 2011-06-28
          • 2011-08-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多