SpringMVC框架的文件下载

Posted nuist__NJUPT

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SpringMVC框架的文件下载相关的知识,希望对你有一定的参考价值。

SpringMVC框架的文件下载

实现文件下载的方法有两种,一种是通过超链接下载,一种是利用程序编码实现下载。通过超链接下载固然简单,但容易暴露下载文件的真实位置,并且只能下载存放在Web应用程序所在的目录的文件,利用程序编码实现下载可以增加安全访问控制,还可以从任意位置提供下载的数据,可以将文件存放到Web应用程序以外的目录中,也可以将文件保存到数据库。

利用程序实现文件下载需要设置两个报头:
1-Web服务器需要告诉浏览器其所输出的内容的类型不是普通文本文件或html文件,而是一个要保存到本地的下载文件,这需要设置Content-Type的值为application/x-msdownload
2-Web服务器希望浏览器不直接处理相应的实体内容,而是由用户选择将相应的实体内容保存到一个文件中,这需要设置Content-Dispositon报头,该报头指定了接收程序处理数据内容的方式,在HTTP应用中只有attachment是标准方式,attachment要求用户干预,在attachment后面还可以指定filename参数,该参数是服务器建议浏览器将实体内容保存到文件中的文件名称。

下面我们学习一下文件下载的案例。
1-创建web应用,并导入相关jar包。
2-在web.xml部署DispatcherServlet,并设置编码过滤器。

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
         http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         id = "WebApp_ID" version="4.0">
    <!--部署DispatcherServlet-->
    <servlet>
        <servlet-name>springmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>WEB-INF/springmvc-servlet.xml</param-value>
        </init-param>
        <!--表示容器启动时加载的servlet-->
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <!--任意的请求都通过DispatcherServlet-->
        <url-pattern>/</url-pattern>
    </servlet-mapping>

    <!-- 配置 CharacterEncodingFilter解决中文乱码问题-->
    <filter>
        <filter-name>CharacterEncodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>

        <!-- 配置编码格式为UTF-8 -->
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>CharacterEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
</web-app>


3-在src目录下,创建controller包,在该包中创建控制器类FileDownController,在该类中编写了三个方法,分别完成文件的展示,下载以及文件名字符编码格式的转换。


import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;

import java.util.ArrayList;

@Controller
public class FileDownController {
    //显示要下载的文件
    @RequestMapping("/showDownFiles")
    public String show(HttpServletRequest request, Model model){
        String realpath = "D:\\\\study" ; //路径名
        File dir = new File(realpath) ; //目录
        File [] files = dir.listFiles() ; //目录下的所有文件
        //获取该目录下的所有文件名称
        ArrayList<String> fileName = new ArrayList<>() ;
        for(int i=0; i<files.length; i++){
            fileName.add(files[i].getName()) ; //获取文件名称存入集合
        }
        model.addAttribute("files", fileName) ; //暴露为模型数据,可以在jsp页面使用EL表达式取出
        return "showDownFiles" ;
    }
    //执行下载
    @RequestMapping("/down")
    public String down(@RequestParam  String filename, HttpServletRequest request, HttpServletResponse response){
        String aFilePath = null ; //要下载文件的路径
        FileInputStream in = null ; //输入流
        ServletOutputStream out = null ; //输出流
        try{
            aFilePath = "D:\\\\study" ;
            //设置下载文件使用的报头
            response.setHeader("Content-Type", "application/x-msdownload") ;
            response.setHeader("Content-Disposition", "attachment;filename="  + toUTF8String(filename)) ;

            //读入文件
            in = new FileInputStream(aFilePath + "\\\\" + filename) ;
            //得到响应文件的输出流,用于向客户端输出二进制数据
            out = response.getOutputStream() ;

            out.flush() ;
            int aRead = 0 ;
            byte [] b = new byte[1024] ;
            while((aRead=in.read(b)) != -1 && in != null){
                out.write(b) ; //写出
            }
            out.flush() ;
            in.close() ;
            out.close() ;
        }catch(Exception e){
            e.printStackTrace();
        }
        return null ;
    }
    //下载保存时中文文件名称的字符编码转换方法
    private String toUTF8String(String str) {
        StringBuffer sb = new StringBuffer() ;
        int len = str.length() ;
        for(int i=0; i<len; i++){
            //取出字符串的每个字符
            char c = str.charAt(i) ;
            if(c >= 0 && c <= 255){
                sb.append(c) ;
            }else{
                byte [] b ;
                try{
                    b = Character.toString(c).getBytes("utf-8") ;
                }catch(Exception e){
                    e.printStackTrace();
                    b = null ;
                }
                for(int j=0; j<b.length; j++){
                    int k = b[j] ;
                    if(k < 0){
                        k &= 255 ;
                    }
                    sb.append("%" + Integer.toHexString(k).toUpperCase()) ;
                }
            }
        }
        return sb.toString() ;
    }
}


4-在src目录下创建配置文件springmvc-servlet.xml,在该配置文件中扫描controller包,配置视图解析器。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:p="http://www.springframework.org/schema/p"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       https://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/mvc
       http://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <!--使用扫描机制,扫描控制器类-->
    <context:component-scan base-package="controller"/>
    <mvc:annotation-driven />

    <!--配置视图解析器-->
    <bean class = "org.springframework.web.servlet.view.InternalResourceViewResolver" id = "internalResourceViewResolver">
        <!--前缀-->
        <property name = "prefix" value = "/WEB-INF/jsp/"/>
        <!--后缀-->
        <property name = "suffix" value = ".jsp"/>
    </bean>

    <!--使用Spring的CommonsMultipartResolver配置MultipartResolver用于文件上传-->
    <!--配置默认编码方式,允许上传文件的最大值,单位为字节,配置文件的临时路径-->
    <bean id = "multipartResolver" class = "org.springframework.web.multipart.commons.CommonsMultipartResolver"
          p:defaultEncoding="UTF-8"
          p:maxUploadSize="5400000000000"
          p:uploadTempDir="WEB-INF">
    </bean>

</beans>


5-在WE-INF的jsp目录下创建文件列表页面showDownFiles.jsp

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%--
  Created by IntelliJ IDEA.
  User: nuist__NJUPT
  Date: 2021/10/2
  Time: 16:25
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<table>
    <tr>
        <td>被下载的文件名称</td>
    </tr>
    <!--遍历Model中的files-->
    <c:forEach items = "${files}" var = "filename">
        <tr>
            <td><a href = "${pageContext.request.contextPath}/down?filename=${filename}">${filename}</a></td>
        </tr>
    </c:forEach>
</table>
</body>
</html>

以上是关于SpringMVC框架的文件下载的主要内容,如果未能解决你的问题,请参考以下文章

SpringMVC上传下载

SpringMVC框架的学习

spring整合springMVC

SpringMVC+Mybatis框架整合源码

SpringMVC+Hibernate框架整合,构建一个简单项目

JDBC在springMvc等框架中使用的方式