Springboot 文件下载

springboot打包目录结构和普通web项目结构有区别,所以做文件下载的时候,

往往Windows下测试OK,但是到了Linux就不行了。下面提供一种满足两种系统的通用写法,以供参考。

@Api(tags="文件下载")
@Controller
@RequestMapping({"/downLoad"})
public class DownLoadController {
    // 日志
    Logger logger = LoggerFactory.getLogger(DownLoadController.class);

    @ApiOperation(httpMethod="GET", value="下载文件(模板)-(不需要token令牌)", produces="application/json")
    @ApiImplicitParams({@io.swagger.annotations.ApiImplicitParam(name="type", value="模板类型(1:人员导入模板)", required=true, dataType="long", paramType="query")})
    @GetMapping({"/downLoadFile"})
    public void downLoadFile(Integer type, HttpServletResponse response) throws Exception {
        if (type == null) {
            throw new BusinessException("下载文件类型不能为空");
        }

        String fileName = TemplateEnum.valueOf(type);
        if (fileName == null) {
            throw new BusinessException("下载文件参数不正确,type=" + type);
        }

        this.logger.info("开始下载文件,fileName=" + fileName + ",type=" + type);

        // 重点在这里 windows和Linux环境下的区别,下面这种形式都可以
        ClassPathResource resource = new ClassPathResource("template\\" + fileName);

        if (resource == null) {
            throw new BusinessException("文件不存在");
        }

        ServletOutputStream sos = null;
        InputStream inputStream = null;
        try {
            fileName = URLDecoder.decode(fileName, "UTF-8");

            response.reset();

            response.setContentType("application/x-msdownload");

            // 添加请求头,避免下载中文乱码
            fileName = new String(fileName.getBytes("gbk"), "iso-8859-1");
            response.addHeader("Content-Disposition", "attachment; filename=" + fileName);

            inputStream = resource.getInputStream();

            sos = response.getOutputStream();
            int i;
            while ((i = inputStream.read()) != -1) {
                sos.write(i);
            }
            sos.flush();
            this.logger.info("执行下载正常结束!");
        } catch (Exception e) {
            this.logger.error("执行下载出错:fileName=" + fileName, e);
        }
        finally {
            closeStream(sos, inputStream);
        }
    }

    private void closeStream(ServletOutputStream sos, InputStream inputStream)
    {
        try
        {
            if (sos != null) {
                sos.close();
            }
            if (inputStream != null)
            {
                inputStream.close();
            }
        } catch (IOException ex) {
            this.logger.info("断开连接出错!");
            ex.printStackTrace();
        }
    }

上面代码可以直接拿来使用,做几点说明:

1.  代码中有个枚举类  TemplateEnum 会编译出错

这个类没什么东西,就是一个 type对应一个文件名字,主要是拿到下载文件的名字,也可以直接通过调用的

时候传参即可。

2.  核心代码

// 重点在这里 windows和Linux环境下的区别,下面这种形式都可以
ClassPathResource resource = new ClassPathResource("template\\" + fileName);

3. 我这里是下载一个导入模板,模板路径在template下,如下:

 

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页