spring mvc文件流形式下载

转自:http://mayday85.iteye.com/blog/1622445

首先感谢这位作者的博客,使得我解决问题,只是感觉这个博客有点散,所以特此笔记总结一下:

在使用一个框架时,程序员分为三种级别:
1.看demo开发
2.看文档开发
3.看源码开发

注意:考虑时间上的问题,有好的demo不看文档,有好的文档不看源码。

关于spring mvc文件下载,博客中提到了两种解决方案:

方案1:

        @RequestMapping("download")
        public void download(HttpServletResponse res) throws IOException {
            OutputStream os = res.getOutputStream();
            try {
                res.reset();
                res.setHeader("Content-Disposition", "attachment; filename=dict.txt");
                res.setContentType("application/octet-stream; charset=utf-8");
                os.write(FileUtils.readFileToByteArray(getDictionaryFile()));
                os.flush();
            } finally {
                if (os != null) {
                    os.close();
                }
            }
        }

因为既然使用了mvc,怎么还能暴露HttpServletResponse这样的j2ee接口出来,为作者不推荐。

方案2:

相信spring提供了更好的方式,于是通过翻阅文档,作者得出如下代码:

    @RequestMapping("download")
    public ResponseEntity<byte[]> download() throws IOException {
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
        headers.setContentDispositionFormData("attachment", "dict.txt");
        return new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(getDictionaryFile()),
                                          headers, HttpStatus.CREATED);
    }

文件内容为:

aa    1
vv    2
hh    3

但是结果错误的输出为:

    "YWEJMQ0KdnYJMg0KaGgJMw=="  

解决:

1.查看ByteArrayHttpMessageConverter的源码:

 public ByteArrayHttpMessageConverter() {  
    super(new MediaType("application", "octet-stream"), MediaType.ALL);  
}  
       ...  
       protected void writeInternal(byte[] bytes, HttpOutputMessage outputMessage) throws IOException {  
    FileCopyUtils.copy(bytes, outputMessage.getBody());  
}  

2.查看AnnotationMethodHandlerAdapter源码:

 public AnnotationMethodHandlerAdapter() {  
    // no restriction of HTTP methods by default  
    super(false);  
  
    // See SPR-7316  
    StringHttpMessageConverter stringHttpMessageConverter = new StringHttpMessageConverter();  
    stringHttpMessageConverter.setWriteAcceptCharset(false);  
    this.messageConverters = new HttpMessageConverter[]{new ByteArrayHttpMessageConverter(), stringHttpMessageConverter,  
            new SourceHttpMessageConverter(), new XmlAwareFormHttpMessageConverter()};  
}  
  
       public void setMessageConverters(HttpMessageConverter<?>[] messageConverters) {  
    this.messageConverters = messageConverters;  
}  

3.查看MappingJacksonHttpMessageConverter源码:

    extends AbstractHttpMessageConverter<Object>

4.结论修改XML文件:

    <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">  
        <property name="messageConverters">  
            <list>  
               <bean class="org.springframework.http.converter.ByteArrayHttpMessageConverter"/>
                <bean id="jsonHttpMessageConverter" class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter" >  
                    <property name = "supportedMediaTypes">  
                        <list>  
                            <value>text/plain;charset=UTF-8</value>  
                        </list>  
                    </property>  
                </bean>  
            </list>  
        </property>  
    </bean>  

注意:导入json相关jar包。解决。

题记

每个例子和demo最好都以最佳实践去写!(很欣赏作者这句话,生活工作,态度很重要)

原文地址:https://www.cnblogs.com/tv151579/p/2877487.html