1.基于springmvc的文件上传
1.1导入依赖
依赖包:spring-webmvc servlet-api commons-fileupload
<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.1.5.RELEASE</version>
</dependency>
<!-- 配置ServletAPI依赖 -->
<!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.0.1</version>
<scope>provided</scope>
</dependency>
<!-- commons-fileupload组件 -->
<!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
1.2 配置web.xml
由于SpringMVC不支持静态资源的访问,因此可以配置default允许访问静态资源
default的mapping的配置,一定要写在dispatcherServle的mapping的配置之前。
<?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">
<display-name>Archetype Created Web Application</display-name>
<servlet>
<servlet-name>DispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.jpg</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.html</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.js</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.css</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>DispatcherServlet</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
</web-app>
1.3 需要的接口和方法
1.3.1 MultipartResolver接口
MultipartResolver 用于处理文件上传,当收到请求时 DispatcherServlet 的 checkMultipart() 方法会调用 MultipartResolver 的 isMultipart() 方法判断请求中是否包含文件。如果请求数据中包含文件,则调用 MultipartResolver 的 resolveMultipart() 方法对请求的数据进行解析,然后将文件数据解析成 MultipartFile 并封装在 MultipartHttpServletRequest (继承了 HttpServletRequest) 对象中,最后传递给 Controller。
在 MultipartResolver 接口中有如下方法:
boolean isMultipart(HttpServletRequest request); // 是否是一个文件上传请求
MultipartHttpServletRequest resolveMultipart(HttpServletRequest request); // 解析请求
void cleanupMultipart(MultipartHttpServletRequest request);//清理上传的资源
我们用它的实现类CommonsMultipartResolver
1.3.2 CommonsMultipartResolver类
MultipartResolver 是一个接口,它的实现类如下图所示,分为CommonsMultipartResolver 类和 StandardServletMultipartResolver 类。
它的构造方法需要一个servletContext对象
public CommonsMultipartResolver(ServletContext servletContext) {
this();
this.setServletContext(servletContext);
}
其中 CommonsMultipartResolver 使用 commons Fileupload 来处理 multipart 请求,所以在使用时,必须要引入相应的 jar 包;而 StandardServletMultipartResolver 是基于 Servlet 3.0来处理 multipart 请求的,所以不需要引用其他 jar 包,但是必须使用支持 Servlet 3.0的容器才可以,以tomcat为例,从 Tomcat 7.0.x的版本开始就支持 Servlet 3.0了。
配置文件中配置:
<!-- 定义文件上传解析器-->
<!-- Spring 组件 CommonsMultipartResolver 类的主要作用是配置文件上传的一些属性,也可以控制上传文件的大小。 -->
<!--必须保证 id 是 multipartResolver-->
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!--设置默认编码-->
<property name="defaultEncoding" value="UTF-8"/>
<!-- 设定文件上传的最大值为5M,5*1024*1024-->
<property name="maxUploadSize" value="5242880"></property>
<!--设定文件最大缓存大小,如果小于这个参数不会生成临时文件,默认为10240-->
<property name="maxInMemorySize" value="10240"/>
</bean>
上传表单:
要在 form 标签中加入 enctype="multipart/form-data" 表示该表单要提交文件。
<form action="xxxxx " method="xxx" enctype="multipart/form-data">
<input type="file" name="file">
<input type="submit" value="提交">
</form>
1.3.3 MultipartRequest接口和实现类MultipartHttpServletRequest
MultipartRequest接口下有如下方法:
MultipartHttpServletRequest类
1.3.4 MultipartFile接口
MultipartFile 封装了请求数据中的文件,此时这个文件存储在内存中或临时的磁盘文件中,需要将其转存到一个合适的位置,因为请求结束后临时存储将被清空。
在 MultipartFile 接口中有如下方法:
String getName(); // 获取参数的名称
String getOriginalFilename(); // 获取文件的原名称
String getContentType(); // 文件内容的类型
boolean isEmpty(); // 文件是否为空
long getSize(); // 文件大小
byte[] getBytes(); // 将文件内容以字节数组的形式返回
InputStream getInputStream(); // 将文件内容以输入流的形式返回
void transferTo(File dest); // 将文件内容传输到指定文件中
1.4 springmvc.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/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!--开启注解-->
<mvc:annotation-driven/>
<!-- 开启自动扫描包-->
<context:component-scan base-package="com.weiwei.springmvcfile"/>
<!-- 定义文件上传解析器-->
<!-- Spring 组件 CommonsMultipartResolver 类的主要作用是配置文件上传的一些属性,也可以控制上传文件的大小。 -->
<!--必须保证 id 是 multipartResolver-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!--设置默认编码-->
<property name="defaultEncoding" value="UTF-8"/>
<!-- 设定文件上传的最大值为5M,5*1024*1024-->
<property name="maxUploadSize" value="5242880"/>
<!--设定文件最大缓存大小,如果小于这个参数不会生成临时文件,默认为10240-->
<property name="maxInMemorySize" value="10240"/>
</bean>
</beans>
1.5 文件上传页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>上传文件</title>
</head>
<body>
<form action="upload.do" method="post" enctype="multipart/form-data">
<input type="file" name="myfile1">
<input type="file" name="myfile2">
<input type="submit" value="上传">
</form>
</body>
</html>
1.6 uploadController类
package com.weiwei.springmvcfile.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.MultipartRequest;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
import org.springframework.web.servlet.ModelAndView;
import sun.security.krb5.internal.tools.Klist;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
@Controller
public class UploadController {
@RequestMapping(value = "upload.do",method = RequestMethod.POST)
@ResponseBody
public ModelAndView uploadFile(HttpServletRequest request){
List<String> list=new ArrayList();
ModelAndView modelAndView = new ModelAndView();
//创建CommonsMultipartResolver对象
ServletContext servletContext = request.getSession().getServletContext();
CommonsMultipartResolver commonsMultipartResolver = new CommonsMultipartResolver(servletContext);
//检验请求是否是一个文件上传请求,commonsMultipartResolver中有一个方法isMultipart
if(commonsMultipartResolver.isMultipart(request)){
//将HttpServletRequest转换成 MultipartHttpServletRequest文件上传请求对象
MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
//从文件上传请求中得到文件名称,返回迭代器
Iterator<String> fileNames = multipartRequest.getFileNames();
//遍历迭代器
while(fileNames.hasNext()){
String filehttpUrl="";
//得到input元素的name属性值
String shuxingname = fileNames.next().toString();//myfile1 myfile2
//根据name属性值得到上传来的文件名称,返回MultipartFile对象
MultipartFile multipartFile = multipartRequest.getFile(shuxingname);
if(multipartFile!=null){
//得到被传上来的文件的真实名称【图片1.jpg】
String originalFilename = multipartFile.getOriginalFilename();
//重新组织文件名名称,防止出现上传的文件名称相同而失败
//得到文件真实名称的后缀名
String houzhuiname = originalFilename.substring(originalFilename.lastIndexOf("."));
//以系统时间毫秒数命名文件名称
long currentTimeMillis = System.currentTimeMillis();
String newfilename = currentTimeMillis + houzhuiname;
//System.out.println(newfilename);
//保存上传的文件到服务器
//获取项目的根目录,创建保存文件的目录
//F:\Tomcat8.0\apache-tomcat-8.0.52\webapps\demofile\fileupload
String rootpath = servletContext.getRealPath("/fileupload");
System.out.println(rootpath);
File uploadfile = new File(rootpath);
if (!uploadfile.exists()) {
//创建upload目录
uploadfile.mkdirs();
}
//保存文件的目录带文件名称
String pathfile = rootpath + File.separator + newfilename;
// System.out.println(pathfile);//F:\Tomcat8.0\apache-tomcat-8.0.52\webapps\demofile\fileupload\1646997723418.jpg
File savefile = new File(pathfile);
try {
//保存文件到本地磁盘
multipartFile.transferTo(savefile);
} catch (IOException e) {
e.printStackTrace();
}
//保存的文件在服务器的地址http://localhost:8080/demofile/fileupload/1646998210613.jpg
//想办法组成这个地址,需要返回给前端
String requrl = request.getRequestURL().toString();
//System.out.println(requrl);//http://localhost:8080/demofile/upload.do
filehttpUrl=requrl.substring(0,requrl.lastIndexOf("/"))+"/fileupload/"+newfilename;
System.out.println(filehttpUrl);
list.add(newfilename);
}else{
System.out.println("上传的是一个空文件");
}
}
modelAndView.addObject("mypicture", list);
modelAndView.setViewName("downfile.jsp");//设置跳转路径
}else {
System.out.println("http请求中没有文件");
}
return modelAndView;
}
}
2. 基于Springmvc的文件下载
2.1 下载页面jsp
<%--
Created by IntelliJ IDEA.
User: Betty
Date: 2022/3/12
Time: 12:00
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<html>
<head>
<title>下载文件</title>
</head>
<body>
<h3><a href="download.do?mypicture=${mypicture[0]}">下载图片${mypicture[0]}</a></h3>
<h3><a href="download.do?mypicture=${mypicture[1]}">下载图片${mypicture[1]}</a></h3>
</body>
</html>
2.2 下载控制类
package com.weiwei.springmvcfile.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 org.springframework.web.bind.annotation.RequestMethod;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
@Controller
public class DownloadController {
@RequestMapping(value = "download.do",method = RequestMethod.GET)
public ResponseEntity<byte[]> getDownload(HttpServletRequest request){
//得到指定下载的文件名称
String downname = request.getParameter("mypicture");
String realpath = request.getSession().getServletContext().getRealPath("/fileupload");
//创建保存文件目录的文件对象
File savedownfilepath = new File(realpath);
//创建被下载的文件对象
File file = new File(savedownfilepath, downname);
System.out.println(file.getAbsoluteFile());
//设置http协议头
HttpHeaders headers = new HttpHeaders();
headers.setContentDispositionFormData("attachment",downname);
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
ResponseEntity<byte[]> responseEntity=null;
try {
responseEntity = new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(file), headers, HttpStatus.CREATED);
}catch (Exception e){
e.printStackTrace();
}
return responseEntity;
}
}