SpringMVC高级特性
- SpringMVC三种处理资源方式
- Json数据交互
- Springmvc处理异常方式
- 文件上传下载
一、SpringMVC的拦截规则
昨天我们将SpringMVC拦截后缀设置为*.form
代表SpringMVC会拦截*.form
结尾的后缀
SpringMVC提供的拦截规则:
*.form
:代表以*.form
结尾的后缀请求都会进入springmvc管理
/:代表除了JSP以外拦截所有,html、css、js等静态web资源也会拦截
/*:拦截所有请求
1. 分析
如果SpringMVC拦截了静态资源会怎么样?会出现404错误!
在昨天的源码分析中分析发现,所有请求进入SpringMVC最终会寻找handler执行,很显然如果拦截到静态资源的话是肯定找不到对应的handler的,因此就会出现404情况。
2. 缺省servlet放行
tomcat提供的默认servlet(DefaultServlet),处理静态资源的(html/css/js),此Servlet在tomcat/conf/web.xml中有配置
<!--代表以html的任何请求进入Tomcat默认的Servlet处理(放行)-->
<servlet>
<servlet-name>default</servlet-name>
<servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
<init-param>
<param-name>debug</param-name>
<param-value>0</param-value>
</init-param>
<init-param>
<param-name>listings</param-name>
<param-value>false</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.html</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.png</url-pattern>
</servlet-mapping>
配置DefaultServlet需要引入依赖:
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-catalina</artifactId>
<version>8.5.41</version>
<!--此jar包在tomcat中已经有了,但是如果不引入此依赖项目则会报错,因此依赖范围provided就行-->
<scope>provided</scope>
</dependency>
回顾Maven依赖范围:
- compile:编译时需要,测试时需要,运行时需要,打包时需要
- provided:编译时需要,测试时需要,运行时不需要,打包时不需要
- runtime:编译时不需要,测试时需要,运行时需要,打包时需要
- Test:编译时不需要,测试时需要,运行不时需要,打包也需要
缺省servlet放行原理是如果是配置的后缀请求直接进入缺省servlet,而不是进入springmvc进行处理
但是如果springmvc的拦截规则配置成/*
代表拦截请求优先进入springmvc不进入缺省servlet导致出现404
因此如果想要使用缺省servlet方式放行静态资源springmvc拦截规则不能为/*
3. 配置resource放行静态资源
<!--
resources:配置springmvc放行
mapping:映射地址
location:具体目录
/js/*代表page下面的所有资源不拦截
/js/** 代表page下所有的资源不拦截包括子孙包
-->
<mvc:resources mapping="/js/**" location="/js/" />
<mvc:resources mapping="/css/**" location="/css/" />
<mvc:resources mapping="/img/**" location="/img/" />
<mvc:resources />由Spring MVC框架自己按配置的规则处理静态资源,并添加一些有用的附加值功能。
**注意:JSP页面不属于静态资源!**如果是常见的浏览器能解析的格式,直接按照协议返回,如果不是浏览器能直接解析的会返回下载头导致下载该jsp页面!
4. 配置SpringMVC静态资源处理
<mvc:default-servlet-handler />
Springmvc会在Spring MVC上下文中定义一个DefaultServletHttpRequestHandler
它会像一个检查员,对进入DispatcherServlet的URL进行筛查,如果发现是静态资源的请求,就将该请求转由Web应用服务器默认的Servlet处理,如果不是静态资源的请求,才由DispatcherServlet继续处理。
一般Web应用服务器默认的Servlet名称是"default",因此DefaultServletHttpRequestHandler可以找到它。如果你所有的Web应用服务器的默认Servlet名称不是"default",则需要通过default-servlet-name属性显示指定:
<mvc:default-servlet-handler default-servlet-name=“所使用的Web服务器默认使用的Servlet名称” />
<!--
default-servlet-name:缺省servlet的名称(默认值为default)
-->
<mvc:default-servlet-handler default-servlet-name="default"/>
DefaultServletHttpRequestHandler底层也是依赖缺省servlet,请求被springmvc拦截下来之后会判断是否是静态资源,如果是那么就走缺省servlet
4. 探究三种放行
web.xml:
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--配置springmvc配置文件的位置-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:dispatcher-servlet.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<!--配置拦截所有请求,jsp也不例外-->
<url-pattern>/*</url-pattern>
</servlet-mapping>
controller:
@Controller
public class Demo1Controller {
@RequestMapping("/demo1")
public String demo1() {
System.out.println("controller执行啦!");
return "/success.jsp";
}
}
发现跳转到的jsp页面以源码形式展示,这是因为web.xml中配置/*
导致jsp页面被拦截,而且配置的放行机制为
<mvc:default-servlet-handler />,把jsp页面交给缺省servlet,而缺省servlet只能处理静态页面,jsp严格来说不算是静态页面,缺省servlet就把他当做普通文本处理了
解决方法:web.xml中拦截规则使用/
5. 放行规则小结:
缺省servlet放行:请求没有进入springmvc,而是直接进入缺省servlet进行处理放行
resource放行:实质上请求是进入了springmvc然后由springmvc自己处理资源,达到放行效果
default-servlet-handler放行:请求进入springmvc然后对其进行筛选,发现是个"静态"资源就交给缺省servlet去处理,但是缺省servlet只会处理静态资源,如果是jsp会特殊处理!
6. 视图解析器
打开spring-webmvc-5.0.6.RELEASE.jar下的DispatcherServlet.properties文件查看默认注册的视图解析器
我们希望不适用默认的视图解析器,而是在视图解析器上"做点手脚"
<!--配置视图解析器
prefix:视图解析器的前缀
suffix:视图解析器的后缀
-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/jsp/" />
<property name="suffix" value=".jsp" />
</bean>
controller:
package com.dfbz.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class Demo1Controller {
@RequestMapping("/demo1") //自定义属性绑定
public String demo1(Model model) {
model.addAttribute("user","xiaodong");
return "index"; //自动跳转到 /jsp/index.jsp页面
}
}
二. Json的支持
所谓的对JSON的支持,就是SpringMVC支持自动将JSON转换成JAVA对象,也支持将Java对象自动转成JSON.
SpringMVC本身没有对JSON数据处理的类库.要支持JSON的自动转换必须导入JSON的支持包
Jackson依赖:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.8</version>
</dependency>
1. JSON转换成JAVA对象
需求:请求发送一个JSON字符串给执行方法,执行方法根据@RequestBody这个注解强制将
如果前端发送的不是JSON字符串则不能使用@RequestBody
请求发送过来的JSON转换成Java对象.
1.1页面以JSON字符串传递方式:
"{\"username\": \"xiaodong\", \"address\": \"guangzhou\", \"birthday\": \"2000-10-10\"}"
配置步骤
客户端请求
$.ajax({
url: "/demo5_1.form",
contentType:"application/json", //告知ajax引擎传递的是json类型
type:"post", //传递json字符串必须使用post提交
data: "{\"username\": \"xiaodong\", \"address\": \"guangzhou\", \"birthday\": \"2000-10-10\"}",
success: function (data) {
}
});
控制器代码
@RequestMapping("/demo5_1")
public String demo5_1(@RequestBody User user) { //json字符串 转user
System.out.println(user);
return "/success.jsp";
}
Json字符串转Map
前端
$("#test3").click(function () {
$.ajax({
url: "/demo5_2.form",
type:"post",
contentType:"application/json",
//Map类型只支持json字符串
data: "{\"username\": \"xiaodong\", \"address\": \"guangzhou\", \"birthday\": \"2000-10-10\"}",
success: function (data) {
}
});
});
后台:
//json字符串 转map Map类型不支持json对象
@RequestMapping("/demo5_2")
public String demo5_1(@RequestBody Map map) {
System.out.println(map);
return "/success.jsp";
}
2. 数据返回到页面,自动将Java对象转成JSON
Java对象转Json
借助@ResponseBody把Java对象转换为json对象,并且把响应头类型改为application/json;charset=utf8
前端:
$("#test4").click(function () {
$.ajax({
url: "/demo5_3.form",
success: function (data) {
alert(data);
alert(JSON.stringify(data));
}
});
});
后台:
@RequestMapping("/demo5_3")
//表示对象以json对象写出到前端 并修改contentType:'application/json;charset=utf8'
@ResponseBody
public User demo5_3() { //user转json对象
User user = new User();
user.setId(20);
user.setUsername("xiaobiao");
user.setPassword("admin");
user.setAddress("guangzhou");
user.setBirthday(new Date());
return user;
}
将Map对象转JSON对象
$("#test5").click(function () {
$.ajax({
url: "/demo5_4.form",
success: function (data) {
alert(data);
alert(JSON.stringify(data));
}
});
});
@RequestMapping("/demo5_4")
@ResponseBody
public Map demo5_4() { //map转json对象
Map map=new HashMap();
map.put("id",20);
map.put("username","xiaobiao");
map.put("password","admin");
map.put("address","guangzhou");
map.put("birthday",new Date());
return map;
}
小结:
使用@ResponseBody如果返回的是一个Java对象,那么springmvc会帮我们自动转成json对象写入到前端
并且把响应头(Content-Type)设置为application/json;charset=utf8
,但是如果直接返回一个字符串,那么@ResponseBody
会以普通文本方式写入到前端Content-Type还是默认的text/plain;charset=ISO-8859-1
就会造成中文乱码现象
@produces :设置响应的类型(Content-Type)
@consumes:规定请求的类型(Content-Type)
案例produces:响应普通字符串
如果响应的直接是个字符串则会出现乱码现象
@RequestMapping(value = "/demo5_5")
@ResponseBody
public String demo5_5() {
return "{\"username\":\"东方标准\"}";
}
查看响应头:
修改代码:
//规定响应的格式为 application/json;charset=utf8
@RequestMapping(value = "/demo5_5",produces = "application/json;charset=utf8")
@ResponseBody
public String demo5_5() {
return "{\"username\":\"东方标准\"}";
}
查看响应头:
以Json对象形式返回,并且编码为utf8
案例consumes:
我们知道@RequestBody能够把前台传递过来的json字符串自动封装到后台的Java对象中,但是前台提交的方式必须是POST,除此之外请求头(Content-Type)必须是application/json;charset=utf8
,我们能不能在后台就规定(提示)一下前端传递的请求头的类型呢?用@RequestMapping注解中的consumes!
后台代码:
//规定前端提交的请求头必须application/json;charset=utf8
@RequestMapping(value = "/demo5_7", consumes = "application/json;charset=utf8")
@ResponseBody
public User demo5_7(@RequestBody User user) { //map转json对象
return user;
}
前端代码:
$("#test6").click(function () {
var json={username:"东方标准",password:"admin"};
$.ajax({
url: "/demo5_7.form",
type:"post",
contentType: "application/json;charset=utf8",
data: "{\"username\": \"xiaodong\", \"address\": \"guangzhou\", \"birthday\": \"2000-10-10\"}"
success: function (data) {
alert(data);
alert(JSON.stringify(data));
}
});
});
3. 探究springmvc参数封装
1. 表单entype类型
- application/x-www-form-urlencoded
这是默认的编码类型,使用该类型时,会将表单数据中非字母数字的字符转换成转义字符,如"%HH"
,然后组合成这种形式key1=value1&key2=value2
;所以后端在取数据后,要进行解码。
- multipart/form-data
这是一个常见的 POST 数据提交的方式。我们使用表单上传文件时,必须让 表单的 enctype
等于 multipart/form-data
。
注意:
- 一般来说,
method
和enctype
是两个不同的互不影响的属性,但在传文件时,method
必须要指定为POST
,否则文件只剩下filename了; - 当没有传文件时,enctype会改回默认的application/x-www-form-urlencoded。
- text/plain
按照键值对排列表单数据key1=val1\r\nkey2=val2
,不进行转义。
- application/json及其他MIME类型
application/json 这个 Content-Type 作为响应头大家肯定不陌生。实际上,现在越来越多的人把它作为请求头,用来告诉服务端消息主体是序列化后的 JSON 字符串。由于 JSON 规范的流行,除了低版本 IE 之外的各大浏览器都原生支持 JSON.stringify,服务端语言也都有处理 JSON 的函数,使用 JSON 不会遇上什么麻烦。
表单数据编码类型application/json
,已经被W3C遗弃(详见HTML JSON Form Submission),建议不要在<form enctype="...">
中使用了,即使用了如果浏览器不支持,也会替换成application/x-www-form-urlencoded
。
同理,其余的MIME类型,也不支持,均会替换成默认编码application/x-www-form-urlencoded
contentType对照表:http://tool.oschina.net/commons/
2. 探究springmvc自动封装
我们前面已经学过,不使用@RequestBody注解springmvc也能帮我们自动封装Java对象
但是是有前提的:
-
请求类型为get:**提交的请求头必须是null(get提交设置了别的entype也会自动为null),因此get提交不需要担心请求头问题
-
请求类型为post:**提交的请求头必须是
application/x-www-form-urlencoded
类型(表单默认的提交类型),ajax不写也是默认这种类型
只要提交数据格式为username=东方标准&admin=123456
springmvc都能帮我们封装数据,不限提交方式get/post
我们前面知道ajax提交使用json字符串,而且后台必须需用@RequestBody注解来强制封装,我们知道前端有json对象方式提交数据,此时如果请求头类型为application/x-www-form-urlencoded
json对象也会默认格式化为username=东方标准&admin=123456
这种数据格式往后台提交,能够自动封装数据
测试springmvc自动封装(get)
前端:
<!--
get方式提交,ContentType即使设置了也是null
post方式可以
-->
<form action="/demo5_7.form" method="get" entype="application/x-www-form-urlencoded">
<input type="text" name="username">
<input type="text" name="password">
<input type="submit">
</form>
后台:
@RequestMapping(value = "/demo5_7")
@ResponseBody
public User demo5_7(User user, HttpServletRequest request) throws IOException { //map转json对象
/**
* get提交ContentType为null
* post提交ContentType为application/x-www-form-urlencoded
*/
String contentType = request.getContentType();
System.out.println(contentType);
System.out.println(user);
return user;
}
测试json对象自动封装数据(post)
前端:
$("#test6").click(function () {
var json = {username: "dfbz", password: "admin"};
$.ajax({
url: "/demo5_7.form",
type: "post",
//请求头类型设置为默认的(不写也可以post默认就是application../x-www...)
contentType:"application/x-www-form-urlencoded; charset=UTF-8",
data: json, //传递json对象
success: function (data) {
alert(data);
alert(JSON.stringify(data));
}
});
});
后台:
@RequestMapping(value = "/demo5_7")
@ResponseBody
public User demo5_7(User user, HttpServletRequest request) throws IOException { //map转json对象
/**
* ajax提交不写contentType默认为application/x-www-form-urlencoded
*/
String contentType = request.getContentType();
System.out.println(contentType);
System.out.println(user);
return user;
}
测试json字符串自动封装数据
前端:
$("#test6").click(function () {
var json = {username: "dfbz", password: "admin"};
$.ajax({
url: "/demo5_6.form",
type: "post", //提交方式必须使用post
//提交json字符串自动封装必须使用application/json
contentType:"application/json;charset=utf8",
data: JSON.stringify(json),
success: function (data) {
alert(data);
alert(JSON.stringify(data));
}
});
});
后台:
/**
* 1. 使用@RequestBody前端必须传递json字符串
* 2. 请求类型必须是application/json
* 3. 必须是post提交
* @param user
* @return
*/
@RequestMapping(value = "/demo5_6")
@ResponseBody
public User demo5_6(@RequestBody User user) {
return user;
}
小结:我们只要记住get一般是用于查询的,因此只要封装基本数据类型就可以,post一般做添加的因此需要封装Java对象
@RequestBody:强制封装,只能用于前端提交json字符串的,而且提交类型必须是application/json;charset=utf8
,提交类型必须是Post(因为get的提交类型为null)
自动封装:用于前端提交key=val&key=val
类型的数据,提交方式为get或者post+提交类型application/x-www-form-urlencoded;
3. 表单序列化
有时候我们也需要使用ajax提交整个表单的数据,如果将整个表单的数据手动拼接为json对象未免太过麻烦,好在jquery有帮我们提供一个表单序列化方法(serialize),将整个表单的数据序列化为key1=val1&key2=val2
这样的格式,加上我们前面学过的知识可以使用ajax将整个表单的数据提交到后台并能自动封装了!
前端:
<form action="/demo5_7.form" id="mainForm" >
<input type="text" name="username">
<input type="text" name="password">
</form>
<button id="test6">ajax提交表单数据</button>
<script>
$("#test6").click(function () {
$.ajax({
url: "/demo5_7.form",
type: "post",
data: $("#mainForm").serialize(), //序列化表单数据
success: function (data) {
alert(data);
alert(JSON.stringify(data));
}
})
});
</script>
后端:
@RequestMapping(value = "/demo5_7")
@ResponseBody
public User demo5_7(User user, HttpServletRequest request) throws IOException {
System.out.println(user);
return user;
}
三、SpringMVC的异常处理方式
1.单个异常处理方式
package com.dfbz.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class Demo2Controller {
@RequestMapping("/demo2_1")
@ResponseBody
public String test1() {
System.out.println("东方");
int i = 1 / 0;
System.out.println("标准");
return "你好好";
}
/**
* 当前controller方法出现异常进入此方法
* @param model
* @param e:出现的异常对象
* @return
*/
@ExceptionHandler(ArithmeticException.class)
public String test2(Model model, Exception e) {
model.addAttribute("error", e.getMessage());
System.out.println("出现异常啦!");
return "error";
}
}
2. 全局异常处理方式
需要我们编写一个类实现HandlerExceptionResolver接口
定义全局异常:
package com.dfbz.exception;
import com.dfbz.controller.Demo2Controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
/**
* 全局异常处理类
*/
public class MyExceptionHandler implements HandlerExceptionResolver {
/**
*
* @param request
* @param response
* @param obj :出现异常handler(HandlerMethod类型)
* @param e :出现的异常对象
* @return
*/
@Override
public ModelAndView resolveException(
HttpServletRequest request,
HttpServletResponse response,
Object obj,
Exception e) {
HandlerMethod method= (HandlerMethod) obj;
ModelAndView mav=new ModelAndView();
mav.setViewName("error");
mav.addObject("error",e.getMessage());
return mav;
}
}
注入到IOC容器中:
<!--把异常类注入IOC容器-->
<bean class="com.dfbz.exception.MyExceptionHandler" />
测试controller:
@RequestMapping("/demo2_1")
@ResponseBody
public String test1() {
System.out.println("东方");
int i = 1 / 0;
System.out.println("标准");
return "你好好";
}
注意:方法处理异常优先级比全局异常高!如果进入了方法处理异常则不会进入全局异常方法中!
注解方式实现全局异常
使用@ControllerAdvice
注解可以配置全局异常
@ExceptionHandler()
:设置什么异常才会进入方法
package com.dfbz.exception;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.servlet.ModelAndView;
@ControllerAdvice //全局异常注解
public class AnnoMyExceptionHandler {
/**
*
* @param e 触发的异常对象
* @return
*/
@ExceptionHandler(value = Exception.class) //传入什么异常需要进入此方法
public ModelAndView resolveException(Exception e) {
ModelAndView mav=new ModelAndView();
mav.setViewName("error");
mav.addObject("error",e.getMessage());
return mav;
}
}
3. SpringMVC提供的处理方式
只需要在spring.xml配置文件中定义即可,适合全局处理简单的异常,缺点不能自定义异常信息
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<property name="exceptionMappings">
<props>
<!-- <prop key="java.lang.ArithmeticException">/jsp/error.jsp</prop>-->
<!--已经配置了视图解析器-->
<prop key="java.lang.ClassCastException">index</prop>
<prop key="java.lang.ArithmeticException">error</prop>
</props>
</property>
</bean>
4. 框架底层异常和无法捕获的异常处理方案
在web.xml文件中定义此类的处理方法
<!--如果程序出现Throwable异常则会跳转到/index.jsp页面-->
<error-page>
<exception-type>java.lang.Throwable</exception-type>
<location>/index.jsp</location>
</error-page>
<error-page>
<!--如果页面出现404则跳转到/success.jsp页面-->
<error-code>404</error-code>
<location>/success.jsp</location>
</error-page>
四、上传下载的实现
1.文件上传
SpringMVC支持文件上传组件
commons-fileupload组件.
commons-fileupload依赖commons-io组件.
1.1 文件上传开发流程
a.编写form表单 表单必须是post请求方式,enctype必须是multipart/form-data
(默认值是:application/x-www-form-urlencoded)
b.配置文件上传解析器 bean的名字不能写错,一定是multipartResolver
c.在controller中编写处理文件上传的方法,参数为MultipartFile
1.2 配置步骤
1.2.1.导入依赖
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.3</version>
</dependency>
1.2.2. 前端页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%--
文件上传enctype类型必须是multipart/form-data
提交方式必须是post
--%>
<form action="/upload" enctype="multipart/form-data" method="post">
<input type="file" name="file">
<input type="submit">
</form>
</body>
</html>
1.2.3. controller
@RequestMapping("/upload")
public String upload(HttpServletRequest request, MultipartFile file) throws IOException { //变量名一定要和前端提交的name一致
String fileName = file.getOriginalFilename();
String realPath = request.getRealPath("upload"); //获取服务器端某个文件夹的绝对路径
file.transferTo(new File(realPath +"/"+ UUID.randomUUID().toString() + fileName));
return "success";
}
1.2.4. dispatcher-servlet.xml配置
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!--默认文件最大大小,单位b-->
<property name="maxUploadSize" value="20000000"></property>
</bean>
注意:
因为核心控制器对上传解释器的名字是固定的. 是multipartResolver,所以我们配置上传解释器,名字必须是multipartResolver
查询核心控制器DispacherServlet代码,发现multipartResolver一个固定加载的属性。
public class DispatcherServlet extends FrameworkServlet {
public static final String MULTIPART_RESOLVER_BEAN_NAME = "multipartResolver";
如图所示
1.3. 多文件上传
前端页面
<h3>多文件上传</h3>
<form action="/uploads" enctype="multipart/form-data" method="post">
<input type="file" name="files">
<input type="file" name="files">
<input type="file" name="files">
<input type="file" name="files">
<input type="submit">
</form>
controller
@RequestMapping("/uploads")
public String uploads(HttpServletRequest request, MultipartFile[] files) throws IOException { //变量名一定要和前端提交的name一致
String realPath = request.getRealPath("upload"); //获取服务器端某个文件夹的绝对路径
for (MultipartFile file : files) {
String fileName = file.getOriginalFilename();
file.transferTo(new File(realPath + "/" + UUID.randomUUID().toString() + fileName));
}
return "success";
}
dispatcher-servlet.xml配置:
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!--默认文件最大大小,单位b-->
<property name="maxUploadSize" value="20000000"></property>
</bean>
1.3.* 多文件上传
前端页面
<h3>多文件上传</h3>
<form action="/uploads" enctype="multipart/form-data" method="post">
<input type="file" name="files">
<input type="file" name="files">
<input type="file" name="files">
<input type="file" name="files">
<input type="submit">
</form>
controller
@RequestMapping("/uploads")
public String uploads(HttpServletRequest request, MultipartFile[] files) throws IOException { //变量名一定要和前端提交的name一致
String realPath = request.getRealPath("upload"); //获取服务器端某个文件夹的绝对路径
for (MultipartFile file : files) {
String fileName = file.getOriginalFilename();
file.transferTo(new File(realPath + "/" + UUID.randomUUID().toString() + fileName));
}
return "success";
}
dispatcher-servlet.xml配置:
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!--默认文件最大大小,单位b-->
<property name="maxUploadSize" value="20000000"></property>
</bean>
转载:https://blog.csdn.net/m0_47157676/article/details/108082936