Spring MVC-Datei herunterladen-controller gibt verstümmelt Inhalt

Ich versuche zu schreiben, ein controller, um wieder eine Datei zum download bereit.

Zuerst war ich mit der Programmierung so:

@RequestMapping(value = RESTConstants.SLASH + "{id}" + RESTConstants.SLASH + RESTConstants.EXPORT, method = RequestMethod.GET, produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
@ResponseBody
public ResponseEntity<FileSystemResource> 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<FileSystemResource> responseEntity = new ResponseEntity<FileSystemResource>(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;
}

Aber die Antwort wäre ein 406 Der Ressource identifiziert, die durch diese Anforderung ist nur in der Lage, generieren von Antworten mit Merkmalen, die nicht akzeptabel nach der Anfrage "accept" - Header.

Mit der Konsole sagen:

2014-11-05 01:18:39,403 DEBUG  [DefaultHandlerExceptionResolver] Resolving exception from handler [public org.springframework.http.ResponseEntity<org.springframework.core.io.FileSystemResource> 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

Und so änderte ich es nicht wieder eine Antwort wie:

@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(); 
    }
}

Auf beiden Controllern, die Anforderung ist die gleiche, eingegeben in den browser Chromium:

http://localhost:8080/nitro-project-rest/rollouts/3/export

Aber die Antwort würde verstümmelt werden Inhalte im browser angezeigt:
PK��îeE���������������/home/stephane/tmp/Sprache.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Í3vÍKÏIÌK±6äJ+2v+JÌKN2PK*9»¶-���-���PK��îeE���������������/home/stephane/tmp/team.csvËKÌMµNI-N. Ê,(ÉÌÏ3N.JM1\KRK2sS1BRsC2RJ

Mit der Konsole sagen:

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

Mein letzter Versuch war dieser:

@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;
}

Aber es gab mir auch einen 406 Antwort.

Aus der Letzte Versuch vor, die ich entfernt das Attribut: erzeugt =

MediaType.APPLICATION_OCTET_STREAM_VALUE

Und die gleiche Anfrage gesendet durch den browser (gesehen in der Konsole) sah aus wie:

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

Mit der server console-log sagt:

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"]->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"]->java.io.FileInputStream["fd"])
  • welche Art von Dateien willst du downloaden ?
  • Es ist eine zip-Datei.
  • In deinem ersten Beispiel gibt es keine Notwendigkeit, kopieren Sie den stream.
  • Ich sah, dass heute früher, ja, es war überflüssig. Dann habe ich versucht, ohne es bekam aber den gleichen 406. Bearbeitete ich die Frage gepostet und der controller als mein Dritter Versuch.
InformationsquelleAutor Stephane | 2014-11-05
Schreibe einen Kommentar