通常使用ajax异步方式实现文件上传功能。
项目目录结构图如下:

实现步骤如下:
1.编写upload.html实现前端上传页面
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>文件上传</title>
<script src="https://code.jquery.com/jquery-3.5.1.min.js"
integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
<style>
#uploadImg{
width: 400px;
height: 300px;
}
</style>
</head>
<body>
<h1>文件上传</h1>
<hr>
<div>
<form id="uploadForm" action="#" enctype="multipart/form-data">
<table>
<tr>
<td class="title">上传照片:</td>
<td><input type="file" id="file" name="file" value="选择图片" onchange="uploadFile()"/></td>
</tr>
<!--以下是实现图片预览-->
<tr>
<td colspan="2">
<img id="uploadImg" src="#"/>
</td>
</tr>
</table>
</form>
</div>
<script>
//上传成功后的图片路径
var uploadPath = "http://localhost:8888/springmvctest/upload/";
function uploadFile() {
let formData = new FormData($('#uploadForm')[0]);
$.ajax({
type: 'post',
url: "http://localhost:8888/springmvctest/file/upload", //调用后台上传接口
data: formData,
cache: false,
processData: false,
contentType: false,
success: function (data) {
console.log(data);
$('#uploadImg').attr("src",uploadPath+data.data);
}
});
}
</script>
</body>
</html>
2.在pom.xml中添加commons-io上传组件依赖 Spring MVC实现上传必须依赖apache的commons-io组件。
<?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.simoniu</groupId>
<artifactId>springmvcdemo</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<name>springmvcdemo Maven Webapp</name>
<properties>
<spring.version>5.2.5.RELEASE</spring.version>
<servlet-version>3.0.1</servlet-version>
<jackson-versoin>2.10.0</jackson-versoin>
</properties>
<dependencies>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-core -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-web -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/junit/junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>${servlet-version}</version>
<scope>compile</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>${jackson-versoin}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson-versoin}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>${jackson-versoin}</version>
</dependency>
<!--springmvc添加了上传文件解析器,必须添加commons-io/commons-fileupload的依赖-->
<!--https://mvnrepository.com/artifact/commons-io/commons-io -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>1.4</version>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<!-- 此处的 1.8 指的是 JDK 的版本,目前一般为 1.7 或 1.8 -->
<target>1.8</target>
</configuration>
</plugin>
<!--servlet容器 jetty插件-->
<plugin>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>9.4.18.v20190429</version>
<configuration>
<webApp>
<!--项目的上下文配置-->
<contextPath>/springmvctest</contextPath>
</webApp>
<!--项目的端口号和服务器配置-->
<httpConnector>
<port>8888</port>
<host>localhost</host>
</httpConnector>
<scanIntervalSeconds>1</scanIntervalSeconds>
</configuration>
</plugin>
</plugins>
</build>
</project>
3.在applicationContext.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:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!-- 注册HandlerMapper、HandlerAdapter两个映射类 -->
<mvc:annotation-driven />
<!-- 访问静态资源 -->
<mvc:default-servlet-handler/>
<!-- 使用扫描机制扫描控制器类,控制器类都在controller包及其子包下 -->
<context:component-scan base-package="com" />
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" >
<!--前缀-->
<property name="prefix" value="/WEB-INF/jsp/"/>
<!--后缀-->
<property name="suffix" value=".jsp"/>
</bean>
<!-- 定义文件上传的解析器-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="defaultEncoding" value="UTF-8"/>
<!-- 指定所上传文件的总大小不能超过200KB。注意maxUploadSize属性的限制不是针对单个文件,而是所有文件的容量之和 -->
<property name="maxUploadSize" value="2000000"/>
<!--resolveLazily属性启用是为了推迟文件解析,以便在UploadController 中捕获文件大小异常-->
<property name="resolveLazily" value="true"/>
</bean>
</beans>
4.定义Controller返回的结果视图类Json.
package com.json;
import java.util.HashMap;
import java.util.Map;
/*
* Controller 返回的json格式类
*
* */
public class Json {
//默认成功响应
public static Map<String, Object> success(Object data) {
Map<String, Object> map = new HashMap<String, Object>();
map.put("code", 200);
map.put("msg", "ok");
map.put("data", data);
return map;
}
//自定义消息的成功响应
public static Map<String, Object> success(Object data,String msg) {
Map<String, Object> map = new HashMap<String, Object>();
map.put("code", 200);
map.put("msg", msg);
map.put("data", data);
return map;
}
public static Map<String, Object> success(Object data,String msg,String token) {
Map<String, Object> map = new HashMap<String, Object>();
map.put("code", 200);
map.put("msg", msg);
map.put("data", data);
map.put("token",token);
return map;
}
//自定义消息的失败响应
public static Map<String, Object> fail(String msg) {
Map<String, Object> map = new HashMap<String, Object>();
map.put("code", 400);
map.put("msg", msg); // Json.fail("验证码不正确"); Json.fail("用户名和密码");
return map;
}
//默认失败响应
public static Map<String, Object> fail() {
Map<String, Object> map = new HashMap<String, Object>();
map.put("code", 400);
map.put("msg", "error");
return map;
}
}
5.完成MyUtils工具类里面封装了文件上传方法
package com.util;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.util.UUID;
public class MyUtils {
public static String uploadFile(MultipartFile file,String path) throws Exception{
String fileName = file.getOriginalFilename(); //获得上传文件的文件名
//使用UUID生成一个不重复的文件名字。
String uploadFileName = createUUIDFileName(fileName);
//先判断文件的父目录是否存在,如果不存在先创建目录
File uploadFile = new File(path,uploadFileName);
if(!uploadFile.getParentFile().exists()){
uploadFile.getParentFile().mkdirs();
}
//在判断文件是否存在,如果存在先删除,再创建。
if(uploadFile.exists()){
uploadFile.delete();
}
uploadFile.createNewFile();
file.transferTo(uploadFile);
return uploadFile.getName();
}
public static String createUUIDFileName(String fileName){
String uuid = UUID.randomUUID().toString().replace("-","");
return uuid+fileName;
}
}
6.完成UploadController文件上传控制器类
package com.controller;
import com.json.Json;
import com.util.MyUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import javax.servlet.http.HttpServletRequest;
import java.util.Map;
@RestController
@RequestMapping("file")
public class UploadController {
@PostMapping("/upload")
public Map<String,Object> upload(HttpServletRequest request) {
System.out.println("开始上传...");
MultipartHttpServletRequest multipartRequest
= (MultipartHttpServletRequest) request;
MultipartFile mFile = multipartRequest.getFile("file");
System.out.println(mFile.getOriginalFilename());
String path = request.getSession().getServletContext().getRealPath("/upload");
System.out.println("上传绝对路径是:" + path);
try{
String image = MyUtils.uploadFile(mFile,path); //image 表示上传成功之后的文件名
System.out.println("文件上传成功!");
System.out.println("文件名是:" + image);
return Json.success(image,"uploadSuccess");
}
catch(Exception ex){
ex.printStackTrace();
return Json.fail("uploadFailure");
}
}
}
7.测试文件上传
