当前位置: 首页 > news >正文

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中关键字

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

相关文章:

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

目录: 一、文件上传1.1 文件上传“概述”1.2 文件上传“具体配置” :“前端”中配置“文件上传” ( type“file” 满足3个条件 )“后端”中配置“文件上传” ( 配置id为“CommonsMultipartResolver”的bean 配置“文件上传”的“约束条件” 通过“MultipartFile接口”参数接…...

JVM快速入门(2)HotSpot和堆、新生区、永久区、堆内存调优、JProfiler工具分析OOM原因、GC(垃圾回收)、JVM经典面试笔试题整理

5.6 HotSpot和堆 5.6.1 Hotspot 三种JVM&#xff1a; Sun公司&#xff0c;HotspotBEA&#xff0c;JRockitIBM&#xff0c;J9 VM&#xff0c;号称是世界上最快的Java虚拟机 我们一般学习的是&#xff1a;HotSpot 5.6.2 堆 Heap&#xff0c;一个JVM只有一个堆内存&#xff0c…...

我的风采——android studio

目录 实现“我的风采”页面要求理论代码生成apk文件 实现“我的风采”页面 要求 要求利用’java框架的边框布局实现“找的风采 ”页而&#xff0c;其中中间为你的生活照&#xff0c;左右和下面为按钮&#xff0c;上面为标签 理论 Java GUI编程是Java程序设计的重要组成部分…...

BMS设计中的短路保护和MOSFET选型(上)

电池管理系统&#xff08;BMS&#xff09;是一种能够对电池进行监控和管理的电子装备&#xff0c;是电池与用户之间的纽带。通过对电压、电流、温度以及SOC等数据采集&#xff0c;计算进而控制电池的充放电过程&#xff0c;主要就是为了能够提高电池的利用率&#xff0c;防止电…...

用go实现一个任务调度类 (泛型)

用go实现一个任务调度类 &#xff08;泛型&#xff09; 源码地址&#xff1a; https://github.com/robinfoxnan/BirdTalkServer/blob/main/server/core/workmanager.go 1.概述 实现了一个简单的任务管理系统&#xff0c;允许用户定义任务和工作者&#xff0c;并将任务分配给…...

ansible 管理工具以及常用模块

一、前期准备 1、安装 yum install ansible 如果yum源没有ansible&#xff0c;需要提前配置yum源&#xff1a; mv /etc/yum.repos.d/epel.repo /etc/yum.repos.d/epel.repo.backup mv /etc/yum.repos.d/epel-testing.repo /etc/yum.repos.d/epel-testing.repo.backup wget -O…...

javaSSM公司招聘管理系统IDEA开发mysql数据库web结构计算机java编程maven项目

一、源码特点 IDEA开发SSM公司招聘管理系统是一套完善的完整企业内部系统&#xff0c;结合SSM框架和bootstrap完成本系统&#xff0c;对理解JSP java编程开发语言有帮助系统采用SSM框架&#xff08;MVC模式开发&#xff09;MAVEN方式加 载&#xff0c;系统具有完整的源代码和…...

蓝桥杯day11刷题日记

P8615 [蓝桥杯 2014 国 C] 拼接平方数 思路&#xff1a;先把数据范围内的平方数打上标记&#xff0c;然后就是遍历这个区间&#xff0c;转成字符串&#xff08;好拆数据&#xff09;&#xff0c;用substr拆开数据&#xff0c;再强转成整数类型&#xff0c;最后查看拆开的数据是…...

IDEA, Pycharm, Goland控制台乱码

IDEA, Pycharm, Goland控制台乱码 问题描述: 控制台出现&#xfffd;&#xfffd;&#xfffd;&#xfffd;等乱码 复现频率: 总是 解决方案: 以IDEA为例 添加 -Dfile.encodingUTF-8位置 idea64.exe.vmoptions 在安装idea的bin目录idea.vmoptions idea客户端 示意图...

JavaScript单元测试jasmine学习(一)

介绍&#xff1a; jasmine是用于测试JavaScript的一种测试框架,BDD(Behavior Driven Development)行为驱动开发。不依赖于任何其他JavaScript框架&#xff0c;也不需要DOM 准备工作&#xff1a; 1. 首先添加jasmine到自己的项目中 npm install --save-dev jasmine 2. 在项目…...

108、3D Gaussian Splatting for Real-Time Radiance Field Rendering

简介 官网 更少训练时间的同时实现最先进的视觉质量&#xff0c;能在1080p分辨率下实现高质量的实时(≥30 fps)新视图合成 NeRF使用隐式场景表示&#xff0c;体素&#xff0c;点云等属于显示建模方法&#xff0c;3DGS就是显示辐射场。它用3D高斯作为灵活高效的表示方法&…...

PHP之CURL和Socket

文章目录 一、CURL1.基本流程&#xff08;1&#xff09;初始化&#xff08;2&#xff09;向服务器发送请求&#xff08;3&#xff09;向服务器发送请求&#xff08;4&#xff09;关闭curl 2.CURLOPT参数记得写一个文件curl上传的例子记得写一个json上传的例子3.CURL批处理 二、…...

【Web】NKCTF 2024 个人wp(部分)

目录 my first cms 全世界最简单的CTF attack_tacooooo 属实太菜了&#xff0c;3/4 my first cms 一眼搜版本2.2.19 CVE -CVE-2024-27622 GitHub - capture0x/CMSMadeSimple 访问/admin/login.php 爆出弱口令&#xff0c;后台登录 admin Admin123 Extensions > User D…...

QT常见布局器使用

布局简介 为什么要布局&#xff1f;通过布局拖动不影响鼠标拖动窗口的效果等优点.QT设计器布局比较固定&#xff0c;不方便后期修改和维护&#xff1b;在Qt里面布局分为四个大类 &#xff1a; 盒子布局&#xff1a;QBoxLayout 网格布局&#xff1a;QGridLayout 表单布局&am…...

政安晨:【深度学习部署】—— TensorFlow Extended(TFX)介绍

政安晨的个人主页&#xff1a;政安晨 欢迎 &#x1f44d;点赞✍评论⭐收藏 收录专栏: TensorFlow与Keras实战演绎机器学习 希望政安晨的博客能够对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff01; 前言 TensorFlow Extended&#xff08;TFX&a…...

宝石与石头

宝石与石头 链接:https://leetcode.cn/problems/jewels-and-stones/description/ 给你⼀个字符串 jewels 代表石头中宝石的类型&#xff0c;另有⼀个字符串 stones 代表你拥有的石头。 stones 中每个字符代表了⼀种你拥有的石头的类型&#xff0c;你想知道你拥有的石头中有多…...

【Vue3之computed属性(四)】

文章目录 前言一、computed属性有缓存二、使用方法三、修改全名 前言 理解computed属性&#xff0c;实现输入姓和名得出全名并双向绑定&#xff0c;区分单向绑定和双向绑定。测试computed属性和方法的区别 一、computed属性有缓存 先引入computed&#xff0c;写箭头函数定义并…...

生产力工具|安装更新R软件(R、studio)

内容介绍&#xff1a; 安装R软件&#xff1a; 下载 R X64 3.5.1: 访问官方R网站 https://cran.r-project.org/。选择适合Windows版本的安装包。将安装包下载到您的计算机。 本地安装: 运行下载的“R-3.5.1-win.exe”文件。按照安装向导&#xff0c;选择安装路径&#xff0c;取消…...

ffmpeg实现媒体流解码

本期主要讲解怎么将MP4媒体流的视频解码为yuv,音频解码为pcm数据;在此之前我们要先了解解复用和复用的概念; 解复用:像mp4是由音频和视频组成的(其他内容流除外);将MP4的流拆分成视频流(h264或h265等)和音频流(AAC或mp3等); 复用:就是将音频和视频打包成MP4或者fl…...

面试题 之 react

1.说说对react的理解 1️⃣是什么 React是用于构建用户界面的 JavaScript 库,遵循组件设计模式、声明式编程范式和函数式编程概念&#xff0c;更高效使用虚拟 DOM 来有效地操作 DOM &#xff0c;遵循从高阶组件到低阶组件的单向数据流。 react 类组件使用一个名为 render() 的方…...

8k长序列建模,蛋白质语言模型Prot42仅利用目标蛋白序列即可生成高亲和力结合剂

蛋白质结合剂&#xff08;如抗体、抑制肽&#xff09;在疾病诊断、成像分析及靶向药物递送等关键场景中发挥着不可替代的作用。传统上&#xff0c;高特异性蛋白质结合剂的开发高度依赖噬菌体展示、定向进化等实验技术&#xff0c;但这类方法普遍面临资源消耗巨大、研发周期冗长…...

【大模型RAG】Docker 一键部署 Milvus 完整攻略

本文概要 Milvus 2.5 Stand-alone 版可通过 Docker 在几分钟内完成安装&#xff1b;只需暴露 19530&#xff08;gRPC&#xff09;与 9091&#xff08;HTTP/WebUI&#xff09;两个端口&#xff0c;即可让本地电脑通过 PyMilvus 或浏览器访问远程 Linux 服务器上的 Milvus。下面…...

苍穹外卖--缓存菜品

1.问题说明 用户端小程序展示的菜品数据都是通过查询数据库获得&#xff0c;如果用户端访问量比较大&#xff0c;数据库访问压力随之增大 2.实现思路 通过Redis来缓存菜品数据&#xff0c;减少数据库查询操作。 缓存逻辑分析&#xff1a; ①每个分类下的菜品保持一份缓存数据…...

python爬虫:Newspaper3k 的详细使用(好用的新闻网站文章抓取和解析的Python库)

更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Newspaper3k 概述1.1 Newspaper3k 介绍1.2 主要功能1.3 典型应用场景1.4 安装二、基本用法2.2 提取单篇文章的内容2.2 处理多篇文档三、高级选项3.1 自定义配置3.2 分析文章情感四、实战案例4.1 构建新闻摘要聚合器…...

令牌桶 滑动窗口->限流 分布式信号量->限并发的原理 lua脚本分析介绍

文章目录 前言限流限制并发的实际理解限流令牌桶代码实现结果分析令牌桶lua的模拟实现原理总结&#xff1a; 滑动窗口代码实现结果分析lua脚本原理解析 限并发分布式信号量代码实现结果分析lua脚本实现原理 双注解去实现限流 并发结果分析&#xff1a; 实际业务去理解体会统一注…...

【7色560页】职场可视化逻辑图高级数据分析PPT模版

7种色调职场工作汇报PPT&#xff0c;橙蓝、黑红、红蓝、蓝橙灰、浅蓝、浅绿、深蓝七种色调模版 【7色560页】职场可视化逻辑图高级数据分析PPT模版&#xff1a;职场可视化逻辑图分析PPT模版https://pan.quark.cn/s/78aeabbd92d1...

基于Java+MySQL实现(GUI)客户管理系统

客户资料管理系统的设计与实现 第一章 需求分析 1.1 需求总体介绍 本项目为了方便维护客户信息为了方便维护客户信息&#xff0c;对客户进行统一管理&#xff0c;可以把所有客户信息录入系统&#xff0c;进行维护和统计功能。可通过文件的方式保存相关录入数据&#xff0c;对…...

Python Ovito统计金刚石结构数量

大家好,我是小马老师。 本文介绍python ovito方法统计金刚石结构的方法。 Ovito Identify diamond structure命令可以识别和统计金刚石结构,但是无法直接输出结构的变化情况。 本文使用python调用ovito包的方法,可以持续统计各步的金刚石结构,具体代码如下: from ovito…...

【JVM面试篇】高频八股汇总——类加载和类加载器

目录 1. 讲一下类加载过程&#xff1f; 2. Java创建对象的过程&#xff1f; 3. 对象的生命周期&#xff1f; 4. 类加载器有哪些&#xff1f; 5. 双亲委派模型的作用&#xff08;好处&#xff09;&#xff1f; 6. 讲一下类的加载和双亲委派原则&#xff1f; 7. 双亲委派模…...

HTML前端开发:JavaScript 获取元素方法详解

作为前端开发者&#xff0c;高效获取 DOM 元素是必备技能。以下是 JS 中核心的获取元素方法&#xff0c;分为两大系列&#xff1a; 一、getElementBy... 系列 传统方法&#xff0c;直接通过 DOM 接口访问&#xff0c;返回动态集合&#xff08;元素变化会实时更新&#xff09;。…...