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;
??? }
}
?
|