最近在学习SpringMVC,记录一下SpringMVC进行文件上传的方法,以备以后查阅
一、准备工作
使用maven搭建一个web项目,在xml文件中进行如下配置
<!-- 中文乱码-->
<filter>
<filter-name>characterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>characterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<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>dispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
导入pom依赖
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<!-- 版本控制-->
<spring.version>5.0.2.RELEASE</spring.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.47</version>
</dependency>
<!-- 上传组件 -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
</dependencies>
准备文件上传页面
<form action="file/fileupload" method="post" enctype="multipart/form-data">
<input type="file" name="upload">
<input type="submit" value="上传文件"/>
</form>
上传成功,跳转的success.jsp页面
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>成功页面</h1>
<hr>
</body>
</html>
二、进行文件上传
1.传统文件上传方式
在springMVC.xml文件中进行如下配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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">
<!-- 配置spring容器创建容器时需要扫描的包 -->
<context:component-scan base-package="cn.cyikns.controller"/>
<!-- 配置视图简析器-->
<bean id="resourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/pages/"/>
<property name="suffix" value=".jsp"/>
</bean>
<!-- 哪些静态文件应该放行-->
<mvc:resources mapping="/css/**" location="/css/"/>
<mvc:resources mapping="/images/**" location="/images/"/>
<mvc:resources mapping="/js/**" location="/js/"/>
<!-- 配置Spring扫描注解支持-->
<mvc:annotation-driven/>
</beans>
在controller中写的方法
/**
* 传统文件上传方式
*
* @param request
* @return
* @throws FileUploadException
*/
@RequestMapping("/fileupload")
public String fileupload(HttpServletRequest request) throws FileUploadException {
// 获取上传的文件目录
String path = request.getSession().getServletContext().getRealPath("/uploads");
// 创建File对象
File file = new File(path);
if (!file.exists()) {
file.mkdirs();
}
// 创建文件磁盘项工厂
DiskFileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload fileUpload = new ServletFileUpload(factory);
// 解析request对象
List<FileItem> fileItems = fileUpload.parseRequest(request);
// 遍历
for (FileItem item : fileItems) {
// 判断文件项是普通文件还是上传文件
if (item.isFormField()) {
// 普通字段
} else {
// 上传文件
try {
/* // 获取到上传文件的filename
String name = item.getName();
String prename = UUID.randomUUID().toString().replace("-", "");
String filename = prename + name;*/
// 获取上传文件的扩展名
String name = item.getName();
String filenamewithoutsuffix = name.substring(0, name.lastIndexOf("."));
String suffix = name.substring(name.lastIndexOf(".") + 1);
System.out.println("没有后缀的文件名:" + filenamewithoutsuffix + " 文件的后缀名:" + suffix);
String prefixName = UUID.randomUUID().toString().replace("-", "");
String filename = prefixName + filenamewithoutsuffix + "." + suffix;
// 上传文件
item.write(new File(file, filename));
// 删除临时文件
item.delete();
} catch (Exception e) {
e.printStackTrace();
}
}
}
return "success";
}
传统方式需要自己手动去解析request,并且进行遍历,比较麻烦
2.Springmvc方式上传文件
在上文springMVC.xml文件的基础上增加文件解析器对象
<!-- 配置文件解析器对象,要求id名称必须是multipartResolver-->
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="10485760"/>
</bean>
上传页面还是与之前保持不变
编写controller方法,如下
/**
* MultipartFile的变量名一定要去页面input[type=File]的name名称保持一致
*
* @param request
* @param upload
* @return
*/
@RequestMapping("/fileupload2")
public String fileupload2(HttpServletRequest request, MultipartFile upload) throws IOException, ParseException {
// 先获取文件要存储的路径
Date date = new Date();
String s = date.toString();
SimpleDateFormat format = new SimpleDateFormat("yyyy/MM/dd");
String dateStr = format.format(date);
System.out.println(dateStr);
String path = request.getSession().getServletContext().getRealPath("/uploads/" + dateStr);
// 创建File对象
File file = new File(path);
if (!file.exists()) {
file.mkdirs();
}
// 获取文件上传名称
String filename = upload.getOriginalFilename();
String uuid = UUID.randomUUID().toString().replace("-", "");
// 把文件名称唯一化
filename = uuid + filename;
// 上传文件
upload.transferTo(new File(file, filename));
return "success";
}
这里重点注意MultipartFile upload
的参数名必须与上传文件中input的name属性名保持一致,否则会出现解析错误。
这里记录一个坑,当我们写完之后你会发现上传中文名称的文件会出现乱码,所以还需要做一些操作
1、在上传文件页面header位置,写上编码
<!-- html 4 的编码设置方式 -->
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<!-- html 5 的编码设置方式 -->
<meta charset="UTF-8">
2、还需要在springmvc配置的文件解析其中加上
<property name="defaultEncoding" value="UTF-8"/>
因为默认是iso编码(这种情况request.getCharacterEncoding获得值是null,其实就是ISO编码)。
完整Springmvc.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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">
<!-- 配置spring容器创建容器时需要扫描的包 -->
<context:component-scan base-package="cn.cyikns.controller"/>
<!-- 配置视图简析器-->
<bean id="resourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/pages/"/>
<property name="suffix" value=".jsp"/>
</bean>
<!-- 配置文件解析器对象,要求id名称必须是multipartResolver-->
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="defaultEncoding" value="UTF-8"/>
<property name="maxUploadSize" value="10485760"/>
</bean>
<!-- 哪些静态文件应该放行-->
<mvc:resources mapping="/css/**" location="/css/"/>
<mvc:resources mapping="/images/**" location="/images/"/>
<mvc:resources mapping="/js/**" location="/js/"/>
<!-- 配置Spring扫描注解支持-->
<mvc:annotation-driven/>
</beans>