我正在使用弹簧4.3.14
我面临一个奇怪的问题。我只是想通过使用控制器下载文件,但是当我使用InputStreamResource时,下载的文件已损坏。 这是我的WebMvcConfig:
public class SpringConfig extends WebMvcConfigurerAdapter {
@Override
public void configureMessageConverters(List < HttpMessageConverter < ? >> converters) {
converters.add(new ResourceHttpMessageConverter());
}
}
我写了以下方法:
@RequestMapping(value = "/download", method = {RequestMethod.GET})
public ResponseEntity < InputStreamResource > download() {
try {
File f = new File("/home/angelo/Scrivania/modulo.pdf");
int dimensione = (int) f.length();
InputStream is = new FileInputStream(f);
HttpHeaders respHeaders = new HttpHeaders();
String mi = mimeSvc.getMimeType(fileName, is);
MediaType mime = MediaType.parseMediaType(mi);
respHeaders.setContentType(mime);
respHeaders.setContentDispositionFormData("attachment", fileName);
respHeaders.setContentLength(dimensione);
InputStreamResource result = new InputStreamResource(is);
return new ResponseEntity < InputStreamResource > (result, respHeaders, HttpStatus.OK);
} catch (Exception e) {
if (logger.isErrorEnabled()) {
logger.error("Errore nel download del manuale", e);
}
return new ResponseEntity < InputStreamResource > (HttpStatus.INTERNAL_SERVER_ERROR);
}
}
@RequestMapping(value = "/download2", method = {RequestMethod.GET})
public void download2() {
try {
File f = new File("/home/angelo/Scrivania/modulo.pdf");
InputStream is = new BufferedInputStream(new FileInputStream(f));
String mi = mimeSvc.getMimeType(fileName, is);
response.setContentType(mi);
response.setHeader("Content-Disposition", String.format("attachment; filename=\"" + fileName + "\""));
response.setContentLength((int) f.length());
InputStream inputStream = new BufferedInputStream(new FileInputStream(f));
FileCopyUtils.copy(inputStream, response.getOutputStream());
} catch (Exception e) {
if (logger.isErrorEnabled()) {
logger.error("Errore nel download del manuale", e);
}
try {
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
} catch (IOException e1) {
//Ignoro l'eccezione
}
}
}
通过使用第一种方法,下载的文件已损坏。通过使用第二个文件,下载的文件就可以了。我无法理解原因 这里有关于第一种方法的日志:
2018-03-26 12:59:05,949 36704 [http-nio-8080-exec-4] DEBUG o.s.w.s.m.m.a.RequestMappingHandlerMapping - Returning handler method [public org.springframework.http.ResponseEntity<org.springframework.core.io.InputStreamResource> it.eng.tz.aa.suap.sue.download.manuali.controller.DownloadController.download(java.lang.String)] 2018-03-26 12:59:05,949 36704 [http-nio-8080-exec-4] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Returning cached instance of singleton bean 'downloadController' 2018-03-26 12:59:05,949 36704 [http-nio-8080-exec-4] TRACE o.s.web.servlet.DispatcherServlet - Testing handler adapter [org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter@20669e53] 2018-03-26 12:59:05,949 36704 [http-nio-8080-exec-4] DEBUG o.s.web.servlet.DispatcherServlet - Last-Modified value for [/download-manualistica/download/suap_sue/ME] is: -1 2018-03-26 12:59:05,949 36704 [http-nio-8080-exec-4] TRACE o.s.w.s.m.m.a.ServletInvocableHandlerMethod - Invoking 'it.eng.tz.aa.suap.sue.download.manuali.controller.DownloadController.download' with arguments [ME]
2018-03-26 12:59:09,325 40080 [http-nio-8080-exec-4] TRACE o.s.w.s.m.m.a.ServletInvocableHandlerMethod - Method [it.eng.tz.aa.suap.sue.download.manuali.controller.DownloadController.download] returned [<200 OK,InputStream resource [resource loaded through InputStream],{Content-Type=[application/pdf], Content-Disposition=[form-data; name="attachment"; filename="modulo.pdf"], Content-Length=[1621137]}>] 2018-03-26 12:59:09,354 40109 [http-nio-8080-exec-4] DEBUG o.s.w.s.m.m.a.HttpEntityMethodProcessor - Written [InputStream resource [resource loaded through InputStream]] as "text/html" using [org.springframework.http.converter.ResourceHttpMessageConverter@2316895c] 2018-03-26 12:59:09,354 40109 [http-nio-8080-exec-4] DEBUG o.s.web.servlet.DispatcherServlet - Null ModelAndView returned to DispatcherServlet with name 'DownloadModulisticaSvlt': assuming HandlerAdapter completed request handling 2018-03-26 12:59:09,354 40109 [http-nio-8080-exec-4] TRACE o.s.web.servlet.DispatcherServlet - Cleared thread-bound request context: org.apache.catalina.connector.RequestFacade@622b8367 2018-03-26 12:59:09,354 40109 [http-nio-8080-exec-4] DEBUG o.s.web.servlet.DispatcherServlet - Successfully completed request 2018-03-26 12:59:09,354 40109 [http-nio-8080-exec-4] TRACE o.s.w.c.s.AnnotationConfigWebApplicationContext - Publishing event in WebApplicationContext for namespace 'DownloadModulisticaSvlt-servlet': ServletRequestHandledEvent: url=[/download-manualistica/download/suap_sue/ME]; client=[0:0:0:0:0:0:0:1]; method=[GET]; servlet=[DownloadModulisticaSvlt]; session=[null]; user=[null]; time=[3407ms]; status=[OK]
为什么这个差异在同一个文件上?
我总是使用InputStreamResource,我没有问题。
谢谢
安吉洛
答案 0 :(得分:0)
在您的第一个下载方法中,您使用相同的FileInputStream
两次。第二,您为每次使用创建new FileInputStream
。第二种方法是正确的。
输入流应该只读一次。这就是为什么第二种方法有效,首先没有。
如果输入流支持寻求使用InputStream#reset
方法“回放”流。如果支持倒带,它将解决问题。
is.mark(0);
is.reset();
InputStreamResource result = new InputStreamResource(is);