欢迎来到HugNew-拥抱变化,扫一扫右边二维码关注微信订阅号:Martin说 或 加QQ群:427697041互相交流,Stay hungry, Stay foolish.

关于SpringMVC中文件下载小记

spring Martin 2994℃ 0评论

正在学习SpringMVC的路上,今天项目中需要用到文件下载的一个小功能,于是乎开始各种找资料看SpringMVC中是如何通过MessageConverter来实现的,其实做完发现还是比较简洁的,过程遇到几个问题:

  • 下载下来的文件内容异常
  • IE下无法下载
  • IE下下载时文件名乱码

“上代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
    /**
     * 文件下载
     
     * @param fname 文件名称(含后缀)
     * @throws IOException
     */
    @RequestMapping("/down")
    public ResponseEntity<byte[]> downFile(@RequestParam(required = true) String fname)  {
        HttpServletRequest req = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        String path = req.getSession().getServletContext().getRealPath("/upload");
        
        //默认文件名称
        String downFileName = "开支明细" + fname.substring(fname.lastIndexOf("."));
        try {
            downFileName = URLEncoder.encode(downFileName, "UTF-8");//转码解决IE下文件名乱码问题
        catch (Exception e) {
            e.printStackTrace();
        }
        
        //Http响应头
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
        headers.setContentDispositionFormData("attachment", downFileName);
        try {
            return new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(new File(path + "/" + fname)),
                                              headers,
                                              HttpStatus.OK);
        catch (Exception e) {
            e.printStackTrace();
            //日志
            //TODO
        }
        
        headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
        headers.setContentDispositionFormData("attachment""error.txt");
        return new ResponseEntity<byte[]>("文件不存在.".getBytes(), headers, HttpStatus.OK);
    }

问题拆解:

问题1:文件无法下载问题主要是因为配置servlet配置文件中没能把ByteArrayHttpMessageConverter配上

配置文件如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<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>

主要就是加上了一下这一段

1
<bean class="org.springframework.http.converter.ByteArrayHttpMessageConverter" />

问题2、IE下无法下载主要是因为IE对http1.1支持不够完善(大家都这么说), 细了说就是对201状态支持不到位,代码如下:

1
2
3
return new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(new File(path + "/" + fname)),
                                              headers,
                                              HttpStatus.OK);

如果咱们将最后的状态码用HttpStatus.CREATED,那么问题就会出现了!

问题3、IE下这个乱码折腾了一下,也是各种关键字google,最后将filename转个码问题解决,咱这项目是UTF8的,所以我将默认的文件名(中文)Encode一下,代码如下:

1
downFileName = URLEncoder.encode(downFileName, "UTF-8");

文件名终于ok了,IE、Chrome测试ok

转载请注明:HugNew » 关于SpringMVC中文件下载小记

喜欢 (1)or分享 (0)
发表我的评论
取消评论

表情