Spring MVC文件下载

方案一:

    // 文件下载
    @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;
    }
时间: 2024-11-08 09:52:18

Spring MVC文件下载的相关文章

Spring MVC 文件下载时候 发现IE不支持

@RequestMapping("download") public ResponseEntity<byte[]> download(Long fileKey) throws IOException { HttpHeaders headers = new HttpHeaders(); String fileName=new String(massMessage.getFileName().getBytes("UTF-8"),"iso-8859-

spring mvc 文件下载、

/**前台传过来一个文件名*/ @RequestMapping("/download") public ResponseEntity<Resource> export(@RequestParam("strZipPath") String strZipPath) throws IOException { //filepath 为视频的的路径 //strZipPath 为视频的名字 return download(new File(filepath + &q

spring mvc 文件下载

在controller中进行代码编写: @RequestMapping("/download") public ResponseEntity<byte[]> download(HttpServletRequest req) throws IOException { HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_OCTET_STREAM); //解决中

Spring MVC 的文件下载

在看Spring MVC文件下载之前请先看Spring MVC文件上传 地址:http://www.cnblogs.com/dj-blog/p/7535101.html 文件下载比较简单,在超链接中指定文件下载的文件名就可以了. springMVC提供了一个ResponseEntity类型,可以方便的定义返回的HttpHeads和HttpStatus. 在FileUploadController中加入下面这个controller @RequestMapping("/download")

Spring MVC 4 文件下载实例(带源码)

[本系列其他教程正在陆续翻译中,点击分类:spring 4 mvc 进行查看.源码下载地址在文章末尾.] [翻译 by 明明如月 QQ 605283073] 原文地址:http://websystique.com/springmvc/spring-mvc-4-file-download-example/ 上一篇:Spring MVC 4 使用常规的fileupload上传文件(带源码) 本文将为你展示通过Spring MVC 4实现文件下载. 下载一个文件比较简单,主要包括下面几个步骤. 创建下

Spring MVC文件上传和下载

在Spring MVC中有两种实现上传文件的办法,第一种是Servlet3.0以下的版本通过commons-fileupload与commons-io完成的通用上传,第二种是Servlet3.0以上的版本的Spring内置标准上传,不需借助第3方组件.通用上传也兼容Servlet3.0以上的版本 Servlet3.0以下的通过commons-fileupload上传 1.添加上传依赖包 一个是文件上传的jar包,一个是其所依赖的IO包.这两个jar包,均在Spring支持库的org.apache

Http请求中Content-Type讲解以及在Spring MVC中的应用

引言: 在Http请求中,我们每天都在使用Content-type来指定不同格式的请求信息,但是却很少有人去全面了解content-type中允许的值有多少,这里将讲解Content-Type的可用值,以及在Spring MVC中如何使用它们来映射请求信息. 1.  Content-Type MediaType,即是Internet Media Type,互联网媒体类型:也叫做MIME类型,在Http协议消息头中,使用Content-Type来表示具体请求中的媒体类型信息. [html] vie

Spring MVC 4使用Servlet 3 MultiPartConfigElement实现文件上传(带源码)

[本系列其他教程正在陆续翻译中,点击分类:spring 4 mvc 进行查看.源码下载地址在文章末尾.] [翻译 by 明明如月 QQ 605283073] 原文地址:http://websystique.com/springmvc/spring-mvc-4-file-upload-example-using-multipartconfigelement/ 上一篇:Spring MVC 4 使用常规的fileupload上传文件(带源码) 下一篇:Spring MVC 4 文件下载实例(带源码)

spring mvc velocity多视图

1.ViewResolverUrlBasedViewResolver 这个东西是根据url 进行路由的.网上搜了 1.order 排序,同名出现各种问题 2.XmlViewResolver,BeanNameViewResolver,ResourceBundleViewResolver 这个 根据配置文件去找不同的view 乱码...莫名,而且配置的起来比较麻烦,好处么,就是一个配置文件基本搞定所有页面位置 乱码据说WebApplicationContext 中可以设置某弄过 3.自己写个View