2

I am using Spring MVC in my application. For a certain ajax call, I need to return JSON response. Normally you would do that using @ReponseBody annotation.

Here is the piece of code I have used.

@RequestMapping(value ="/getClients", headers="Accept=*/*", produces = "application/json")
public @ResponseBody List<Map<String, Object>> getClients(@ModelAttribute("searchText") String searchText, ModelMap model){
    logger.debug("Entering getClients with searchtext as : {}", searchText);
    List<Map<String, Object>> autoCompleterResult = null;
    try{
        autoCompleterResult = clientService.getClientsForAutoCompleter(searchText);
    logger.debug("Grid Result is : {}", autoCompleterResult );
    }catch(Exception e){
        logger.error("Exception occured", e);
    }
    return autoCompleterResult;
}

This works with Spring 3.1.4, but doesn't works with Spring 3.2 version. Or is there some specific configuration I need to do for this to work with Spring 3.2?

MVC Config

  <?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd">
<mvc:annotation-driven />
<mvc:resources location="/css/**" mapping="/css/" />
<mvc:resources location="/js/**" mapping="/js/" />
<mvc:resources location="/images/**" mapping="/images/" />
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
    <property name="exceptionMappings">
        <props>
            <prop key="java.lang.Exception">error</prop>
        </props>
    </property>
</bean>
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
    <property name="prefix" value="/WEB-INF/views/" />
    <property name="suffix" value=".jsp" />
</bean>
<context:component-scan base-package="com.controllers" />
<context:property-placeholder location="classpath:application.properties"/>

PS : I have included Jackson jar in my class path.

Update Stack Trace :

 02 Aug 2013 11:55:00 DEBUG impl.DistributionPlatformRepositoryImpl           (DistributionPlatformServiceImpl.java42) - Entering getPlatforms 
 02 Aug 2013 11:55:00 DEBUG impl.DistributionPlatformRepositoryImpl (DistributionPlatformRepositoryImpl.java40) - Entering getPlatforms
 02 Aug 2013 11:55:00 DEBUG impl.DistributionPlatformRepositoryImpl (DistributionPlatformServiceImpl.java88) - Entering getPlatformsAaData
 02 Aug 2013 11:55:00 DEBUG controllers.SearchPlatformController (SearchPlatformController.java56) - Grid Result is : {iTotalDisplayRecords=7, aaData=[[A, B, C, 7, D, E, C, In Active, 25], [A, T, B, 3, L, C, 001, In Active, 20]]}
 02 Aug 2013 11:55:00 DEBUG annotation.ExceptionHandlerExceptionResolver (AbstractHandlerExceptionResolver.java132) - Resolving exception from handler [public java.util.Map<java.lang.String, java.lang.Object> com.controllers.SearchPlatformController.getPlatforms(com.model.form.SearchPlatformForm,org.springframework.ui.ModelMap)]: org.springframework.web.HttpMediaTypeNotAcceptableException: Could not find acceptable representation
 02 Aug 2013 11:55:00 DEBUG annotation.ResponseStatusExceptionResolver (AbstractHandlerExceptionResolver.java132) - Resolving exception from handler [public java.util.Map<java.lang.String, java.lang.Object> com.controllers.SearchPlatformController.getPlatforms(com.model.form.SearchPlatformForm,org.springframework.ui.ModelMap)]: org.springframework.web.HttpMediaTypeNotAcceptableException: Could not find acceptable representation
 02 Aug 2013 11:55:00 DEBUG support.DefaultHandlerExceptionResolver (AbstractHandlerExceptionResolver.java132) - Resolving exception from handler [public java.util.Map<java.lang.String, java.lang.Object> com.controllers.SearchPlatformController.getPlatforms(com.model.form.SearchPlatformForm,org.springframework.ui.ModelMap)]: org.springframework.web.HttpMediaTypeNotAcceptableException: Could not find acceptable representation
 02 Aug 2013 11:55:00 DEBUG servlet.DispatcherServlet (DispatcherServlet.java999) - Null ModelAndView returned to DispatcherServlet with name 'managedaccounts': assuming HandlerAdapter completed request handling
 02 Aug 2013 11:55:00 DEBUG servlet.DispatcherServlet (FrameworkServlet.java951) - Successfully completed request
Rachit Agrawal
  • 685
  • 4
  • 13
  • 35
  • Spring 3.2 has a new ContentNegotiationStrategy pattern that does require some changes in configuration, depending whether or not you've added any additional settings (like request suffix mapping, content-type mapping, etc.) can you add your configuration XML as it might help identify the cause – incomplete-co.de Aug 01 '13 at 10:40
  • @incomplete-co.de : If you are talking about View Resolvers, I have configured one. I have updated my post with view resolver config. – Rachit Agrawal Aug 01 '13 at 11:03
  • no - that *shouldn't* be causing any problems as you're not returning a view or specifying one - do you have any other MVC config? – incomplete-co.de Aug 01 '13 at 11:05
  • @incomplete-co.de : I have update my post with my MVC Config File. Please suggest if any other configuration is required. – Rachit Agrawal Aug 01 '13 at 11:06
  • @incomplete-co.de : Do you need any other config file? – Rachit Agrawal Aug 01 '13 at 11:16
  • "Doesn't work" is incredibly vague. What happens? What is returned from the request? – Michał Politowski Aug 01 '13 at 11:18
  • @MichałPolitowski : (406) The resource identified by this request is only capable of generating responses with characteristics not acceptable according to the request "accept" headers () – Rachit Agrawal Aug 01 '13 at 11:20
  • Try removing the `headers` argument from the annotation – Bart Aug 01 '13 at 11:25
  • you pass a ModelMap in as a parameter for the method, but it doesn't appear that you're using it. can you try the method without the ModelMap and see what happens? (i'm guessing that by using the ModelMap, Spring MVC is pointing you towards the view resolution and it can't map the autoCompleterResult to a view) – incomplete-co.de Aug 01 '13 at 11:25
  • @Bart, incomplete-co.de : Did as you both suggested . Still getting the same error. – Rachit Agrawal Aug 01 '13 at 12:07
  • Could you log an entire request from *org.springframework* with loglevel DEBUG and include it? – Bart Aug 01 '13 at 17:02

3 Answers3

3

Finally after lot of searching I was able solve this. All thanks to Stackoverflow. Please refer to the following link :

https://stackoverflow.com/a/13939290/1061430

Basically following section was required to be included in the MVC config file :

<mvc:annotation-driven content-negotiation-manager="contentNegotiationManager"/>
<bean id="contentNegotiationManager" class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
<!-- Turn off working out content type based on URL file extension, should fall back to looking at the Accept headers -->
<property name="favorPathExtension" value="false" />
</bean>

Thanks again stackoverflow.

Community
  • 1
  • 1
Rachit Agrawal
  • 685
  • 4
  • 13
  • 35
1

Just include the jackson jars into your project and spring will automatically detect it's presence and use it to serialize your objects.

Update

I saw someone has voted this answer down without clarifying why. This is a bit awkward. Especially since the statement is true ;)

So here's a piece quoted from http://blog.springsource.org/2010/01/25/ajax-simplifications-in-spring-3-0/

Underneath the covers, Spring MVC delegates to a HttpMessageConverter to perform the serialization. In this case, Spring MVC invokes a MappingJacksonHttpMessageConverter built on the Jackson JSON processor. This implementation is enabled automatically when you use the mvc:annotation-driven configuration element with Jackson present in your classpath.

Bart
  • 17,070
  • 5
  • 61
  • 80
  • You should mention that in the question. Any way... Good chance jackson doesn't know how to serialize `List>`. In that case you'll need to implement a custom serializer to handle it. See http://stackoverflow.com/questions/11106053/how-to-serialize-a-map-as-list-using-jackson – Bart Aug 01 '13 at 11:21
  • Good point. Will do that :). I tried with `String` as return type. Same result. Also `List>` works with Spring 3.1.4 – Rachit Agrawal Aug 01 '13 at 11:22
0

What version of Jackson you using? Jackson 2.1.0 works great with Spring 3.2 of me with next maven dependencies:

<dependency>
  <groupId>com.fasterxml.jackson.core</groupId>
  <artifactId>jackson-core</artifactId>
  <version>2.1.0</version>
</dependency>
<dependency>
  <groupId>com.fasterxml.jackson.core</groupId>
  <artifactId>jackson-databind</artifactId>
  <version>2.1.0</version>
</dependency>
seralex.vi
  • 620
  • 3
  • 6