zoukankan      html  css  js  c++  java
  • Spring MVC文件下载

    <div>   
        <a href="/Cyberspace/main/downloadFile.do?fileName=模板.xlsx">模板下载</a>
    </div>

    方案一:

        // 文件下载
        @RequestMapping(value = "/downloadFile")
        public ResponseEntity<byte[]> downloadFile() throws IOException {
            String basePath = "F:/testDir/";
            String fileName = "ChromeStandaloneV45.0.2454.101.exe";
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
            headers.setContentDispositionFormData("attachment", URLEncoder.encode(fileName, "utf-8"));//这里用URLEncoder.encode是为了解决文件名中的中文乱码问题
            return new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(new File(basePath + fileName)), headers, HttpStatus.CREATED);
        }

    配置xxx-servelt.xml

    <bean id="stringHttpMessageConverter" class="org.springframework.http.converter.StringHttpMessageConverter">
            <constructor-arg value="UTF-8" index="0"></constructor-arg><!-- 避免出现乱码 -->
            <property name="supportedMediaTypes">
                <list>
                    <value>text/plain;charset=UTF-8</value>
                </list>
            </property>
        </bean>
        <!-- 避免IE出现下载JSON文件的情况 -->
        <bean id="mappingJacksonHttpMessageConverter" class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
            <property name="supportedMediaTypes">
                <list>
                    <value>text/html;charset=UTF-8</value>
                </list>
            </property>
        </bean>
        <bean id="byteArrayHttpMessageConverter" class="org.springframework.http.converter.ByteArrayHttpMessageConverter" />
        <!-- 启动Spring MVC的注解功能,完成请求和注解POJO的映射 -->
        <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
            <property name="messageConverters">
                <list>
                    <ref bean="byteArrayHttpMessageConverter" />
                    <ref bean="stringHttpMessageConverter" />
                    <ref bean="mappingJacksonHttpMessageConverter" /><!-- json转换器 -->
                </list>
            </property>
        </bean>

    方案二:通过Response获得输出流,以流的形式下载文件。以下代码大部分是一样的,自行选择

    /**
         * 文件下载
         * 
         * @param path
         *            文件路径(绝对)
         * @param response
         *            响应对象
         */
        public static void download(String path, HttpServletResponse response) {
            File file = new File(path);
            InputStream fis = null;
            OutputStream os = null;
            try {
                if (!file.exists()) {
                    response.getWriter().print("文件不存在");
                }
                // 以流的形式下载文件
                fis = new BufferedInputStream(new FileInputStream(file));
                // 设置响应报头
                response.reset();
                response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(file.getName(), ENCODING));
                response.addHeader("Content-Length", "" + file.length());
                response.setContentType(MIME_TYPE_BIN);
                response.setCharacterEncoding(ENCODING);
    
                // 写入响应流数据
                os = new BufferedOutputStream(response.getOutputStream());
                byte[] bytes = new byte[1024];
                while (fis.read(bytes) != -1) {
                    os.write(bytes);
                }
            } catch (Throwable e) {
                if (e instanceof ClientAbortException) {
                    // 浏览器点击取消
                    LOGGER.info("用户取消下载!");
                } else {
                    e.printStackTrace();
                }
            } finally {
                try {
                    if (os != null) {
                        os.close();
                    }
                    if (fis != null) {
                        fis.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
    
            }
        }
    
        /**
         * 下载服务器已存在的文件,支持断点续传
         * 
         * @param request
         *            请求对象
         * @param response
         *            响应对象
         * @param path
         *            文件路径(绝对)
         */
        public static void download(HttpServletRequest request, HttpServletResponse response, File proposeFile) {
            LOGGER.debug("下载文件路径:" + proposeFile.getPath());
            InputStream inputStream = null;
            OutputStream bufferOut = null;
            try {
                // 设置响应报头
                long fSize = proposeFile.length();
                response.setContentType("application/x-download");
                // Content-Disposition: attachment; filename=WebGoat-OWASP_Developer-5.2.zip
                response.addHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(proposeFile.getName(), ENCODING));
                // Accept-Ranges: bytes
                response.setHeader("Accept-Ranges", "bytes");
                long pos = 0, last = fSize - 1, sum = 0;// pos开始读取位置; last最后读取位置; sum记录总共已经读取了多少字节
                if (null != request.getHeader("Range")) {
                    // 断点续传
                    response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);
                    try {
                        // 情景一:RANGE: bytes=2000070- 情景二:RANGE: bytes=2000070-2000970
                        String numRang = request.getHeader("Range").replaceAll("bytes=", "");
                        String[] strRange = numRang.split("-");
                        if (strRange.length == 2) {
                            pos = Long.parseLong(strRange[0].trim());
                            last = Long.parseLong(strRange[1].trim());
                        } else {
                            pos = Long.parseLong(numRang.replaceAll("-", "").trim());
                        }
                    } catch (NumberFormatException e) {
                        LOGGER.error(request.getHeader("Range") + " is not Number!");
                        pos = 0;
                    }
                }
                long rangLength = last - pos + 1;// 总共需要读取的字节
                // Content-Range: bytes 10-1033/304974592
                String contentRange = new StringBuffer("bytes ").append(pos).append("-").append(last).append("/").append(fSize).toString();
                response.setHeader("Content-Range", contentRange);
                // Content-Length: 1024
                response.addHeader("Content-Length", String.valueOf(rangLength));
    
                // 跳过已经下载的部分,进行后续下载
                bufferOut = new BufferedOutputStream(response.getOutputStream());
                inputStream = new BufferedInputStream(new FileInputStream(proposeFile));
                inputStream.skip(pos);
                byte[] buffer = new byte[1024];
                int length = 0;
                while (sum < rangLength) {
                    length = inputStream.read(buffer, 0, ((rangLength - sum) <= buffer.length ? ((int) (rangLength - sum)) : buffer.length));
                    sum = sum + length;
                    bufferOut.write(buffer, 0, length);
                }
            } catch (Throwable e) {
                if (e instanceof ClientAbortException) {
                    // 浏览器点击取消
                    LOGGER.info("用户取消下载!");
                } else {
                    LOGGER.info("下载文件失败....");
                    e.printStackTrace();
                }
            } finally {
                try {
                    if (bufferOut != null) {
                        bufferOut.close();
                    }
                    if (inputStream != null) {
                        inputStream.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    
        public static void downloadWithoutEncode(HttpServletRequest request, HttpServletResponse response, File proposeFile) {
            LOGGER.debug("下载文件路径:" + proposeFile.getPath());
            InputStream inputStream = null;
            OutputStream bufferOut = null;
            try {
                // 设置响应报头
                long fSize = proposeFile.length();
                response.setContentType("application/x-download");
                response.addHeader("Content-Disposition", "attachment; filename=" + proposeFile.getName());
                response.setHeader("Accept-Ranges", "bytes");
                long pos = 0, last = fSize - 1, sum = 0;// pos开始读取位置; last最后读取位置; sum记录总共已经读取了多少字节
                if (null != request.getHeader("Range")) {
                    // 断点续传
                    response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);
                    try {
                        // 情景一:RANGE: bytes=2000070- 情景二:RANGE: bytes=2000070-2000970
                        String numRang = request.getHeader("Range").replaceAll("bytes=", "");
                        String[] strRange = numRang.split("-");
                        if (strRange.length == 2) {
                            pos = Long.parseLong(strRange[0].trim());
                            last = Long.parseLong(strRange[1].trim());
                        } else {
                            pos = Long.parseLong(numRang.replaceAll("-", "").trim());
                        }
                    } catch (NumberFormatException e) {
                        LOGGER.error(request.getHeader("Range") + " is not Number!");
                        pos = 0;
                    }
                }
                long rangLength = last - pos + 1;// 总共需要读取的字节
                // Content-Range: bytes 10-1033/304974592
                String contentRange = new StringBuffer("bytes ").append(pos).append("-").append(last).append("/").append(fSize).toString();
                response.setHeader("Content-Range", contentRange);
                // Content-Length: 1024
                response.addHeader("Content-Length", String.valueOf(rangLength));
    
                // 跳过已经下载的部分,进行后续下载
                bufferOut = new BufferedOutputStream(response.getOutputStream());
                inputStream = new BufferedInputStream(new FileInputStream(proposeFile));
                inputStream.skip(pos);
                byte[] buffer = new byte[1024];
                int length = 0;
                while (sum < rangLength) {
                    length = inputStream.read(buffer, 0, ((rangLength - sum) <= buffer.length ? ((int) (rangLength - sum)) : buffer.length));
                    sum = sum + length;
                    bufferOut.write(buffer, 0, length);
                }
            } catch (Throwable e) {
                if (e instanceof ClientAbortException) {
                    // 浏览器点击取消
                    LOGGER.info("用户取消下载!");
                } else {
                    LOGGER.info("下载文件失败....");
                    e.printStackTrace();
                }
            } finally {
                try {
                    if (bufferOut != null) {
                        bufferOut.close();
                    }
                    if (inputStream != null) {
                        inputStream.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    
        /**
         * @param path
         *            文件路径(绝对)
         * @param response
         *            响应对象
         * @return
         */
        public static Boolean download(String path, HttpServletResponse response, String filename) {
            Boolean isBoolean = false;
            File file = new File(path);
            InputStream fis = null;
            OutputStream os = null;
            try {
                if (!file.exists()) {
                    response.getWriter().print("文件不存在");
                }
                // 以流的形式下载文件
                fis = new BufferedInputStream(new FileInputStream(file));
                // 设置响应报头
                response.reset();
                response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(filename.trim(), ENCODING));
                response.addHeader("Content-Length", "" + file.length());
                response.setContentType(MIME_TYPE_BIN);
                response.setCharacterEncoding(ENCODING);
                // 写入响应流数据
                os = new BufferedOutputStream(response.getOutputStream());
                byte[] bytes = new byte[1024];
                while (fis.read(bytes) != -1) {
                    os.write(bytes);
                }
                isBoolean = true;
            } catch (Throwable e) {
                if (e instanceof ClientAbortException) {
                    // 浏览器点击取消
                    isBoolean = false;
                    LOGGER.info("用户取消下载!");
                } else {
                    isBoolean = false;
                    e.printStackTrace();
                }
            } finally {
                try {
                    if (os != null) {
                        os.close();
                    }
                    if (fis != null) {
                        fis.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return isBoolean;
        }
  • 相关阅读:
    重写对象的compareTo方法
    java基础之----hbase
    java基础之----innodb存储引擎
    java基础之----mysql存储结构
    fastjson jsonArrsy 转 list ,list 转 jsonArray
    java基础之----elasticsearch(Java客服端搜索实例)
    java基础之----elasticsearch
    java基础之----RabbitMQ
    java基础之----kafka
    java基础之----zookeeper
  • 原文地址:https://www.cnblogs.com/liaojie970/p/5569466.html
Copyright © 2011-2022 走看看