第一步:导入文件上传需要的包
commons-fileupload
详细的pom文件如下
<?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">
<modelVersion>4.0.0</modelVersion>
<groupId>com.zbt</groupId>
<artifactId>spring</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<name>spring Maven Webapp</name>
<!-- FIXME change it to the project's website -->
<url>http://www.example.com</url>
<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>
<org.springframework-version>4.0.3.RELEASE</org.springframework-version>
<org.aspectj-version>1.7.4</org.aspectj-version>
<org.slf4j-version>1.7.5</org.slf4j-version>
<hibernate.version>4.3.5.Final</hibernate.version>
<c3p0.version>0.9.5.2</c3p0.version>
<mysql.version>5.1.44</mysql.version>
<taglibs.version>1.2.5</taglibs.version>
</properties>
<dependencies>
<!--Spring-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${org.springframework-version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${org.springframework-version}</version>
</dependency>
<!--Logging-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${org.slf4j-version}</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.4</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
<!--@Inject-->
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
</dependency>
<!--Servlet-->
<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.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.taglibs</groupId>
<artifactId>taglibs-standard-impl</artifactId>
<version>${taglibs.version}</version>
</dependency>
<dependency>
<groupId>org.apache.taglibs</groupId>
<artifactId>taglibs-standard-jstlel</artifactId>
<version>${taglibs.version}</version>
</dependency>
</dependencies>
<build>
<finalName>spring</finalName>
</build>
</project>
第二步在SpringMVC中配置文件上传解析器
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!--设置文件最大上传的大小-->
<property name="maxUploadSize" value="100000"/>
</bean>
详细配置文件如下
<?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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="com.zbt.controller"/>
<context:annotation-config/>
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="100000"/>
</bean>
<bean id="jspViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
</beans>
第三步在Controller中使用MultiPart 类型接受File文件
package com.zbt.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.RequestParam;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
/**
* Created by luckyboy on 2018/8/23.
*/
@Controller
@RequestMapping("/file")
public class FileUploadController {
@RequestMapping(value="/upload",method= RequestMethod.POST)
public String upload(@RequestParam("name")String name ,@RequestParam("file") MultipartFile file){
if(file!= null){
try {
byte[] bytes = file.getBytes();
}catch (IOException e) {
e.printStackTrace();
}
return "success";
}else{
return "fail";
}
}
}
文件上传详解
DispactherServlet.doDispatch
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
HttpServletRequest processedRequest = request;
HandlerExecutionChain mappedHandler = null;
boolean multipartRequestParsed = false;
//由DispatcherServlet的checkMultipart(request)返回一个一个HttpprocessRequest子类MultipartHttpServletRequest
processedRequest = checkMultipart(request);
//如果是一个文件上传,processRequest != request
multipartRequestParsed = processedRequest != request;
//后面就是处理器映射了、视图渲染等操作
}
DispactherServlet.checkMultipart
protected HttpServletRequest checkMultipart(HttpServletRequest request) throws MultipartException {
//multipartResolver不为空,且由方法isMultipart(request)判断是文件上传,那么就解析request返回一个MultipartHttpServletRequest
if (this.multipartResolver != null && this.multipartResolver.isMultipart(request)) {
if (request instanceof MultipartHttpServletRequest) {
logger.debug("Request is already a MultipartHttpServletRequest - if not in a forward, " +
"this typically results from an additional MultipartFilter in web.xml");
}
else {
return this.multipartResolver.resolveMultipart(request);
}
}
// If not returned before: return original request.
return request;
}
//MultipartResolver的一个子类调用CommonsMultipartResolver调用ServletFileUpload判断是否是文件
@Override
public boolean isMultipart(HttpServletRequest request) {
return (request != null && ServletFileUpload.isMultipartContent(request));
}
//由ServletFileUpload调用FileUploadBase.isMultipartContent是否是文件上传
public static final boolean isMultipartContent(
HttpServletRequest request) {
if (!POST_METHOD.equalsIgnoreCase(request.getMethod())) {
return false;
}
return FileUploadBase.isMultipartContent(new ServletRequestContext(request));
}
//由FileUpload中的isMultipartContent从contentType中判断是否是文件上传,是则返回true,否则返回false
public static final boolean isMultipartContent(RequestContext ctx) {
String contentType = ctx.getContentType();
if (contentType == null) {
return false;
}
if (contentType.toLowerCase(Locale.ENGLISH).startsWith(MULTIPART)) {
return true;
}
return false;
}
第一步:我们配置多路文件解析器,当一个请求到来时,在DispatcherServlet的doDispatcher会将HttpServletRequest进行一个校验
第二步:校验的工作是由MultipartResolver的一个子类CommonsMultipartResolver去调用一系列的方法最终从request的contentType来判断是否是一个文件上传,如果是则将request包装成一个MultipartHttpServletRequest
第三步:对包装后的MultipartMultipartHttpServletRequest进行处理