一、SpringMVC简介
1、什么是MVC
MVC是一种软件架构的思想,将软件按照模型、视图、控制器来划分
M: Model,模型层,指工程中的JavaBean,作用是处理数据
JavaBean分为两类:
- 一类称为实体类Bean:专门存储业务数据的,如Student 、user 等
- 一类称为业务处理Bean:指Service或Dao对象,专门用于处理业务逻辑和数据访问。
V: View,视图层,指工程中的html或jsp等页面,作用是与用户进行交互,展示数据。
C: Controller,控制层,指工程中的servlet,作用是接收请求和响应浏览器。
MVC的工作流程:
用户通过视图层发送请求到服务器,在服务器中请求被Controller接收,Controller调用相应的Model层处理请求,处理完毕将结果返回到Controller,Controller再根据请求处理的结果找到相应的View视图,渲染数据后最终响应给浏览器。
2、什么是SpringMVC
- SpringMVC是Spring的一个后续产品,是Spring的一个子项目。
- SpringMVC是Spring为表述层开发提供的一整套完备的解决方案。在表述层框架历经Strust、WebWork、Strust2等诸多产品的历代更迭之后,目前业界普遍选择了SpringMVC作为JavaE项目表述层开发的首选方案。
注:三层架构分为表述层(或表示层)、业务逻辑层、数据访问层,表述层表示前台页面和后台servlet
3、SpringMVC的特点
- Spring家族原生产品,与IOC容器等基础设施无缝对接
- 基于原生的Servlet,通过了功能强大的前端控制器DispatcherServlet,对请求和响应进行统一处理
- 表述层各细分领域需要解决的问题全方位覆盖,提供全面解决方案
- 代码清新简洁,大幅度提升开发效率
- 内部组件化程度高,可插拔式组件即插即用,想要什么功能配置相应组件即可
- 性能卓著,尤其适合现代大型、超大型互联网项目要求
二、Spring集成web环境
Spring提供获取应用上下文的工具
Spring提供了一个监听器
ContextLoaderListener
就是对上述功能的封装,该监听器内部加载Spring配置文件,创建应用上下文对象,并存储到
ServletContext
域中,提供了一个客户端工
具
WebApplicationContextUtils
供使用者获得应用上下文对象。
所以我们需要做的只有两件事:
① 在
web.xml
中配置
ContextLoaderListener
监听器(添加spring-web依赖)
< dependency >< groupId >org.springframework</ groupId >< artifactId >spring-web</ artifactId >< version >5.0.5.RELEASE</ version ></ dependency >
② 使用
WebApplicationContextUtils
获得应用上下文对象
ApplicationContext
配置ContextLoaderListener监听器
<!-- 全局参数 -->< context-param >< param-name >contextConfigLocation</ param-name >< param-value >classpath:applicationContext.xml</ param-value ></ context-param ><!--Spring 的监听器 -->< listener >< listener-class >org.springframework.web.context.ContextLoaderListener</ listener-class ></ listener >
通过工具获得应用上下文对象
ApplicationContext applicationContext =WebApplicationContextUtils. getWebApplicationContext (servletContext);Object obj = applicationContext.getBean( "id" );
三、MVC入门开发步骤
1、导入SpringMVC相关坐标
<!--Spring 坐标 -->< dependency >< groupId >org.springframework</ groupId >< artifactId >spring-context</ artifactId >< version >5.0.5.RELEASE</ version ></ dependency ><!--SpringMVC 坐标 -->< dependency >< groupId >org.springframework</ groupId >< artifactId >spring-webmvc</ artifactId >< version >5.0.5.RELEASE</ version ></ dependency >
2、配置SpringMVC核心控制器DispathcerServlet
<!-- 配置 SpringMVC的前端控制器--> <servlet> <servlet-name>DispatcherServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>DispatcherServlet</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping>
3、创建Controller类和视图页面(success.jsp)
package com.zd.controller;
public class UserController {
public String save(){
System.out.println("Cotroller save running....");
return "success.jsp";
}
}
4、使用注解配置Controller类中业务方法的映射地址
package com.zd.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class UserController {
@RequestMapping("/quick")//quick 映射名称
public String save(){
System.out.println("Cotroller save running....");
return "success.jsp";
}
}
5、配置SpringMVC核心文件 spring-mvc.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" 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/context http://www.springframework.org/schema/beans/spring-context.xsd"> <!-- Controller的组件扫描 --> <context:component-scan base-package="com.zd.controller"/> </beans>
修改web.xml的配置
<!-- 配置 SpringMVC的前端控制器--> <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:spring-mvc.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet>
6、客户端发起请求测试
SpringMVC流程
①从代码层面解析
②
四、SpringMVC的组件解析
SpringMVC的执行流程
① 用户发送请求至前端控制器DispatcherServlet。
② DispatcherServlet收到请求调用HandlerMapping处理器映射器。
③ 处理器映射器找到具体的处理器(可以根据xml配置、注解进行查找),生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet。
④ DispatcherServlet调用HandlerAdapter处理器适配器。
⑤ HandlerAdapter经过适配调用具体的处理器(Controller,也叫后端控制器)。
⑥ Controller执行完成返回ModelAndView。
⑦ HandlerAdapter将controller执行结果ModelAndView返回给DispatcherServlet。
⑧ DispatcherServlet将ModelAndView传给ViewReslover视图解析器。
⑨ ViewReslover解析后返回具体View。
⑩ DispatcherServlet根据View进行渲染视图(即将模型数据填充至视图中)。DispatcherServlet 响应用户
SpringMVC组件解析
1. 前端控制器:DispatcherServlet
用户请求到达前端控制器,它就相当于 MVC 模式中的 C,DispatcherServlet 是整个流程控制的中心,由
它调用其它组件处理用户的请求,DispatcherServlet 的存在降低了组件之间的耦合性。
2. 处理器映射器:HandlerMapping
HandlerMapping 负责根据用户请求找到 Handler 即处理器,SpringMVC 提供了不同的映射器实现不同的映射方式,例如:配置文件方式,实现接口方式,注解方式等。
3. 处理器适配器:HandlerAdapter
通过 HandlerAdapter 对处理器进行执行,这是适配器模式的应用,通过扩展适配器可以对更多类型的处理器进行执行
4. 处理器:Handler
它就是我们开发中要编写的具体业务控制器。由 DispatcherServlet 把用户请求转发到 Handler。由Handler 对具体的用户请求进行处理。
5. 视图解析器:View Resolver
View Resolver 负责将处理结果生成 View 视图,View Resolver 首先根据逻辑视图名解析成物理视图名,即 具体的页面地址,再生成 View 视图对象,最后对 View 进行渲染将处理结果通过页面展示给用户。
6. 视图:View
SpringMVC 框架提供了很多的 View 视图类型的支持,包括:jstlView、freemarkerView、pdfView等。最常用的视图就是 jsp。一般情况下需要通过页面标签或页面模版技术将模型数据通过页面展示给用户,需要由程序员根据业务需求开发具体的页面。
SpringMVC注解解析
@RequestMapping
作用:用于建立请求 URL 和处理请求方法之间的对应关系
位置:
- 类上,请求URL 的第一级访问目录。此处不写的话,就相当于应用的根目录
- 方法上,请求 URL 的第二级访问目录,与类上的使用@ReqquestMapping标注的一级目录一起组成访问虚拟路径
属性:
- value:用于指定请求的URL。它和path属性的作用是一样的
- method:用于指定请求的方式
- params:用于指定限制请求参数的条件。它支持简单的表达式。要求请求参数的key和value必须和配置的一模一样
例如:
- params = {"accountName"},表示请求参数必须有accountName
- params = {"moeny!100"},表示请求参数中money不能是100
1. mvc命名空间引入
命名空间:
xmlns: context ="http://www.springframework.org/schema/context"xmlns: mvc ="http://www.springframework.org/schema/mvc"
约束地址:
http://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/mvchttp://www.springframework.org/schema/mvc/spring-mvc.xsd
2. 组件扫描
SpringMVC
基于
Spring
容器,所以在进行
SpringMVC
操作时,需要将
Controller
存储到
Spring
容器中,如果使用@Controller注解标注的话,就需要使用以下代码进行组件扫描。
< context :component-scan base- package =“com.itheima.controller" />
SpringMVC的XML配置解析
视图解析器
SpringMVC
有默认组件配置,默认组件都是
DispatcherServlet.properties
配置文件中配置的,该配置文件地址
org/springframework/web/servlet/DispatcherServlet.properties
,该文件中配置了默认的视图解析器,如下:
org.springframework.web.servlet.ViewResolver = org.springframework.web.servlet.view.InternalResourceViewResolver
翻看该解析器源码,可以看到该解析器的默认设置,如下:
REDIRECT_URL_PREFIX = "redirect:" -- 重定向前缀FORWARD_URL_PREFIX = "forward:" -- 转发前缀(默认值)prefix = "" ; -- 视图名称前缀suffix = "" ; -- 视图名称后缀
我们可以通过属性注入的方式修改视图的的前后缀
<!-- 配置内部资源视图解析器 -->< bean class ="org.springframework.web.servlet.view.InternalResourceViewResolver" >< property name ="prefix" value ="/WEB-INF/views/" ></ property >< property name ="suffix" value =".jsp" ></ property ></ bean >
五、SpringMVC的请求和响应
1、SpringMVC的数据响应
1.1 SpringMVC的数据响应方式
1) 页面跳转
- 直接返回字符串
- 通过ModelAndView对象返回
2) 回写数据
- 直接返回字符串
- 返回对象或集合
1.2 页面跳转
2. 返回ModelAndView对象
package com.zd.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
@Controller
public class UserController {
@RequestMapping("/quick2")
public ModelAndView quickMethod2(){
//Model:模型 作用封装数据
//view:视图 作用展示数据
ModelAndView modelAndView = new ModelAndView();
//设置模型数据
modelAndView.addObject("username","itcast");//username=itcast
//设置视图名称
modelAndView.setViewName("redirect:index.jsp");
return modelAndView;
}
@RequestMapping("/quick3")
public ModelAndView quickMethod3(ModelAndView modelAndView){
//设置模型数据
modelAndView.addObject("username","zdzd");//username=zdzd
//设置视图名称
modelAndView.setViewName("redirect:index.jsp");
return modelAndView;
}
@RequestMapping("/quick4")
public String quickMethod4(Model model){
//设置模型数据
model.addAttribute("username","博学谷");
return "success.jsp";
}
/*
向request域存储数据
在进行转发时,往往要向request域中存储数据,在jsp页面中显示,那么Controller中怎样向request域中存储数据呢?
通过SpringMVC框架注入的request对象setAttribute()方法设置
*/
@RequestMapping("/quick5")
public String quickMethod5(HttpServletRequest request){
//设置模型数据
request.setAttribute("username","博学谷");
return "success.jsp";
}
@RequestMapping("/quick")
public String save(){
System.out.println("Cotroller save running....");
return "success.jsp";
}
}
1.3 回写数据
(1)直接返回字符串
Web基础阶段,客户端访问服务器端,如果想直接回写字符串作为响应体返回的话,只需要使用
response.getWriter().print(“hello world”) 即可,那么在Controller中想直接回写字符串该怎样呢?
① 通过SpringMVC框架注入的response对象,使用response.getWriter().print(“hello world”) 回写 数据,此时不需要视图跳转,业务方法返回值为void。
@RequestMapping("/quick6")
public void quickMethod6(HttpServletResponse response) throws IOException {
response.getWriter().print("hello itcast");
}
② 将需要回写的字符串直接返回,但此时需要通过
@ResponseBody
注解告知SpringMVC框架,方法返回的字符串不是跳转是直接在http响应体中返回。
@RequestMapping("/quick7")
@ResponseBody //告知SpringMVC框架不进行试图跳转 直接进行数据响应
public String quickMethod7(){
return "hello zdzd";
}
在异步项目中,客户端与服务器端往往要进行json格式字符串交互,此时我们可以手动拼接json字符串返回。
添加依赖
<!--jackson--> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>2.9.0</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.9.0</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-annotations</artifactId> <version>2.9.0</version> </dependency>
@RequestMapping("/quick6")
@ResponseBody
public String quickMethod6() throws IOException {
return "{\"name\":\"zhangsan\",\"age\":18}";//直接返回
}
使用json的转换工具将对象转换成json格式字符串再返回
@RequestMapping("/quick9")
@ResponseBody
public String quickMethod9() throws JsonProcessingException {
User user = new User();
user.setUsername("zhangsan");
user.setPassword("2346");
//使用json的转换工具将对象转换成json格式字符串再返回
ObjectMapper objectMapper = new ObjectMapper();
String json = objectMapper.writeValueAsString(user);
return json;
}
(2)返回对象集合
spring-mvc.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:mvc="http://www.springframework.org/schema/mvc" 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/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"> <!--Controller的组件扫描--> <context:component-scan base-package="com.zd"> <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/> </context:component-scan> <!--配置内部资源视图解析器--> <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <!-- /jsp/success.jsp --> <property name="prefix" value="/jsp/"></property> <property name="suffix" value=".jsp"></property> </bean> <!--配置处理器映射器--> <!--写了 mvc的注解驱动 可以注释掉了--> <!-- <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"> <property name="messageConverters"> <list> <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"/> </list> </property> </bean> --> <!--mvc的注解驱动--> <mvc:annotation-driven /> </beans>
@RequestMapping(value="/quick10")
@ResponseBody
//期望SpringMVC自动将User转换成json格式的字符串
public User save10() throws IOException {
User user = new User();
user.setUsername("zhangsan");
user.setPassword("2346");
return user;
}
2、SpringMVC获得请求数据
2.1 获得请求参数
客户端请求参数的格式是:
name=value&name=value… …
服务器端要获得请求的参数,有时还需要进行数据的封装,SpringMVC可以接收如下类型的参数:
- 基本类型参数
- POJO类型参数(简单javaBean)
- 数组类型参数
- 集合类型参数
2.2 获得基本类型参数
Controller中的业务方法的参数名称要与请求参数的name一致,参数值会自动映射匹配。
@RequestMapping(value="/quick11")
@ResponseBody //不进行页面跳转
//返回void代表不进行数据回写
/*
手动输入 quick11?username=zhangsan&password=9876
控制台得到:zhangsan 9876
*/
public void save11(String username,String password) throws IOException {
System.out.println(username);
System.out.println(password);
}
2.3 获得POJO类型参数
Controller中的业务方法的POJO参数的属性名与请求参数的name一致,参数值会自动映射匹配。
@RequestMapping(value="/quick12")
@ResponseBody
/*
输入 quick12?id=11&username=zhangsan&password=9876
控制台输出 User{id=11, username='zhangsan', password='9876'}
*/
public void save12(User user) throws IOException {
System.out.println(user);
}
2.4 获得数组类型参数
Controller中的业务方法数组名称与请求参数的name一致,参数值会自动映射匹配。
@RequestMapping(value="/quick13")
@ResponseBody
/*
输入 quick13?str=111&str=222&str=333
控制台输出 [111, 222, 333]
*/
public void save13(String[] str) throws IOException {
System.out.println(Arrays.asList(str));//数组直接打印地址,将数组转为集合就可以得到数组中的数据
}
2.5 获得集合类型参数
获得集合参数时,要将集合参数包装到一个POJO中才可以。
实体类
package com.zd.domian;
import java.util.List;
public class VO {
private List<User> userList;
public List<User> getUserList() {
return userList;
}
public void setUserList(List<User> userList) {
this.userList = userList;
}
@Override
public String toString() {
return "VO{" +
"userList=" + userList +
'}';
}
}
创建一个表单
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <form action="${pageContext.request.contextPath}/quick14" method="post"> <%--表明是第几个User对象的username password--%> <input type="text" name="userList[0].id"><br/> <input type="text" name="userList[0].username"><br/> <input type="text" name="userList[0].password"><br/> <input type="text" name="userList[1].id"><br/> <input type="text" name="userList[1].username"><br/> <input type="text" name="userList[1].password"><br/> <input type="submit" value="提交"> </form> </body> </html>
@RequestMapping(value="/quick14")
@ResponseBody
/*
首先打开 form.jsp进行数据填写提交后
控制台输出VO{userList=[User{id=1, username='zhangsan', password='123'}, User{id=2, username='wuzong', password='3435'}]}
*/
public void save14(VO vo) throws IOException {
System.out.println(vo);//数组直接打印地址,将数组转为集合就可以得到数组中的数据
}
当使用ajax提交时,可以指定contentType为json形式,那么在方法参数位置使用@RequestBody可以直接接收集合数据而无需使用POJO进行包装。
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.js"></script> <script> var userList = new Array(); userList.push({id:"01",username:"zhangsan",password:"1234"}); userList.push({id:"02",username:"lisi",password:"2345"}); <!-- 发送数据 --> $.ajax({ type:"POST", url:"${pageContext.request.contextPath}/quick15", data:JSON.stringify(userList), <!-- 提交参数 --> contentType:"application/json;charset=utf-8" }); </script> </head> <body> </body> </html>
@RequestMapping(value="/quick15")
@ResponseBody
/*
输入ajax.jsp
控制台输出 [User{id=1, username='zhangsan', password='1234'}, User{id=2, username='lisi', password='2345'}]
*/
public void save15(@RequestBody List<User> userList) throws IOException {
System.out.println(userList);
}
2.6 请求数据乱码问题
当post请求时,数据会出现乱码,我们可以设置一个过滤器来进行编码的过滤。
<!--配置全局过滤的filter--> <filter> <filter-name>CharacterEncodingFilter</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> </filter> <filter-mapping> <filter-name>CharacterEncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
2.7 参数绑定注解@requestParam
当请求的参数名称与Controller的业务方法参数名称不一致时,就需要通过@RequestParam注解显示的绑定。
注解@RequestParam还有如下参数可以使用:
- value:与请求参数名称
- required:此在指定的请求参数是否必须包括,默认是true,提交时如果没有此参数则报错
- defaultValue:当没有指定请求参数时,则使用指定的默认值赋值
@RequestMapping(value="/quick16")
@ResponseBody
/*
输入 quick16?name="zhangsan"
控制台得到 zhangsan
如果不使用@RequestParam注解 输入name=...控制台输出null
*/
public void save16(@RequestParam(value="name",required = false,defaultValue = "itcast") String username) throws IOException {
System.out.println(username);
}
2.8 获得Restful风格的参数
Restful
是一种软件
架构风格
、
设计风格
,而不是标准,只是提供了一组设计原则和约束条件。主要用于客户端和服务
器交互类的软件,基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存机制等。
Restful
风格的请求是使用
“url+请求方式”
表示一次请求目的的,HTTP 协议里面四个表示操作方式的动词如下:
- GET:用于获取资源
- POST:用于新建资源
- PUT:用于更新资源
- DELETE:用于删除资源
例如:
- /user/1 GET : 得到 id = 1 的 user
- /user/1 DELETE: 删除 id = 1 的 user
- /user/1 PUT: 更新 id = 1 的 user
- /user POST: 新增 user
// localhost:8080/quick17/zhangsan
//控制台输出 zhangsan
@RequestMapping(value="/quick17/{name}")
@ResponseBody
public void save17(@PathVariable(value="name") String username) throws IOException {
System.out.println(username);
}
2.9 自定义类型转换器
•
SpringMVC 默认已经提供了一些常用的类型转换器,例如客户端提交的字符串转换成int型进行参数设置。
•
但是不是所有的数据类型都提供了转换器,没有提供的就需要自定义转换器,例如:日期类型的数据就需要自 定义转换器。
自定义类型转换器的开发步骤:
① 定义转换器类实现Converter接口
package com.zd.converter;
import org.springframework.core.convert.converter.Converter;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class DateConverter implements Converter<String, Date> {
public Date convert(String dateStr) {
//将日期字符串转换成日期对象 返回
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
Date date = null;
try {
date = format.parse(dateStr);
} catch (ParseException e) {
e.printStackTrace();
}
return date;
}
}
② 在配置文件声明转换器
<!--声明转换器--> <bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean"> <property name="converters"> <list> <bean class="com.zd.converter.DateConverter"></bean> </list> </property> </bean>
③ 在<annotation-driven>中引用转换器
@RequestMapping(value="/quick18")
@ResponseBody
public void save18(Date date) throws IOException {
System.out.println(date);
}
2.10 获得Servlet相关API
SpringMVC支持使用原始ServletAPI对象作为控制器方法的参数进行注入,常用的对象如下:
- HttpServletRequest
- HttpServletResponse
- HttpSession
@RequestMapping(value="/quick19")
@ResponseBody
public void save19(HttpServletRequest request, HttpServletResponse response, HttpSession session) throws IOException {
//打印对象地址
System.out.println(request);//org.apache.catalina.connector.RequestFacade@791e4013
System.out.println(response);//org.apache.catalina.connector.ResponseFacade@181ed328
System.out.println(session);//org.apache.catalina.session.StandardSessionFacade@72c1409e
}
2.11 获得请求头
1. @RequestHeader
使用@RequestHeader可以获得请求头信息,相当于web阶段学习的request.getHeader(name)
@RequestHeader注解的属性如下:
- value:请求头的名称
- required:是否必须携带此请求头
@RequestMapping(value="/quick20")
@ResponseBody
public void save20(@RequestHeader(value = "User-Agent",required = false) String user_agent) throws IOException {
System.out.println(user_agent);
//Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36 Edg/100.0.1185.50
}
2. @CookieValue
使用@CookieValue可以获得指定Cookie的值
@CookieValue注解的属性如下:
- value:指定cookie的名称
- required:是否必须携带此cookie
@RequestMapping(value="/quick21")
@ResponseBody
public void save21(@CookieValue(value = "JSESSIONID") String jsessionId) throws IOException {
System.out.println(jsessionId);//7C95C7D9C01BA28DA898959BBAEE231D
}
2.12 文件上传
1. 文件上传客户端三要素
- 表单项type=“file” (input type="file")
- 表单的提交方式是post
- 表单的enctype属性是多部分表单形式,及enctype=“multipart/form-data”
upload.jsp 创建一个表单
<form action="${pageContext.request.contextPath}/quick22" method="post" enctype="multipart/form-data"> 名称:<input type="text" name="username"><br> 文件:<input type="file" name="uploadFile"><br> <input type="submit" value="提交"><br> </form>
2. 文件上传原理
- 当form表单修改为多部分表单时,request.getParameter()将失效。
- enctype=“application/x-www-form-urlencoded”时,form表单的正文内容格式是: key=value&key=value&key=value
- 当form表单的enctype取值为Mutilpart/form-data时,请求正文内容就变成多部分形式:
2.13 单文件上传步骤
① 添加 fileupload 和 io 依赖
<!-- fileupload 和 io --> <dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.2.2</version> </dependency> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.4</version> </dependency>
② 配置文件上传解析器
<!--配置文件上传解析器--> <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <!--上传文件总大小--> <property name="maxUploadSize" value="5242800"/> <!--上传单个文件的大小--> <property name="maxUploadSizePerFile" value="5242800"/> <!--上传文件的编码类型--> <property name="defaultEncoding" value="UTF-8"/> </bean>
③ 编写文件上传代码
@RequestMapping(value="/quick22")
@ResponseBody
public void save22(String username, MultipartFile uploadFile) throws IOException {
System.out.println(username);//zhangsan
System.out.println(uploadFile);//org.springframework.web.multipart.commons.CommonsMultipartFile@486df907
}
@RequestMapping(value="/quick22")
@ResponseBody
public void save22(String username, MultipartFile uploadFile) throws IOException {
System.out.println(username);//zhangsan
//获得上传文件的名称,进行保存
String originalFilename = uploadFile.getOriginalFilename();
uploadFile.transferTo(new File("D:\\A\\upload\\"+originalFilename));
}
2.15 多文件上传实现
多文件上传,只需要将页面修改为多个文件上传项,将方法参数MultipartFile类型修改为MultipartFile[]即可
@RequestMapping(value="/quick22")
@ResponseBody
public void save22(String username, MultipartFile uploadFile1,MultipartFile uploadFile2) throws IOException {
System.out.println(username);//zhangsan
//获得上传文件的名称,进行保存
String originalFilename1 = uploadFile1.getOriginalFilename();
uploadFile1.transferTo(new File("D:\\A\\upload\\"+originalFilename1));
String originalFilename2 = uploadFile2.getOriginalFilename();
uploadFile2.transferTo(new File("D:\\A\\upload\\"+originalFilename2));
}
@RequestMapping(value="/quick23")
@ResponseBody
public void save23(String username, MultipartFile[] uploadFile) throws IOException {
System.out.println(username);
for (MultipartFile multipartFile : uploadFile) {
String originalFilename = multipartFile.getOriginalFilename();
multipartFile.transferTo(new File("D:\\A\\upload\\"+originalFilename));
}
}