title: Returning CSV or JSON from Spring Controllers using Message Converters
body: <p>I am trying to configure my Spring application to return either JSON or CSV based on user requested media Type. In order to do that I have set up my  tag like below</p>
  
  <pre><code>&lt;context:annotation-config /&gt;
  
  
  &lt;bean id ="contentNegotiationManager" class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean"&gt;
      &lt;property name="favorPathExtension" value="false"/&gt;
      &lt;property name="favorParameter"  value="true"/&gt;
      &lt;property name="parameterName" value="mediaType"/&gt;
      &lt;property name="defaultContentType"  value="test/csv"/&gt;
  
      &lt;property name="mediaTypes"&gt;
          &lt;map&gt;
              &lt;entry key="json" value="application/json" /&gt;
              &lt;entry key="csv" value="test/csv"/&gt;
          &lt;/map&gt;
      &lt;/property&gt;
  &lt;/bean&gt;
  
  &lt;mvc:annotation-driven content-negotiation-manager="contentNegotiationManager"&gt;
      &lt;mvc:message-converters register-defaults="true"&gt;
          &lt;bean class="com.data.api.util.CSVMessageConverter"/&gt;
          &lt;bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"&gt;
              &lt;property name="objectMapper"&gt;
                  &lt;bean class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean"&gt;
                      &lt;property name="modules" ref="jodaModule"/&gt;
                      &lt;property name="featuresToDisable"&gt;
                          &lt;array&gt;
                              &lt;util:constant static-field="com.fasterxml.jackson.databind.SerializationFeature.WRITE_DATES_AS_TIMESTAMPS"/&gt;
                          &lt;/array&gt;
                      &lt;/property&gt;
                      &lt;property name="defaultViewInclusion" value="false"/&gt;
                      &lt;property name="failOnUnknownProperties" value="false"/&gt;
                  &lt;/bean&gt;
  
              &lt;/property&gt;
              &lt;property name="supportedMediaTypes"&gt;
                  &lt;array&gt;
                      &lt;util:constant static-field="org.springframework.http.MediaType.ALL" /&gt;
                  &lt;/array&gt;
  
              &lt;/property&gt;
          &lt;/bean&gt;
  &lt;bean id="jodaModule" class="com.fasterxml.jackson.datatype.joda.JodaModule"/&gt;
      &lt;/mvc:message-converters&gt;
  &lt;/mvc:annotation-driven&gt;
  </code></pre>
  
  <p>Below is my CSVMessageConverter class</p>
  
  <p>public class CSVMessageConverter extends AbstractHttpMessageConverter {</p>
  
  <pre><code>public static final MediaType MEDIA_TYPE = new MediaType("text", "csv", Charset.forName("utf-8"));
  
  public CSVMessageConverter() {
      super(MEDIA_TYPE);
  }
  
  @Override
  protected boolean supports(Class&lt;?&gt; clazz) {
      return true;
  }
  
  @Override
  protected CSVMessage readInternal(Class&lt;? extends CSVMessage&gt; clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException {
      CSVReader reader = new CSVReader(new InputStreamReader(inputMessage.getBody()));
      return new CSVMessage(reader.readAll());
  }
  
  @Override
  protected void writeInternal(CSVMessage message, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException {
      CSVWriter writer = new CSVWriter(new OutputStreamWriter(outputMessage.getBody()));
      if (! Strings.isNullOrEmpty(message.getHeader())) {
          writer.writeNext(new String[] { "#" + message.getHeader() } );
      }
      for (String[] row: message.getRows()) {
          writer.writeNext(row);
      }
      writer.close();
  }
  </code></pre>
  
  <p>}</p>
  
  <p>and My Controller does this</p>
  
  <pre><code>public class TestController { 
  public @ResponseBody List&lt;Records&gt; getHits(@PathVariable("domain") name  domainName,
                                         @PathVariable("property") Name propertyName,
                                         @RequestParam(value = "start", required = true)  @DateTimeFormat(pattern = datePattern) Date startDate,
                                         @RequestParam(value = "end", required = true) @DateTimeFormat(pattern = datePattern) Date endDate,
                                         HttpServletRequest request) {
  //This returns an arralist of records
  }    
  }
  </code></pre>
  
  <p>I am unable to get my CSVMessageConverter to work. It is throwing cannot cast ArrayList to CSVMessage. What am I doing wrong ? It works fine with JSON but If i request for "text/csv" it blows up. </p>
  
  <p>Can someone explain how Spring uses MessageConverters and WhatI can do to make the above code work.</p>