views:

1980

answers:

2

I've scourged the internet for an example that would use both spring-json and annotated controllers, I'm new to spring so I've had no luck adapting the configuration on spring-json's samples (it uses SimpleController et. al.)

Currently I have a controller with 2 mappings, one lists results in html (and works), the other should render json for some ajax calls but when I access the url it returns a 404 and asks for /myapp/jsp/jsonView.jsp. The code on the show method does execute and it even validates the presence of the id param, so it seems that the problem is that it doesn't know how render, as far as I know that's what the viewResolver bean does.

Thanks in advance for any help :)

Here's what I've got:

@Controller
public class ItemController {

 //This one works
 @RequestMapping(value = "/items", method = RequestMethod.GET)
 public ModelMap list() {
     ModelMap map = new ModelMap();
     map.addAttribute("item", "value");
     return map;
 }
 //This one returns 404, asks for jsonView.jsp
 @RequestMapping(value = "/items.json", method = RequestMethod.GET)
 public ModelAndView show(@RequestParam(value = "id", required = true) String id) {
    Map model = new HashMap();
    model.put("firstname", "Peter");
    model.put("secondname", "Schmitt");
    return new ModelAndView("jsonView", model);
  }
}

on myapp-servlet.xml:

    <bean name="viewResolver" class="org.springframework.web.servlet.view.XmlViewResolver"/>

on views.xml:

<beans>
<bean name="jsonView" class="org.springframework.web.servlet.view.json.JsonView">
    <property name="encoding">
        <value>UTF-8</value>
    </property>
    <property name="contentType">
        <value>application/json</value>
    </property>
    <property name="jsonWriter">
        <ref bean="sojoJsonWriter"/>
    </property>
    <property name="jsonErrors">
        <list>
            <ref bean="statusError"/>
            <ref bean="modelflagError"/>
        </list>
    </property>
</bean>

<bean name="sojoJsonWriter" class="org.springframework.web.servlet.view.json.writer.sojo.SojoJsonStringWriter">
    <property name="convertAllMapValues">
        <value>true</value>
    </property>
</bean>

<bean name="statusError" class="org.springframework.web.servlet.view.json.error.HttpStatusError">
    <property name="errorCode">
        <value>311</value>
    </property>
</bean>
<bean name="modelflagError" class="org.springframework.web.servlet.view.json.error.ModelFlagError">
    <property name="name">
        <value>failure</value>
    </property>
    <property name="value">
        <value>true</value>
    </property>
</bean>

web.xml:

<servlet>
 <servlet-name>myapp</servlet-name>
 <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
 <load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
 <servlet-name>myapp</servlet-name>
 <url-pattern>/myapp/*</url-pattern>
</servlet-mapping>
+1  A: 

There could be another alternative: Are you able to upgrade to spring 3 (it has release state now)? There is a fantastic ContentNegotiationResolver which helps a lot when it comes to content-negotatioon and view-resolving.


<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
 <property name="mediaTypes">
   <map>
   <entry key="xml" value="application/xml"/>
   <entry key="json" value="application/json"/>
...

If now appending .json to your URL path or using respective 'Accept' HTTP header, passed object (see model.put(...)) is serialized accordingly. For json spring 3 is using jackson by default.

manuel aldana
I did consider it, but there is already an important part of the app developed which has 0 tests, can't afford to migrate that old part :(
albemuth
+1  A: 

The problem was with the view resolver on the servlet.xml, added a p:order attribute so it would load before the InternalResourceViewResolver

    <bean name="viewResolver" class="org.springframework.web.servlet.view.XmlViewResolver" p:order="1"/>
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" p:prefix="/jsp/"p:suffix=".jsp" p:order="10"/>
albemuth