views:

72

answers:

4

Hi everyone,

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 includes 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!

A: 

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.

BrennaSoft
A: 

If "OK" is actual result you want, then you have to add @ResponseBody annotation to this method

splix
Sorry this is not what I'm looking for.. I want "OK" to resolve to "WEB-INF/jsp/OK.jsp" and that is what is happening.. but the Spring DispatcherServlet is catching the request because the servlet-mapping url-pattern is set to "/*"
Diego
Then that isn't a RESTful Web Service. To be RESTful in this basic way your POST request should return a 201 (Created) response code by using @ResponseStatus(HttpMethod.CREATED).
BrennaSoft
Thanks, I'd still like to know how to have RESTful URLs but also to be able to resolve to .jps's, .ftl's, etc. I have asked a similar question here:http://stackoverflow.com/questions/3212746/spring-mvc-restful-urls-freemarker-tiles-spring-macros-can-these-work-to
Diego
A: 

Hi there, 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

Diego
A: 

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>
Chris Carruthers