文档章节

Spring mvc 下载组件

learn_more
 learn_more
发布于 2016/05/28 13:16
字数 678
阅读 111
收藏 6

1、思考

以前使用J2EE时,都是直接使用Response进行流传输下载,现在使用了Spring MVC ,那么最好是尽量不要把Spring 的 API 和 J2EE API 混合使用,代码显得不友好,尤其是反感,JSP里面有Java代码还有JavaScript代码。

2、封装的代码

package com.hnust.common.controller;

import org.apache.commons.io.FileUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RestController;

import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;

/**
 * Created by Heweipo on 2016/5/27.
 * <p>
 * 下载通用控制器,业务类控制器只要继承该类,调用 export 方法进行下载。
 */
@RestController
public class DownloadController extends BaseController {

    /**
     * 下载文件通用方法
     *
     * @param file 文件对象
     * @return 文件字节流
     */
    public ResponseEntity<byte[]> export(File file) {
        return export(file.getName(), file);
    }


    /**
     * 下载文件通用方法
     *
     * @param fileName 文件名称
     * @param file     文件对象
     * @return 文件字节流
     */
    public ResponseEntity<byte[]> export(String fileName, File file) {

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);

        headers.setContentDispositionFormData("attachment", encodeFileName(fileName));
        ResponseEntity<byte[]> rs = null;
        try {
            // 这里不能使用  HttpStatus.CREATED 201 是因为 IE Edge 无法识别,但是Firefox chrome 没问题
            rs = new ResponseEntity<>(FileUtils.readFileToByteArray(file),
                    headers, HttpStatus.OK);
        } catch (IOException e) {
            // throw new CommonException(ResponseStatusEnum.FILE_ERROR, e);
        }
        return rs;
    }

    /**
     * 下载文件的名称,这个是在浏览器那里显示的名称
     *
     * @param fileName 文件名称
     * @return 加码的文件名称
     * <p>
     * IE
     * Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko
     * <p>
     * Edge
     * Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2486.0 Safari/537.36 Edge/13.10586
     * <p>
     * Firefox
     * Mozilla/5.0 (Windows NT 10.0; WOW64; rv:46.0) Gecko/20100101 Firefox/46.0
     * <p>
     * Chrome
     * Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.106 Safari/537.36
     */
    private String encodeFileName(String fileName) {
        String name = fileName;
        try {
            String agent = request.getHeader("USER-AGENT").toLowerCase();
            if (null != agent && (agent.contains("msie") || agent.contains("edge"))) { // IE edge
                name = URLEncoder.encode(fileName, "UTF-8");
            } else if (agent.contains("safari") || agent.contains("chrome") || agent.contains("firefox")) { // safari chrome firefox
                name = new String(fileName.getBytes("UTF-8"), "iso-8859-1");
            } else { // IE10 IE11
                name = URLEncoder.encode(fileName, "UTF-8");
            }
            // 把加号还原为空格(IE Edge 有问题)
            name = name.replace("+", "%20");
        } catch (UnsupportedEncodingException e) {
            // throw new CommonException(ResponseStatusEnum.FAILURE, e);
        }
        return name;
    }


}

3、调用组件

@Controller
public class HelloController extends DownloadController {

    /**
     * 
     * 下载组件调用
     */
    @RequestMapping(value = "/download", method = RequestMethod.GET)
    public ResponseEntity<byte[]> download() {
        File file = new File("c://1.txt");
        return export(file);
    }

4、注意

1)rs = new ResponseEntity<>(FileUtils.readFileToByteArray(file),headers, HttpStatus.OK);

网上很多人使用这样的代码进行下载:

rs = new ResponseEntity<>(FileUtils.readFileToByteArray(file),headers, HttpStatus.CREATED);

这样在Chrome Firefox 浏览器中下载没有问题,但是在IE、Edge就无法下载,原因可能是IE、Edge无法识别 201 响应结果。

2)下载文件名称乱码,或者有+号

这个问题确实很常见了,在IE、Firefox下就必须这样设置,通过如下浏览器头信息解析加码方式。 另外,把加号还原为空格(IE Edge 有问题) ,这个jQuery也是一样把空格进行encode之后变为加号了。还原一下

name = name.replace("+", "%20");

© 著作权归作者所有

learn_more
粉丝 93
博文 240
码字总数 210196
作品 0
深圳
程序员
私信 提问
spring MVC 框架结构

![在此输入图片描述][1] 整个处理过程从一个HTTP请求开始: 1)DispatcherServlet接收到请求后,根据对应配置文件中配置的处理器映射,找到对应的处理器映射项(HandlerMapping),根据配置的...

浅夏
2014/03/11
4.6K
0
Spring 3.x Web MVC

本文demo下载地址:http://www.wisdomdd.cn/Wisdom/resource/articleDetail.htm?resourceId=1142 Spring 3.x Web MVC Spring mvc 特点 @ 功能组件划分细致 @ 灵活、强大 @ 设计思想优秀 MVC框......

智慧点点
2018/08/26
19
0
Spring Portlet MVC开发入门示例

本文通过一个简单实例介绍一下Spring 的Portlet MVC框架. Spring Portlet MVC和其Web MVC可以说是如出一辙,只是在Web MVC中处于核心的DispatcherServlet在Portlet MVC中换成了DispatcherPor...

晨曦之光
2012/04/25
945
0
fastupload-springmvc 0.5.5 发布

fastupload-springmvc是利用fastupload开源组件Spring MVC框架写的文件上传插件,使用此插件,能在Controller中以注解的方式来获取上传的文件,然后对其进行操作。比使用fastupload核心API更...

仪山湖
2013/04/15
1K
8
仿照源码,手写一个自定义 Spring MVC 框架

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 https://blog.csdn.net/GitChat/article/details/97947618 前言 上节课我们学习了 Spring M...

GitChat技术杂谈
07/31
0
0

没有更多内容

加载失败,请刷新页面

加载更多

手机视频如何制作GIF动图

很多小伙伴都喜欢用GIF动图在各大社交软件上与好友斗图,那你知道这些好玩有趣的GIF动图是如何制作的吗?下面教你一个将手机视频制作成GIF动图的方法,让你都可以随时随地制作有趣的表情包,...

白米稀饭2019
29分钟前
5
0
Spring Security 实战干货:实现自定义退出登录

1. 前言 上一篇对 Spring Security 所有内置的 Filter 进行了介绍。今天我们来实战如何安全退出应用程序。 2. 我们使用 Spring Security 登录后都做了什么 这个问题我们必须搞清楚!一般登录...

码农小胖哥
今天
10
0
JVM核心知识-类加载机制

JVM中类的生命周期包括7个阶段,加载、准备、验证、解析、初始化、使用、卸载。其中准备、验证、解析被归为连接阶段。 加载 jvm在这个阶段完成的工作 通过类名获取类的二进制字节流 将这个字...

moon888
今天
8
0
.net工作流引擎ccflow流程结束相关功能的介绍

关键字: 工作流程管理系统 工作流引擎 asp.net工作流引擎 java工作流引擎. 表单引擎 工作流功能说明 工作流设计 工作流快速开发平台 业务流程管理 bpm工作流系统 java工作流主流框架 自定义...

孟娟
今天
8
0
APP 值入轻量级钱包以太坊网络钱包

APP 值入轻量级钱包以太坊网络钱包

xiaodong16
今天
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部