Skip to content

前台构造超链接:

<a href="http://localhost:9898/blog/blog/Download?fileName=xxx.docx">download</a>

1. 使用servlet的方式

第一种跟 servlet的实现方法 一致,注意一下参数的获取

    @GetMapping("/Download")
    @PostMapping("/Download")
    public void download(@RequestParam("fileName") String fileName, HttpServletRequest req, HttpServletResponse resp) {
//        String fileName = req.getParameter("fileName");
        ServletContext servletContext = req.getServletContext();
        resp.setContentType(servletContext.getMimeType(fileName));
//        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder
//                .getRequestAttributes()).getRequest();

//        String dir = servletContext.getRealPath("/WEB-INF/classes/files");
        String dir = "D:/logs/uploadFiles/";
        String fullFileNmame = dir + fileName;
        System.out.println("download file: " + fullFileNmame);

        try (FileInputStream fi = new FileInputStream(fullFileNmame);
             BufferedInputStream bi = new BufferedInputStream(fi);
             ServletOutputStream so = resp.getOutputStream()) {
            resp.setHeader("Content-Disposition", "attachment;filename=" + new String(fileName.getBytes("utf-8"), "ISO8859-1"));

            int len;
            while ((len = bi.read()) != -1) {
                so.write(len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

2. 使用Spring的方式

    @GetMapping("/Download/{fileName}")
    @PostMapping("/Download/{fileName}")
    public ResponseEntity<org.springframework.core.io.Resource> downloadResponse(
            @PathVariable String fileName, HttpServletRequest request) {
        String dir = "D:/logs/uploadFiles/";
        String fullFileNmame = dir + fileName;

        File file = new File(fullFileNmame);
        org.springframework.core.io.Resource body = new FileSystemResource(file);

//        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder
//                .getRequestAttributes()).getRequest();
        String header = request.getHeader("User-Agent").toUpperCase();
        HttpStatus status = HttpStatus.CREATED;
        try {
            if (header.contains("MSIE") || header.contains("TRIDENT") || header.contains("EDGE")) {
                fileName = URLEncoder.encode(fileName, "UTF-8");
                fileName = fileName.replace("+", "%20");    // IE下载文件名空格变+号问题
                status = HttpStatus.OK;
            } else {
                fileName = new String(fileName.getBytes("UTF-8"), "ISO8859-1");
            }
        } catch (UnsupportedEncodingException e) {}

        HttpHeaders headers = new HttpHeaders();
        //这里可以使用 MediaType.parseMediaType(String mediaType) 自动解析
        headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
        headers.setContentDispositionFormData("attachment", fileName);
        headers.setContentLength(file.length());

        return new ResponseEntity<>(body, headers, status);
    }

此方式能够解析的文件类型有限。

MediaType指的是要传递的数据的MIME类型,MediaType对象包含了三种信息:type 、subtype以及charset,一般将这些信息传入parse()方法中,这样就可以解析出MediaType对象,比如 "text/x-markdown; charset=utf-8" ,type值是text,表示是文本这一大类;/后面的x-markdown是subtype,表示是文本这一大类下的markdown这一小类; charset=utf-8 则表示采用UTF-8编码。原文链接:https://www.jianshu.com/p/4721d7b5e780