2024.3.26 Tuesday
目录
- 10.文件的上传和下载
- 10.1.准备工作
- 10.2.基础配置
- 10.2.1.新建名为springmvc-08-file的module
- 10.2.2.新建controller文件夹,applicationContext.xml文件
- 10.3.文件上传
- 10.3.1.在本模块的pom.xml中导入文件上传的jar包:commons-fileupload
- 10.3.2.修改index.jsp
- 10.3.3.新建FileController.java
- 10.3.4.采用file.Transto 来保存上传的文件
- 10.3.5.运行
- 10.4.文件下载
- 10.4.1.文件下载步骤
- 10.4.2.代码实现(修改FileController.java)
- 10.4.3.运行
- 完结撒花
10.文件的上传和下载
10.1.准备工作
- 文件上传是项目开发中最常见的功能之一 ,springMVC 可以很好的支持文件上传,但是SpringMVC上下文中默认没有装配MultipartResolver,因此默认情况下其不能处理文件上传工作。如果想使用Spring的文件上传功能,则需要在上下文中配置MultipartResolver。
- 前端表单要求:为了能上传文件,必须将表单的method设置为POST,并将enctype设置为multipart/form-data。只有在这样的情况下,浏览器才会把用户选择的文件以二进制数据发送给服务器。
- 表单中enctype 属性的详细说明:
- application/x-www=form-urlencoded:默认方式,只处理表单域中的 value 属性值,采用这种编码方式的表单会将表单域中的值处理成 URL 编码方式。
- multipart/form-data:这种编码方式会以二进制流的方式来处理表单数据,这种编码方式会把文件域指定文件的内容也封装到请求参数中,不会对字符编码。
- text/plain:除了把空格转换为 “+” 号外,其他字符都不做编码处理,这种方式适用直接通过表单发送邮件。
- 一旦设置了enctype为multipart/form-data,浏览器即会采用二进制流的方式来处理表单数据,而对于文件上传的处理则涉及在服务器端解析原始的HTTP响应。在2003年,Apache Software Foundation发布了开源的Commons FileUpload组件,其很快成为Servlet/JSP程序员上传文件的最佳选择
- Servlet3.0规范已经提供方法来处理文件上传,但这种上传需要在Servlet中完成。
- 而Spring MVC则提供了更简单的封装。
- Spring MVC为文件上传提供了直接的支持,这种支持是用即插即用的MultipartResolver实现的。
- Spring MVC使用Apache Commons FileUpload技术实现了一个MultipartResolver实现类:CommonsMultipartResolver。因此,SpringMVC的文件上传还需要依赖Apache Commons FileUpload的组件。
10.2.基础配置
10.2.1.新建名为springmvc-08-file的module
添加web支持,修改web.xml(同springmvc-07-interceptor中的web.xml),修改tomcat配置
这些操作已经重复做过多次,这次就只详细写出有修改的地方。
10.2.2.新建controller文件夹,applicationContext.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:context="http://www.springframework.org/schema/context"xmlns:mvc="http://www.springframework.org/schema/mvc"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttps://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/mvchttps://www.springframework.org/schema/mvc/spring-mvc.xsd"><!-- 自动扫描指定的包,下面所有注解类交给IOC容器管理 --><context:component-scan base-package="P29.controller"/><!--静态资源过滤--><mvc:default-servlet-handler /><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><!--文件上传配置--><bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"><!-- 请求的编码格式,必须和jSP的pageEncoding属性一致,以便正确读取表单的内容,默认为ISO-8859-1 --><property name="defaultEncoding" value="utf-8"/><!-- 上传文件大小上限,单位为字节(10485760=10M) --><property name="maxUploadSize" value="10485760"/><property name="maxInMemorySize" value="40960"/></bean></beans>
- CommonsMultipartFile的常用方法:
- String getOriginalFilename():获取上传文件的原名
- InputStream getInputStream():获取文件流
- void transferTo(File dest):将上传文件保存到一个目录文件中
10.3.文件上传
10.3.1.在本模块的pom.xml中导入文件上传的jar包:commons-fileupload
Maven会自动帮我们导入他的依赖包 commons-io包
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><parent><artifactId>SpringMVC_try1</artifactId><groupId>com.kuang</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><groupId>P29</groupId><artifactId>springmvc-08-file</artifactId><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><dependencies><!--文件上传--><dependency><groupId>commons-fileupload</groupId><artifactId>commons-fileupload</artifactId><version>1.3.3</version></dependency><!--servlet-api导入高版本的--><dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>4.0.1</version></dependency></dependencies></project>
在project structure中导入lib目录
10.3.2.修改index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html><head><title>$Title$</title></head><body><%--以二进制流的形式提交一个文件--%><form action="${pageContext.request.contextPath}/upload" enctype="multipart/form-data" method="post"><input type="file" name="file"/><input type="submit" value="upload"></form></body>
</html>
10.3.3.新建FileController.java
package P29.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.commons.CommonsMultipartFile;import javax.servlet.http.HttpServletRequest;
import java.io.*;@Controller
public class FileController {//CommonsMultipartFile接收文件//@RequestParam("file") 将name=file控件得到的文件封装成CommonsMultipartFile 对象//批量上传CommonsMultipartFile则为数组即可@RequestMapping("/upload")public String fileUpload(@RequestParam("file") CommonsMultipartFile file , HttpServletRequest request) throws IOException {//获取文件名 : file.getOriginalFilename();String uploadFileName = file.getOriginalFilename();//如果文件名为空,直接回到首页!if ("".equals(uploadFileName)){return "redirect:/index.jsp";}System.out.println("上传文件名 : "+uploadFileName);//上传路径保存设置String path = request.getServletContext().getRealPath("/upload");//如果路径不存在,创建一个File realPath = new File(path);if (!realPath.exists()){realPath.mkdir();}System.out.println("上传文件保存地址:"+realPath);InputStream is = file.getInputStream(); //文件输入流OutputStream os = new FileOutputStream(new File(realPath,uploadFileName)); //文件输出流//读取写出int len=0;byte[] buffer = new byte[1024];while ((len=is.read(buffer))!=-1){os.write(buffer,0,len);os.flush();}os.close();is.close();return "redirect:/index.jsp";}
}
10.3.4.采用file.Transto 来保存上传的文件
修改FileController.java,添加fileUpload2方法
package P29.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.commons.CommonsMultipartFile;import javax.servlet.http.HttpServletRequest;
import java.io.*;@Controller
public class FileController {//CommonsMultipartFile接收文件//@RequestParam("file") 将name=file控件得到的文件封装成CommonsMultipartFile 对象//批量上传CommonsMultipartFile则为数组即可@RequestMapping("/upload")public String fileUpload(@RequestParam("file") CommonsMultipartFile file , HttpServletRequest request) throws IOException {//获取文件名 : file.getOriginalFilename();String uploadFileName = file.getOriginalFilename();//如果文件名为空,直接回到首页!if ("".equals(uploadFileName)){return "redirect:/index.jsp";}System.out.println("上传文件名 : "+uploadFileName);//上传路径保存设置String path = request.getServletContext().getRealPath("/upload");//如果路径不存在,创建一个File realPath = new File(path);if (!realPath.exists()){realPath.mkdir();}System.out.println("上传文件保存地址:"+realPath);InputStream is = file.getInputStream(); //文件输入流OutputStream os = new FileOutputStream(new File(realPath,uploadFileName)); //文件输出流//读取写出(通过IO)int len=0;byte[] buffer = new byte[1024];while ((len=is.read(buffer))!=-1){os.write(buffer,0,len);os.flush();}os.close();is.close();return "redirect:/index.jsp";}/** 采用file.Transto 来保存上传的文件*/@RequestMapping("/upload2")public String fileUpload2(@RequestParam("file") CommonsMultipartFile file, HttpServletRequest request) throws IOException {//上传路径保存设置//没有获取上传文件的文件名,直接保存文件String path = request.getServletContext().getRealPath("/upload");File realPath = new File(path);if (!realPath.exists()){realPath.mkdir();}//上传文件地址System.out.println("上传文件保存地址:"+realPath);//通过CommonsMultipartFile的方法直接写文件(不通过IO)(注意这个时候)file.transferTo(new File(realPath +"/"+ file.getOriginalFilename()));return "redirect:/index.jsp";}}
10.3.5.运行
http://localhost:8080/springmvc_08_file_war_exploded/
可在指定的位置中找到上传的文件
10.4.文件下载
10.4.1.文件下载步骤
- 设置response响应头
- 读取文件——InputStream
- 写出文件——OutputStream
- 执行操作
- 关闭流(先开后关)
10.4.2.代码实现(修改FileController.java)
package P29.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.commons.CommonsMultipartFile;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;@Controller
public class FileController {// 以下是下载图片的代码@RequestMapping(value="/download")public String downloads(HttpServletResponse response , HttpServletRequest request) throws Exception{//要下载的图片地址(这里希望从/upload地址下载一个名为“截图1.png”的图片)String path = request.getServletContext().getRealPath("/upload");String fileName = "截图1.png";//1、设置response 响应头response.reset(); //设置页面不缓存,清空bufferresponse.setCharacterEncoding("UTF-8"); //字符编码response.setContentType("multipart/form-data"); //二进制传输数据//设置响应头response.setHeader("Content-Disposition","attachment;fileName="+ URLEncoder.encode(fileName, "UTF-8"));File file = new File(path,fileName);//2、 读取文件--输入流InputStream input=new FileInputStream(file);//3、 写出文件--输出流OutputStream out = response.getOutputStream();byte[] buff =new byte[1024];int index=0;//4、执行 写出操作while((index= input.read(buff))!= -1){out.write(buff, 0, index);out.flush();}out.close();input.close();return null;}}
10.4.3.运行
http://localhost:8080/springmvc_08_file_war_exploded/download
下载到浏览器指定的保存地址
完结撒花
SpringMVC部分的学习终于告一段落了!!!
附上SSM框架整合思维导图(还有很多部分需要学习)