SpringMVC | SpringMVC中的 “文件上传和下载”

目录:

    • 一、文件上传
      • 1.1 文件上传“概述”
      • 1.2 文件上传“具体配置” :
        • “前端”中配置“文件上传” ( type=“file” + 满足3个条件 )
        • “后端”中配置“文件上传” ( 配置id为“CommonsMultipartResolver”的bean + 配置“文件上传”的“约束条件” + 通过“MultipartFile接口”参数接收“传来的文件”)
      • 1.3 文件上传“应用案例” :
        • 文件上传 (存储在“相对路径”)
        • 文件上传 (存储在“绝对路径”)
    • 二、文件下载
      • 2.1 实现“文件下载” ( “不可”下载“非中文名称”文件 )
      • 2.2 “中文名称”的文件下载 ( “可”下载“中文名称”文件 )

在这里插入图片描述

作者简介 :一只大皮卡丘,计算机专业学生,正在努力学习、努力敲代码中! 让我们一起继续努力学习!

该文章参考学习教材为:
《Java EE企业级应用开发教程 (Spring + Spring MVC +MyBatis)》 黑马程序员 / 编著
文章以课本知识点 + 代码为主线,结合自己看书学习过程中的理解和感悟 ,最终成就了该文章

文章用于本人学习使用 , 同时希望能帮助大家。
欢迎大家点赞👍 收藏⭐ 关注💖哦!!!

(侵权可联系我,进行删除,如果雷同,纯属巧合)


一、文件上传

1.1 文件上传“概述”

  • 上文件上传下载项目 开发中 最常用功能,例如图片的上传与下载邮件附件上传下载等。

1.2 文件上传“具体配置” :

“前端”中配置“文件上传” ( type=“file” + 满足3个条件 )
  • 多数文件上传 都是通过 表单形式 提交给 后台服务器 的,因此,要实现文件上传功能,就需要提供一个 文件上传表单,而 该表单 必须 满足以下3个条件 :

    form表单method属性设置为post
    form表单enctype属性 (编码方式) 设置为 multipart/form-data (多部分/表单数据)
    提供 <input type=”file” name=filename" multiple=“multiple”/>文件上传输入框

    ps
    multiple=“multiple”可选属性,表示 可以 一次性选择多个文件来上传

  • 文件上传 表单的 示范代码 如下 : (“前端”中配置“文件上传”)

    <%-- 通过表单的方式进行文件上传--%>
    <form action="/uploadUrl" method="post" enctype="multipart/form-data">
    <%--  multiple="multiple 为可选属性,表示一次可以选择多个文件上传  --%><input type="file" name="filename" multiple="multiple">
    </form>
    

    上述代码中,除了满足上传表单必须的3个条件外,在 <input>元素中还增加了一个 multiple属性,该属性HTML5新属性,如果使用了该属性,则可以同时选择多个文件进行上传,即 多文件上传

    客户端form表单enctype属性 (multipart/form-data)为 multipart/form-data 时,浏览器 就会采用 二进制流 的方式来 处理表单数据服务器端 就会对 文件上传请求进行解析处理

“后端”中配置“文件上传” ( 配置id为“CommonsMultipartResolver”的bean + 配置“文件上传”的“约束条件” + 通过“MultipartFile接口”参数接收“传来的文件”)
  • Spring MVC中为文件上传提供了直接的支持,这种支持是通过 MultipartResolver (多部件解析器) 对象实现的。MultipartResolver ( 多部件解析器 )是一个接口对象,需要通过它的 实现类 : CommonsMultipartResolver 来完成 文件上传工作。在Spring MVC中使用 MultipartResolver对象非常简单只需要配置文件中定义MultipartResolver接口Bean 即可。

    (配置 idCommonsMultipartResolverbean )

  • 除了配置 CommonsMultipartResolver类之外,还可以通过 <property>元素配置文件上传”的“约束条件 ,具体 文件上传”的“约束条件 如下 :

约束条件描述
<property name=“defaultEncoding” value=“xxx”/>配置 请求编码格式必须JSP中的 pageEncoding属性一致默认ISO-8859-1
<property name=“maxUploadSize” value=“xxx”/>设置 上传文件最大长度单位字节
<property name="maxInMemorySize" value=“xxx”/>设置 缓存中最大尺寸
ps :
maxInMemorySize最大内存大小
<property name=“resolveLazily” value=“xxx”/>推迟文件解析以便Controller捕获文件大小异常

例子如 : ( springmvc-config.xml配置 “文件上传” )

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd"><!--  配置Springmvc的“文件上传”  -->
<!--   配置id为CommonsMultipartResolver的bean -->
<!--
因为实现类CommonsMultipartResolver的内部是引用multipartResolver的知识点来获取“该实现类对象”并完成“文件解析”的,所以该bean的id名必须为: multipartResolver
-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 配置“请求编码格式”,必须与JSP中的pageEncoding的属性一致,默认是ISO-8859-1 -->
<property name="defaultEncoding" value="UTF-8"/>
<!-- 设置上传文件的最大长度,单位为字节  -->
<!-- 1MB = 1024KB ,1KB = 1024B ,2MB = 2X1024X1024 = 2097152B(字节)-->
<property name="maxUploadSize" value="2097152"/>
</bean></beans>

上述配置代码中,配置了 CommonsMultipartResolver类 外,还通过 <property>元素配置了 编码格式允许上传文件的大小

注意 :

因为MuliparResolver接口实现类CommonsMulipartResolver内部是引用muliparReolver字符
获取该实现类对象完成文件解析
,所以在配置CommonsMulipartResolver必须指定该BeanidmulipartResolver

  • 由于 CommonsMultipartResolverSpringMVC内部通过 Apache Commons FileUpload 技术实现的,所以 SpringMVC文件上传需要依赖Apache Commons FileUpload的组件,即需要导入支持文件上传相关JAR包具体如下 :

    commons-fileupload-1.3.2.jar
    commons-io-2.5.jar
    SpringMVC所需JAR
    SpringMVC中“文件上传”和“下载”所需JAR

  • 后端处理器方法 中是通过 MultipartFile接口类型参数接收前端传来文件 的,例子如下

    package com.myh.controller;import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestParam;
    import org.springframework.web.multipart.MultipartFile;@Controller //将该被设置为"处理器"类
    public class FileUploadController { //文件上传的“控制器类”@RequestMapping("/fileUpload")//使用@RequestParam("前端参数名")注解注解“前后端参数名不一致的问题”,让数据之间能够完成映射/赋值//通过"MultipartFile接口"来接受前端传来的文件public String handlerFormUpload(@RequestParam("filename") MultipartFile file) { //MultipartFile 是一个接口if (!file.isEmpty()) { //如果文件不为空//具体的执行方法...return "uploadSuccess";}return "uploadFailure";}
    }
    

    上述代码中,包含一个 MultipartFile接口类型 的参数file(前端)上传到程序中的文件就是被封装在该参数中 ( MultipartFile接口 )的。org.springframework. web mutipart.MultipartFile接口提供获取上传文件文件名称等方法,这些方法及其说明如下表示 :

    MultipartFile接口中的主要方法 :

    方法说明
    byte[ ] getBytes( )字节数组 形式 返回文件内容
    String getContentType( )返回 文件内容类型
    InputStream getInputStream( )读取文件内容返回一个InputStream流
    String getName( )获取 多部件form表单参数名称
    String getOriginalFilename( )获取 上传文件初始化名
    long getSize( )获取 上传文件大小单位字节
    boolean isEmpty( )判断 上传的文件是否为空
    void transferTo( File file )上传的文件 保存目标目录下
    ps :
    方法 中的 File参数本质上传文件存储地址信息因为 MultipartFile接口代表上传文件本身

1.3 文件上传“应用案例” :

文件上传 (存储在“相对路径”)
  • 第一步导入依赖
    SpringMVC所需JAR
    SpringMVC中“文件上传”和“下载”所需JAR

  • 第二步配置具体操作代码文件

    web.xml

    <?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"version="4.0"><!-- 配置"前端过滤器"--><servlet><servlet-name>dispatcherServlet</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><!--  配置springmvc-config.xml配置文件的位置 (上下文配置位置) --><init-param><param-name>contextConfigLocation</param-name><param-value>classpath:springmvc-config.xml</param-value></init-param><!--  配置启动服务器时加载此配置文件,加载此servlet --><load-on-startup>1</load-on-startup></servlet><!--  配置Servlet的Mapper映射  --><servlet-mapping><servlet-name>dispatcherServlet</servlet-name><url-pattern>/</url-pattern></servlet-mapping></web-app>
    

    springmvc-config.xml

    <?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:mvc="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"><!--  定义“组件扫描”,指定需要扫描的包,让注解生效 --><mvc:component-scan base-package="com.myh.controller"/><!--  配置“视图解析器” : 对于“返回视图”的操作有便利  --><bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"><!--  设置前缀   --><property name="prefix" value="/WEB-INF/jsp/"/><!--  设置后缀   --><property name="suffix" value=".jsp"/></bean><!--  配置文件上传解析器 : 多部件解析器 : MultipleResolver  --><bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"><!--  设置请求编码格式   --><property name="defaultEncoding" value="UTF-8"/></bean></beans>
    

    FileUploadController.java

    package com.myh.controller;import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestParam;
    import org.springframework.web.multipart.MultipartFile;import javax.servlet.http.HttpServletRequest;
    import java.io.File;
    import java.io.IOException;
    import java.util.List;
    import java.util.UUID;/*** 文件上传 (相对路径)*/
    @Controller
    public class FileUploadController {/*** 执行文件上传*/@RequestMapping("/fileUpload")public String handldFormUpload(@RequestParam("username") String username , @RequestParam("file") List<MultipartFile> uploadfiles,HttpServletRequest request) {//判断所上传的文件是否存在if (!uploadfiles.isEmpty() && uploadfiles.size() > 0) {//循环输出上传的文件for (MultipartFile multipartFile : uploadfiles) {//获得上传文件的原始名String originalFilename = multipartFile.getOriginalFilename();/*** 设置上传文件的"保存地址"*///从HTTP请求对象中获取ServletContext对象,然后使用ServletContext对象的.getRealPath()方法来获得“真实路径”。String dirPath = request.getServletContext().getRealPath("/upLoadFile/"); //会在out目录下的打包的项目的“根目录”下创建该文件夹,用于存储文件File filePath = new File(dirPath);//如果保存文件的地址不存在,则先创建目录if (!filePath.exists()) {filePath.mkdirs(); //创建目录(创建文件夹)}//使用UUID重新命名上传的文件名称(上传人_uuid_原始文件名称)/*UUID.randomUUID() 是Java中的一个方法,用于生成一个随机的、唯一的标识符(Universally Unique Identifier,简称UUID)*/String newFilename = username + UUID.randomUUID() + originalFilename;try {//使用MultipartFile接口的 transferTo()方法将文件上传到指定位置/*transferTo(File file) : 该方法中的参数本质上为“上传文件”的存储地址信息,因为multipartFile接口就代表“上传文件本身”*/multipartFile.transferTo(new File(dirPath + newFilename));System.out.println(new File(dirPath + newFilename));} catch (IOException e) {e.printStackTrace();return "error"; //返回错误页面}}//跳转成功页面return "success";} else {return "error";}}
    }
    

    上述代码中,使用注解方式定义了一个控制器类,并在类中定义了执行文件上传方法 :
    handleFormUpload( )在handleFormUpload( )方法参数中使用了List<MultipartFile>集合类型
    接收用户上传的文件,然后判断所上传文件是否存在。如果存在,则继续执行上传操作,在通过MultipartFile接口transferTo( )方法将上传文件保存用户指定的目录位置 ,会跳转到success.jsp页面;如果文件不存在或者上传失败,则跳转到error.jsp页面

    注意点
    此处 文件 存储的路径相对路径 ,即 /upLoadFile/ : 如果该文件夹还没存在,会先在 项目打包后根目录 创建一个 文件夹 : upLoadFile, 然后将 上传的文件 存储到该文件夹中) ,upLoadFile文件夹 (是 相对路径 ) 位置展示如下图所示
    在这里插入图片描述


    FileUpload.jsp

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head><title>文件上传</title><script>//判断是否填写上传人并已选择上传文件function check() {var username = document.getElementById("username").value;var file = document.getElementById("file").value;if (username == "") {alert("请填写上传人!");return false;}if (file.length == 0 || file == "") {alert("请选择上传文件!");return false;}return true;}</script>
    </head>
    <body>
    <%--οnsubmit="return check()" : 只有check()方法的返回值为true,才会正常提交表单(才会访问url)
    --%>
    <form action="${pageContext.request.contextPath}/fileUpload" enctype="multipart/form-data" method="post" onsubmit="return check()">上传人:<input type="text" id="username" name="username"></br>请选择文件:<input type="file" id="file" name="file" multiple="multiple"></br><input type="submit" value="上传"></form>
    </body>
    </html>
    

    文件中,编写了一个用于文件上传fom表单,该表单可以填写上传人上传文件,当单击“上传” 按钮时,会先执行ceck方法检查上传 人文本框文件选择框中内容是否为空只有填写了上传人并选择了需要上传的文件后,才能正常提交表单;否则表单将不会提交,并给相应提示信息οnsubmit="return check() : 只有方法中返回值为true才会提交表单)。 提交表单后,会以POST方式提交到一个以”/fileUpload”结尾的请求中。


    error.jsp

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head><title>error页面</title>
    </head>
    <body>
    error!
    </body>
    </html>
    

    success.jsp

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head><title>success页面</title>
    </head>
    <body>
    ok!
    </body>
    </html>
    

    项目发布Tomcat服务器中并启动,在浏览器中访问地址 : http://localhost:8080/FileUpload.jsp 其显示效果如下图所示 :

    在这里插入图片描述

    在上面的 上传页面 中,填写 上传人 并选择所要 上传的文件,单击 上传 按钮后就可向后台发送上传请求信息


    在这里插入图片描述


    单击 上传按钮,程序在正确执行后浏览器 就会跳转到 success.jsp 页面,此时查看 项目发布项目 ,即 可发现 在:
    S:\2024项目\SpringMVC中的“文件上传”和“下载”\out\artifacts\SpringMVC_Web_exploded下 ( 能 在idea找到该文件夹,所以 属于“相对路径) 创建了一个名字为 :upLoadFile文件夹,同时 前端上传的文件存储该文件夹 中。在IDEA中查看存储上传文件”的upLoadFile文件夹:

    在这里插入图片描述


    注意点

    需要注意的是 ,upLoadFile文件夹 是在项目的 发布路径 / 打包路径 中,而不是创建的项目所在目录中 :
    在这里插入图片描述

文件上传 (存储在“绝对路径”)
  • 文件上传 (存储在“绝对路径”)实现: 除了 FileUploadController.java 这个文件有不同之外其他的都是相同的。(替换以下代码就是将“文件”存储在“绝对路径”)

    /**
    * 存储的是“绝对路径”,将上传的文件存储在D盘下的upLoadFile3文件夹下
    */
    String dirPath = "D:/upLoadFile3/";
    

    FileUploadController.java :

    package com.myh.controller;import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestParam;
    import org.springframework.web.multipart.MultipartFile;import javax.servlet.http.HttpServletRequest;
    import java.io.File;
    import java.io.IOException;
    import java.util.List;
    import java.util.UUID;/*** 文件上传 (绝对路径)*/
    @Controller
    public class FileUploadController2 {/*** 执行文件上传( 文件存储在"绝对路径")*/@RequestMapping("/fileUpload3")public String handldFormUpload(@RequestParam("username") String username , @RequestParam("file") List<MultipartFile> uploadfiles,HttpServletRequest request) {//判断所上传的文件是否存在if (!uploadfiles.isEmpty() && uploadfiles.size() > 0) {//循环输出上传的文件for (MultipartFile multipartFile : uploadfiles) {//获得上传文件的原始名String originalFilename = multipartFile.getOriginalFilename();/*** 存储的是“绝对路径”,将上传的文件存储在D盘下的upLoadFile3文件夹下*/String dirPath = "D:/upLoadFile3/";File filePath = new File(dirPath);//如果保存文件的地址不存在,则先创建目录if (!filePath.exists()) {filePath.mkdirs(); //创建目录(创建文件夹)}//使用UUID重新命名上传的文件名称(上传人_uuid_原始文件名称)/*UUID.randomUUID() 是Java中的一个方法,用于生成一个随机的、唯一的标识符(Universally Unique Identifier,简称UUID)*/String newFilename = username + UUID.randomUUID() + originalFilename;try {//使用MultipartFile接口的 transferTo()方法将文件上传到指定位置/*transferTo(File file) : 该方法中的参数本质上为“上传文件”的存储地址信息,因为multipartFile接口就代表“上传文件本身”*/multipartFile.transferTo(new File(dirPath + newFilename));System.out.println(new File(dirPath + newFilename));} catch (IOException e) {e.printStackTrace();return "error"; //返回错误页面}}//跳转成功页面return "success";} else {return "error";}}
    }
    

二、文件下载

2.1 实现“文件下载” ( “不可”下载“非中文名称”文件 )

文件下载 就是将 文件服务器 中的 文件下载到本机上。在SpringMVC环境中,实现文件下载 大致可分为 如下两个步骤

客户端页面 使用一个 文件下载超链接,该链接href属性 要指定后台文件下载方法 以及 文件名 (需要先在文件下载目录中添加了一个名称为 “1.jpg"的文件 ),具体代码示例如下 :

<a href="${pageContext.request.contextPat}/download?filename=1.jpg"> 文件下载
</a>

在后台 Controller类 中,使用 SpringMVC 提供的 文件下载方法 进行 文件下载SpringMVC提供了一个 ResponseEntity类型对象,使用它可以很方便地定义返回HttpHeaders对象HttpStatus对象,通过对这两个对象的设置,即 可完成下载文件所需的配置信息

文件下载示例代码 如下所示 :

package com.myh.controller;import org.apache.commons.io.FileUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;/*** 文件下载
*/
@Controller
public class FileDownLoadController {@RequestMapping("/download")public ResponseEntity<byte[]> fileDownload(HttpServletRequest request,String filename) throws IOException {//指定要下载的文件所在的路径 (即存储文件的路径) --此时用的是“相对路径”String path = request.getServletContext().getRealPath("/upLoadFile/");//创建该对象File file = new File(path + File.separator + filename);//设置"响应头"HttpHeaders headers = new HttpHeaders();//通知浏览器“以下载的方式”打开文件headers.setContentDispositionFormData("attachment", filename);//定义"以流的形式下载"返回文件数据headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);//使用Spring MVC框架的 ResponseEntity对象封装"下载数据"ResponseEntity<byte[]> responseEntity = new ResponseEntity<>(FileUtils.readFileToByteArray(file), headers, HttpStatus.OK);return responseEntity;}
}

fileDownload( )方法 中,首先根据 文件路径 和需要下载的 文件名创建文件对象,然后对 响应头文件下载时的打开方式 以及 下载方式 进行了设置,最后返回 ResponseEntity封装下载结果对象

ResponseEntity对象 有些 类似 前面章节介绍的 @ResponseBody注解,它用于 直接返回结果对象。上面示例中,设置 响应头信息MediaType代表的是Interner Media Type (即互联网媒体类型),也叫作MIME类型, MediaType.APPLICATION_OCTET_STREAM的值为 application/octet-stream,即表示以 二进制流形式下载数据
HttpStatus 类型代表的是Http协议中的状态,示例中的 HttpStatus.OK 表示 200 ,即服务器 已成功处理了请求


启动服务器后访问网址 :http://localhost:8080/FileDownLoad.jsp ,其显示效果如下图所示
在这里插入图片描述

点击“文件下载”链接后,会出现下载提示弹窗如下图所示
在这里插入图片描述

此时,点击“下载”即可下载该文件

2.2 “中文名称”的文件下载 ( “可”下载“中文名称”文件 )

  • 虽然在 实现“文件下载”案例 中能通过 Spring MvC实现了文件下载功能,但 此案例代码 只适用非中名称的文件进行下载,当对中文名称文件进行下载时,因为各个浏览器内部转码机制的不同,就会出现 不同的乱码以及解析异常问题。例如在文件下载目录中添加一个名称为“壁纸.jpg” 的文件,当通过浏览器下载该文件时,下载弹出窗口显示如下图所示 :
    在这里插入图片描述

    上图可以看出,所要下载的文件名称不是壁纸.jpg, 而是“_.jpg", 这就表示 中文文件名称出现了乱码。那么我们要如何解决这种乱码问题呢?

  • 为了 解决浏览器中文件下载中文名称的乱码问题,可以在 前端页面发送请求前对中文名进行统一编码,然后在 后台控制器类对文件名称进行相应的转码,其 具体实现步骤如下 :

    • 下载页面中对中文文件名编码。可以使用ServletAPI中提供的 URLEncoder类 ( URL编码器 )中的 encoder( String s, String enc )方法中文转为UTF-8编码。该方法中 第一个参数表示 需要转码的字符串
      第二个参数表示 编码格式,其具体实现方式如下
      代码所示

      FileDownLoad.jsp :

      <%@ page import="java.net.URLEncoder" %>
      <%@ page contentType="text/html;charset=UTF-8" language="java" pageEncoding="UTF-8" %>
      <html>
      <head><title>文件下载(下载中文名称文件)</title>
      </head>
      <body>
      <%--<%= URLEncoder.encode("壁纸.jpg","UTF-8") %> : 其作用为:通过URLEncoder(URL编码器)的,encode()方法来对“中文文件名称”进行“转码”
      --%>
      <a href="${pageContext.request.contextPath}/download2?filename=<%= URLEncoder.encode("壁纸.jpg","UTF-8") %>">“中文名称”文件下载
      </a>
      </body>
      </html>
      
    • 修改控制器类FileUploadController 中的fileDownload( )方法,并 增加对文件名进行编码方法,其代码如下所示 :

      FileDownLoadController2.java

      package com.myh.controller;import org.apache.commons.io.FileUtils;
      import org.springframework.http.HttpHeaders;
      import org.springframework.http.HttpStatus;
      import org.springframework.http.MediaType;
      import org.springframework.http.ResponseEntity;
      import org.springframework.stereotype.Controller;
      import org.springframework.web.bind.annotation.RequestMapping;import javax.servlet.http.HttpServletRequest;
      import java.io.File;
      import java.io.IOException;
      import java.io.UnsupportedEncodingException;
      import java.net.URLEncoder;/*** 文件下载 (下载中文名称文件)*/
      @Controller
      public class FileDownLoadController2 {@RequestMapping("/download2")public ResponseEntity<byte[]> fileDownload(HttpServletRequest request,String filename) throws IOException {//指定要下载的文件所在的路径 (即存储文件的路径) --此时用的是“相对路径”String path = request.getServletContext().getRealPath("/upLoadFile/");//创建该文件对象File file = new File(path + File.separator + filename);/*** 对文件名编码,防止中文文件乱码*/filename = this.getFilename(request,filename);//设置"响应头"HttpHeaders headers = new HttpHeaders();//通知浏览器“以下载的方式”打开文件headers.setContentDispositionFormData("attachment", filename);//定义以流的形式下载返回文件数据headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);//使用Spring MVC框架的 ResponseEntity对象封装"下载数据"ResponseEntity<byte[]> responseEntity = new ResponseEntity<>(FileUtils.readFileToByteArray(file), headers, HttpStatus.OK);return responseEntity;}/***  根据浏览器的不同编码进行设置,返回编码后的文件名*/private String getFilename(HttpServletRequest request, String filename) throws UnsupportedEncodingException {//IE不同版本User-Agent中出现的关键词String[] IEBrowserKeyWords = {"MSIE", "Trident", "Edge"};//获取请求头代理信息String userAgent = request.getHeader("User-Agent");for (String keyWord : IEBrowserKeyWords) {if (userAgent.contains(keyWord)) {//IE内核浏览器,统一为UTF-8编码显示return URLEncoder.encode(filename, "UTF-8");}}//火狐等其他浏览器统一为ISO-8859-1编码显示return new String(filename.getBytes("UTF-8"), "ISO-8859-1");}
      }
      

      在方法getFilename( )中,由于IE浏览器文件编码上其他浏览器的方式不同,所以在中文编码设置上IE浏览器设置为UTF-8编码,而火狐等其他浏览器设置ISO-8859-1编码。另外由于不同版本IE浏览器,请求代理User-Agent中的关键字也略有不同,所以在判断IE浏览器时,需要特别意User-Agent中关键字

      再次进行中文名文件下载测试如下图所示
      在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/769021.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

RabbitMQ 的高阶应用及可靠性保证

目录 一、RabbitMQ 高阶应用 1.1 消息何去何从 1.2 过期时间 1.3 死信队列 1.4 延迟队列 1.5 优先级队列 1.6 消费质量保证&#xff08;QOS&#xff09; 二、持久化 三、生产者确认 四、消息可靠性和重复消费 4.1 消息可靠性 4.2 重复消费问题 上篇文章介绍了 Rabb…

流畅的 Python 第二版(GPT 重译)(三)

第五章&#xff1a;数据类构建器 数据类就像孩子一样。它们作为一个起点是可以的&#xff0c;但要作为一个成熟的对象参与&#xff0c;它们需要承担一些责任。 马丁福勒和肯特贝克 Python 提供了几种构建简单类的方法&#xff0c;这些类只是一组字段&#xff0c;几乎没有额外功…

Linux 安装 JDK、MySQL、Tomcat(图文并茂)

所需资料 下载 1.1 软件安装方式 在Linux系统中&#xff0c;安装软件的方式主要有四种&#xff0c;这四种安装方式的特点如下&#xff1a; 安装方式特点二进制发布包安装软件已经针对具体平台编译打包发布&#xff0c;只要解压&#xff0c;修改配置即可rpm安装软件已经按照re…

美易官方:科技巨头涨势好标普指数年底前有望升至6000点

高盛&#xff0c;作为全球领先的金融机构之一&#xff0c;近日发布了一份报告&#xff0c;预测在科技巨头的涨势推动下&#xff0c;标普500指数年底前有望升至6000点。这一预测引起了市场的广泛关注&#xff0c;投资者们纷纷开始重新评估自己的投资策略。 David Kostin等策略师…

超过 1200 个能够拦截在野外检测到的 2FA 的网络钓鱼工具包

超过 1200 个能够拦截在野外检测到的 2FA 的网络钓鱼工具包。 #################### 免责声明&#xff1a;工具本身并无好坏&#xff0c;希望大家以遵守《网络安全法》相关法律为前提来使用该工具&#xff0c;支持研究学习&#xff0c;切勿用于非法犯罪活动&#xff0c;对于恶…

202基于matlab的曲柄滑块机构的运动学仿真分析

基于matlab的曲柄滑块机构的运动学仿真分析&#xff0c;分析各个杆的速度、位移、加速度曲线&#xff0c;以及曲柄滑块机构的动画。程序已调通&#xff0c;可直接运行。 202 matlab 曲柄滑块机构 运动学仿真分析 - 小红书 (xiaohongshu.com)

第九篇【传奇开心果系列】Python自动化办公库技术点案例示例:深度解读Python处理PDF文件

传奇开心果博文系列 系列博文目录Python自动化办公库技术点案例示例系列 博文目录前言一、重要作用介绍二、Python库处理PDF文件基础操作和高级操作介绍&#xff08;一&#xff09;基础操作介绍&#xff08;二&#xff09;高级操作介绍 三、Python库处理PDF文件基础操作示例代码…

H5实现Web ECharts教程:轻松创建动态数据图表

&#x1f31f; 前言 欢迎来到我的技术小宇宙&#xff01;&#x1f30c; 这里不仅是我记录技术点滴的后花园&#xff0c;也是我分享学习心得和项目经验的乐园。&#x1f4da; 无论你是技术小白还是资深大牛&#xff0c;这里总有一些内容能触动你的好奇心。&#x1f50d; &#x…

【OpenBayes 官方教程】快速部署通义千问 72B 大模型

本教程主要为大家介绍怎样在 OpenBayes 上快速部署通义千文 72B 大模型&#xff0c;新朋友点击下方链接注册后&#xff0c;即可获得 4 小时 RTX 4090 5 小时 CPU 的免费使用时长哦&#xff01; 注册链接 https://openbayes.com/console/signup?ryuudi_nBBThttps://openbaye…

算法|数学与数论|素数筛

数学与数论|素数筛 1.判断素数 2.朴素筛 3.埃氏筛 4.欧拉筛(线性筛) 心有猛虎&#xff0c;细嗅蔷薇。你好朋友&#xff0c;这里是锅巴的C\C学习笔记&#xff0c;常言道&#xff0c;不积跬步无以至千里&#xff0c;希望有朝一日我们积累的滴水可以击穿顽石。 质数(素数)&…

【教程】高效数据加密混淆方法及实现简介

背景 在需要对数据进行传输或者表达时&#xff0c;通常要求数据加密的安全级别不高&#xff0c;但希望加解密时间复杂度尽可能低。这时使用传统的对称加密&#xff08;如3DES、AES&#xff09;或非对称加密&#xff08;如RSA、ECC&#xff09;显然不太适合。因为加密的安全级别…

【MySQL】10. 复合查询(重点)

复合查询&#xff08;重点&#xff09; 前面我们讲解的mysql表的查询都是对一张表进行查询&#xff0c;在实际开发中这远远不够。 1. 基本查询回顾 数据还是使用之前的雇员信息表 在标题7的位置&#xff01; mysql> select * from emp where sal > 500 or job MANAG…

【数据结构取经之路】队列循环队列

目录 引言 队列的性质 队列的基本操作 初始化 判空 销毁 队列的长度 插入 删除 返回队头元素 循环队列 假溢出 空与满的判定 实现 初始化 插入 判空 销毁 删除 返回队列长度 返回队列头元素 判满 引言 队列和栈一样&#xff0c;也是数据结构的一种&…

特征工程 | 数据清洗、异常值处理、归一化、标准化、特征提取

目录 一. 数据清洗1. 数据清洗&#xff1a;格式内容错误数据清洗2. 数据清洗&#xff1a;逻辑错误清洗3. 数据清洗&#xff1a;去除不需要的数据4. 数据清洗&#xff1a;关联性验证 二. 异常值的处理1. 删除2. 填充 三. 归一化和标准化1. 归一化2. 标准化 四. 特征提取1. One-H…

MyBatis是纸老虎吗?(六)

经过前面一些列文章的梳理&#xff0c;我们已将MyBatis框架所需要的资源都准备好了&#xff1a;数据库连接信息储存在Configuration对象中的Environment属性中&#xff08;该对象中有这样几个属性String类型的id&#xff0c;TransactionFactory类型的transactionFactory、DataS…

如何优雅的爬取公众号文章

目录 相关函数库介绍 代码例子 IP池免费送 相关函数库介绍 在合法合规的前提下&#xff0c;爬取微信公众号文章可以使用以下几个Python库&#xff1a; requests&#xff1a;这是一个非常流行的HTTP库&#xff0c;用于发送各种HTTP请求。它简单易用&#xff0c;能够高效地处…

关于序列化和反序列化

什么是序列化&#xff0c;什么是反序列化 简单来说&#xff1a; 序列化&#xff1a;将数据结构或对象转换成二进制字节流的过程反序列化&#xff1a;将在序列化过程中所生成的二进制字节流转换成数据结构或者对象的过程 为什么要进行序列化 我们要将java对象进行网络传输&a…

TorchAcc:基于 TorchXLA 的分布式训练框架

演讲人&#xff1a;林伟&#xff0c;阿里云研究员&#xff0c;阿里云人工智能平台 PAI 技术负责人 本文旨在探讨阿里云 TorchAcc&#xff0c;这是一个基于 PyTorch/XLA 的大模型分布式训练框架。 过去十年 AI 领域的显著进步&#xff0c;关键在于训练技术的革新和模型规模的快…

详细剖析多线程2----线程安全问题(面试高频考点)

文章目录 一、概念二、线程不安全的原因三、解决线程不安全问题--加锁&#xff08;synchronized&#xff09;synchronized的特性 四、死锁问题五、内存可见性导致的线程安全问题 一、概念 想给出⼀个线程安全的确切定义是复杂的&#xff0c;但我们可以这样认为&#xff1a; 在多…

立体统计图表绘制方法(凸显式环图)

立体统计图表绘制方法&#xff08;凸显式环图&#xff09; 记得我学统计学的时候&#xff0c;那些统计图表大都是平面的框框图&#xff0c;很呆板&#xff0c;就只是表现出统计的意义就好了。在网络科技发展进步的当下&#xff0c;原来一些传统的统计图表都有了进一步的创新。在…