How do I get RESTful URLS in Spring 3 MVC?
I'm having a frustrating time with Spring 3 MVC trying to build RESTful web services.
I want RESTful URLs, e.g. "my.domain.com/items", not "my.domain.com/items.do" or anything else that inc开发者_如何学Cludes an extension. My web.xml includes the following. Note the URL pattern:
<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>
My addictedWebServices-servlet.xml includes the following view resolvers:
<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"/>
And one of my controllers includes the following method:
@RequestMapping(value = "/shoutouts", method = RequestMethod.POST)
public String post(@RequestBody ShoutOut shoutOut) {
logger.info("In shout outs controller: post().");
shoutOutDao.save(shoutOut);
return "OK";
}
Everything in the method executes fine when I post to this URL, but when Spring goes to display /WEB-INF/jsp/OK.jsp
, I get the following warning:
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'
And Tomcat throws up a 404. It appears the DispatcherServlet handles the URL because my servlet-mapping's url-pattern is set to /**. How can I get around this? Everything executes fine if I change the servlet-mapping url-pattern to **.do and then make all the related changes to my Spring MVC annotations.
Thanks for your help!
With that ViewResolver Spring is going to prefix /WEB-INF/jsp" and postfix .jsp to every view, and since you return a string it assumes you are returning a view name.
You need to get rid of that InternalResourveViewResolver and use the mvc-annotation-driven tag in your servlet-xml file.
Update:
Since you want RESTful you shouldn't be return any jsps at all so get rid of that. Add "" to your servlet-xml file, remove the JstlView bean and any other view beans you have defined. And add the @ResponseBody annotation to your controller.
Change the URL pattern to just '/'.
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>
The only downside is that you need to add mappings for any resources you want the container to process without Spring's intervention, for example:
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.css</url-pattern>
</servlet-mapping>
If "OK" is actual result you want, then you have to add @ResponseBody
annotation to this method
thanks for you reply. If I understand you correctly, I may have already tried this.. I commented out the InternalResourveViewResolver and I put the following in addictedWebServices-servlet.xml:
<bean id="OK" class="org.springframework.web.servlet.view.JstlView">
<property name="url" value="/WEB-INF/jsp/OK.jsp"/>
</bean>
I get the very same Warning and a 404 from Tomcat. The Spring DispatcherServlet still seems to handle that URL
Basically take example
@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";
}
because of @RequestBody before String post then return "OK" consider as plain response
and if you remove that @ResponseBody annotation then return "OK" consider as view not plain Response so it will look for the "OK.jsp" inside /WEB-INF/jsp/ as you set path in "..-servlet.xml" file
精彩评论