title: Spring MVC file download controller returns garbled content
body: <p>I'm trying to write a controller to return a file for download.</p>
  
  <p>At first I was coding it this way:</p>
  
  <pre><code>@RequestMapping(value = RESTConstants.SLASH + "{id}" + RESTConstants.SLASH + RESTConstants.EXPORT, method = RequestMethod.GET, produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
  @ResponseBody
  public ResponseEntity&lt;FileSystemResource&gt; export(@PathVariable Long id, UriComponentsBuilder builder) throws IOException {
      String filename = rolloutExportService.getDownloadFilename();
      FileSystemResource fileSystemResource = rolloutExportService.export(id);
      HttpHeaders responseHeaders = new HttpHeaders();
      responseHeaders.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + filename);
      int read = 0;
      byte[] bytes = new byte[1024];
      OutputStream outputStream = null;
      InputStream inputStream = null;
      ResponseEntity&lt;FileSystemResource&gt; responseEntity = new ResponseEntity&lt;FileSystemResource&gt;(fileSystemResource, responseHeaders, HttpStatus.OK);
      try {
          responseHeaders.add(HttpHeaders.CONTENT_LENGTH, Long.toString(fileSystemResource.contentLength()));
          outputStream = responseEntity.getBody().getOutputStream();
          inputStream = fileSystemResource.getInputStream();
          while ((read = inputStream.read(bytes)) != -1) {
              outputStream.write(bytes, 0, read);
          }
      } finally {
          inputStream.close();
          outputStream.flush();
          outputStream.close(); 
      }
      return responseEntity;
  }
  </code></pre>
  
  <p>But the response would be a 406 The resource identified by this request is only capable of generating responses with characteristics not acceptable according to the request "accept" headers.</p>
  
  <p>With the console log saying:</p>
  
  <pre><code>2014-11-05 01:18:39,403 DEBUG  [DefaultHandlerExceptionResolver] Resolving exception from handler [public org.springframework.http.ResponseEntity&lt;org.springframework.core.io.FileSystemResource&gt; com.nsn.nitro.project.rest.controller.RolloutExportController.export(java.lang.Long,org.springframework.web.util.UriComponentsBuilder) throws java.io.IOException]: org.springframework.web.HttpMediaTypeNotAcceptableException: Could not find acceptable representation 
  2014-11-05 01:18:39,403 DEBUG  [DispatcherServlet] Null ModelAndView returned to DispatcherServlet with name 'NITRo': assuming HandlerAdapter completed request handling 
  2014-11-05 01:18:39,403 DEBUG  [DispatcherServlet] Successfully completed request 
  2014-11-05 01:18:39,405 DEBUG  [ExceptionTranslationFilter] Chain processed normally 
  2014-11-05 01:18:39,405 DEBUG  [SecurityContextPersistenceFilter] SecurityContextHolder now cleared, as request processing completed
  </code></pre>
  
  <p>And so I changed it not to return a response like:</p>
  
  <pre><code>@RequestMapping(value = RESTConstants.SLASH + "{id}" + RESTConstants.SLASH + RESTConstants.EXPORT, method = RequestMethod.GET, produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
  @ResponseBody
  public void export(@PathVariable Long id, HttpServletResponse response) throws IOException {
      String filename = rolloutExportService.getDownloadFilename();
      FileSystemResource fileSystemResource = rolloutExportService.export(id);
      HttpHeaders responseHeaders = new HttpHeaders();
      responseHeaders.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + filename);
      int read = 0;
      byte[] bytes = new byte[1024];
      OutputStream outputStream = null;
      InputStream inputStream = null;
      try {
          responseHeaders.add(HttpHeaders.CONTENT_LENGTH, Long.toString(fileSystemResource.contentLength()));
          outputStream = response.getOutputStream();
          inputStream = fileSystemResource.getInputStream();
          while ((read = inputStream.read(bytes)) != -1) {
              outputStream.write(bytes, 0, read);
          }
      } finally {
          inputStream.close();
          outputStream.flush();
          outputStream.close(); 
      }
  }
  </code></pre>
  
  <p>On both controllers, the request is the same, being typed in the Chromium browser:</p>
  
  <pre><code>http://localhost:8080/nitro-project-rest/rollouts/3/export
  </code></pre>
  
  <p>But the response would be garbled content displayed in the browser:
  PK��îeE���������������/home/stephane/tmp/language.csv%É1
  À ÐÝÃô™uìÐHˆßT‰±ØûC….oy2Èy€l
  ¨
  V8EWc/ÏñÜªµ÷>ú£¡.J‹]@uåtmáò×PKç}:H���O���PK��îeE���������������/home/stephane/tmp/country.csvKÎOIµÎKÌMµÎÉ,.ñ/JI-âJÍ³vÍKÏIÌK±6äJ+²v+JÌKN²PK*9»¶-���-���PK��îeE���������������/home/stephane/tmp/team.csvËKÌMµNI-N.Ê,(ÉÌÏ³N.JM1\KRK2sS¹BRs¬C2RJ </p>
  
  <p>With the console saying:</p>
  
  <pre><code>20. select team0_.id as id1_15_0_, team0_.version as version2_15_0_, team0_.creation_datetime as 
  creation3_15_0_, team0_.description as descript4_15_0_, team0_.name as name5_15_0_ from team 
  team0_ where team0_.id=2  
  2014-11-05 01:31:29,983 DEBUG  [JpaTransactionManager] Initiating transaction commit 
  2014-11-05 01:31:29,983 DEBUG  [JpaTransactionManager] Committing JPA transaction on EntityManager [org.hibernate.jpa.internal.EntityManagerImpl@6569cc] 
  2014-11-05 01:31:29,988 DEBUG  [JpaTransactionManager] Closing JPA EntityManager [org.hibernate.jpa.internal.EntityManagerImpl@6569cc] after transaction 
  2014-11-05 01:31:29,988 DEBUG  [EntityManagerFactoryUtils] Closing JPA EntityManager 
  2014-11-05 01:31:30,013 DEBUG  [DispatcherServlet] Null ModelAndView returned to DispatcherServlet with name 'NITRo': assuming HandlerAdapter completed request handling 
  2014-11-05 01:31:30,013 DEBUG  [DispatcherServlet] Successfully completed request 
  2014-11-05 01:31:30,021 DEBUG  [ExceptionTranslationFilter] Chain processed normally 
  2014-11-05 01:31:30,021 DEBUG  [SecurityContextPersistenceFilter] SecurityContextHolder now cleared, as request processing completed
  </code></pre>
  
  <p>My last attempt was this one:</p>
  
  <pre><code>@RequestMapping(value = RESTConstants.SLASH + "{id}" + RESTConstants.SLASH + RESTConstants.EXPORT, method = RequestMethod.GET, produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
  @ResponseBody
  public FileSystemResource export(@PathVariable Long id) throws IOException {
      String filename = rolloutExportService.getDownloadFilename();
      FileSystemResource fileSystemResource = rolloutExportService.export(id);
      HttpHeaders responseHeaders = new HttpHeaders();
      responseHeaders.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + filename);
      responseHeaders.add(HttpHeaders.CONTENT_LENGTH, Long.toString(fileSystemResource.contentLength()));
      responseHeaders.add(HttpHeaders.CONTENT_TYPE, "application/zip");
      return fileSystemResource;
  }
  </code></pre>
  
  <p>But it also gave me a 406 response.</p>
  
  <p>From the last attempt above, I removed the attribute: produces = </p>
  
  <pre><code>MediaType.APPLICATION_OCTET_STREAM_VALUE
  </code></pre>
  
  <p>And the same request sent by the browser (seen in the console) looked like:</p>
  
  <pre><code>Request URL:data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC4AAAAuCAQAAAD9sOO8AAAASUlEQVR4Xu3SMQoAIAzFUO/o/c+iY4fSSfgQyesgOESHrs9I0j7TEOL9pk5i/OmB/s9IvAYQH6DjxmtTWPEWBcS52zJPIJ4lSRfUZeB1c/cgSwAAAABJRU5ErkJggg==
  Request Headers CAUTION: Provisional headers are shown.
  User-Agent:Mozilla/5.0 (X11; Linux i686) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/34.0.1847.116 Chrome/34.0.1847.116 Safari/537.36
  </code></pre>
  
  <p>With the server console log saying:</p>
  
  <pre><code>2014-11-05 12:08:35,938 DEBUG  [ExceptionsHandler] org.springframework.http.converter.HttpMessageNotWritableException: Could not write content: No serializer found for class java.io.FileDescriptor and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) ) (through reference chain: org.springframework.core.io.InputStreamResource["inputStream"]-&gt;java.io.FileInputStream["fd"]); nested exception is com.fasterxml.jackson.databind.JsonMappingException: No serializer found for class java.io.FileDescriptor and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) ) (through reference chain: org.springframework.core.io.InputStreamResource["inputStream"]-&gt;java.io.FileInputStream["fd"])
  </code></pre>