title: Unable to pass convert JSON arrays to List of objects in spring controllers
body: <p>I am trying to implement a scenario where I want to be able to send an array of JSON object as request body to Spring MVC controller.</p>
  
  <p>I have gone through the following posts</p>
  
  <ol>
  <li><a href="https://stackoverflow.com/questions/5019162/custom-httpmessageconverter-with-responsebody-to-do-json-things">Custom HttpMessageConverter with @ResponseBody to do Json things</a></li>
  <li><a href="https://stackoverflow.com/questions/3693397/howto-get-rid-of-mvcannotation-driven">Howto get rid of &lt;mvc:annotation-driven /&gt;?</a></li>
  <li><a href="http://prasanthnath.wordpress.com/2013/08/23/type-conversion-in-spring/#more-199" rel="nofollow noreferrer">http://prasanthnath.wordpress.com/2013/08/23/type-conversion-in-spring/#more-199</a></li>
  <li><a href="http://gerrydevstory.com/2013/08/14/posting-json-to-spring-mvc-controller/" rel="nofollow noreferrer">http://gerrydevstory.com/2013/08/14/posting-json-to-spring-mvc-controller/</a></li>
  <li><a href="https://stackoverflow.com/questions/5315288/spring-returning-json-with-responsebody-when-the-accept-header-is-throws-ht">Spring-Returning json with @ResponseBody when the Accept header is */* throws HttpMediaTypeNotAcceptableException</a></li>
  </ol>
  
  <p>But none of the suggestions are working. I apologize if I missed any other posts.</p>
  
  <p>The idea is that there are two controller functions that will  </p>
  
  <ol>
  <li>fetch data from the database The controller will query the database and return a List of objects to be serialized.</li>
  <li>accept the JSON response and convert them to list of objects to be inserted into the database.</li>
  </ol>
  
  <p>The first one works without any explicit serialization on my part.</p>
  
  <pre><code>@RequestMapping("/config")
  public class ConfigController {
  
    @Autowired
    private final Service service;
  
     // This works. I don't know why.
     @RequestMapping("/fetch", method=RequestMethod.GET)
     @ResponseBody
     @ResponseStatus(HttpStatus.OK)
     public String readConfigProperties() throws Exception {
       ImmutableList&lt;Config&gt; configObjects = this.service.readConfiguration();
       return configObjects;
     }
  }
  </code></pre>
  
  <p>I am having trouble taking the JSON response passed in request body and make them available as a list of objects. The controller function seems to be passing a list of linked hashmaps which is not what I want. This is raising a ClassCastException. The function set up is given below</p>
  
  <p><strong>UPDATE</strong>: I used @ResponseBody annotation in a previous version of this post. I changed the post to use @RequestBody, but no impact.</p>
  
  <pre><code>@RequestMapping(method=RequestMethod.POST, consumes={"application/json"}, value="/update}
  @ResponseStatus(HttpStatus.OK)
  public void updateConfig(@RequestBody List&lt;Config&gt; configList) throws Exception {
    this.service.updateConfiguration(configList);
  
  }
  </code></pre>
  
  <p>In this case <strong>configList</strong> is a list of LinkedHashMap objects and so it causes a ClassCastException to be thrown. I don't know why.</p>
  
  <p>My headers are as follows:</p>
  
  <pre><code>Content-Type: application/json; charset=utf-8
  </code></pre>
  
  <p>Stack trace:</p>
  
  <pre><code>java.lang.ClassCastException: java.util.LinkedHashMap incompatible with com.kartik.springmvc.model.Config
      com.kartik.springmvc.service.ConfigPropertyService.upsertConfigurationProperties(ConfigPropertyService.java:56)
      com.kartik.springmvc.controller.ConfigController .upsertConfigurationProperties(ConfigController .java:86)
      sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:88)
      sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:55)
      java.lang.reflect.Method.invoke(Method.java:613)
      org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:213)
      org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:126)
      org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:96)
      org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:617)
      org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:578)
      org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80)
      org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:923)
      org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:852)
      org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:882)
      org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:789)
      javax.servlet.http.HttpServlet.service(HttpServlet.java:646)
  </code></pre>
  
  <p>My converters and controller specific configuration</p>
  
  <pre><code>   &lt;context:annotation-config /&gt;
      &lt;context:component-scan base-package="com.kartik.springmvc.controller" /&gt;
      &lt;bean class="com.kartik.springmvc.controller.AppConfigPropertiesConverter" id="appConfigPropertiesConverter"/&gt;
  
      &lt;bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"&gt;
           &lt;property name="messageConverters"&gt;
              &lt;list&gt;
                  &lt;ref bean="appConfigPropertiesConverter" /&gt;
                  &lt;bean  class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter" /&gt;
              &lt;/list&gt;
          &lt;/property&gt;
      &lt;/bean&gt;
      &lt;mvc:annotation-driven/&gt;
  </code></pre>
  
  <p>My converter implementation is given below. 
  <strong>UPDATE</strong>: This class is not invoked.</p>
  
  <pre><code>public class AppConfigPropertiesConverter extends AbstractHttpMessageConverter&lt;Object&gt; {
  
    public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");
  
    private Gson gson = new Gson();
    /**
     * Construct a new {@code GsonHttpMessageConverter}.
     */
    public AppConfigPropertiesConverter() {
      super(new MediaType("application", "json", DEFAULT_CHARSET), new MediaType(
          "application", "*+json", DEFAULT_CHARSET));
    }
  
    /** Supports only {@link Config} instances. */
    @Override
    protected boolean supports(Class&lt;?&gt; clazz) {
      // TODO Auto-generated method stub
      return true;
    }
  
    /**
     * Converts to a list of {@Config}
     */
    @Override
    protected Object readInternal(
        Class&lt;?&gt; clazz, HttpInputMessage inputMessage)
            throws IOException, HttpMessageNotReadableException {
      TypeToken&lt;?&gt; token = TypeToken.get(clazz);
      System.out.println("#################################################################3");
      Reader jsonReader =
          new InputStreamReader(inputMessage.getBody(), DEFAULT_CHARSET.displayName());
      System.out.println("####################################################################");
      try {
        return this.gson.fromJson(jsonReader, token.getType());
      } catch (JsonParseException ex) {
        throw new HttpMessageNotReadableException("Could not read JSON: " + ex.getMessage(), ex);
      }
    }
  
    /**
     * Write the json reprsentation to {@link OutputStream}.
     * 
     * @param config object to be serialized
     * @param output http output message
     */
    @Override
    protected void writeInternal(
        Object config, HttpOutputMessage outputMessage)
            throws IOException, HttpMessageNotWritableException {
      outputMessage.getBody().write(
          this.gson.toJson(config).getBytes(DEFAULT_CHARSET.displayName()));
    }
  
  }
  </code></pre>
  
  <p><strong>UPDATE: Added the service layer</strong></p>
  
  <pre><code>   public class ConfigPropertyService implements IConfigPropertyService {
  
    private final Log LOG = LogFactory.getLog(ConfigPropertyService.class);
  
    private final IConfigPropertyDao&lt;Config&gt; configPropertyDao;
  
    /**
     * Returns the instance of Dao.
     */
    @Override
    public IConfigPropertyDao&lt;Config&gt; getConfigPropertyDao() {
      return this.configPropertyDao;
    }
  
    /**
     * Initializes the data access tier.
     */
  
        public ConfigPropertyService(IConfigPropertyDao&lt;Config&gt; configPropertyDao) {
          this.configPropertyDao = Objects.requireNonNull(configPropertyDao);
        }
  
    /**
     * {@inheritDoc}
     * @throws ConfigServiceException if the resources can't be cleaned up successfully
     */
    @Override
    public void upsertConfigurationProperties(
        ImmutableList&lt;Config&gt; configModels) {
  
      for (Config config: configModels) {
           // This for loop throws an exception.
      }
  
      // Step # 2: Updating the properties. 
      this.configPropertyDao.upsertProperties(configModels);
    }
  
  
    /**
     * {@inheritDoc}
     */
    @Override
    public ImmutableList&lt;ConfigModel&gt; readConfigProperties() {
      return this.configPropertyDao.readProperties();
  
    }
  
  }
  </code></pre>
  
  <p>My request body is given as follows. It is a String body with <code>Content-Type: application/json; charset=UTF-8</code></p>
  
  <pre><code>[{"propertyName":"anchorIndexingFilter.deduplicate","propertyValue":"false","propertyDescription":"With this enabled the indexer will case-insensitive deduplicate hanchors\n  before indexing. This prevents possible hundreds or thousands of identical anchors for\n  a given page to be indexed but will affect the search scoring (i.e. tf=1.0f).\n  ","editable":true}]   
  </code></pre>