zoukankan      html  css  js  c++  java
  • 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最好都以最佳实践去写!(很欣赏作者这句话,生活工作,态度很重要)

  • 相关阅读:
    ionic开发遇到的问题总结
    promise和Rxjs的一点区别
    angular2组件通信
    神奇的函数作用域
    vue模板的几种写法及变化
    在安卓上,微信公众号无法分享到QQ的解决办法之一
    mysql忘记密码
    无法远程连接服务器上的mysql
    gitHub 基础命令
    linux安装Node(Centos)
  • 原文地址:https://www.cnblogs.com/tv151579/p/2877487.html
Copyright © 2011-2022 走看看