最近在學習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>