文章目录
1 SpringMVC获得请求数据
1.1 请求参数类型
来自浏览器的请求参数的格式是name=value1&age=value2&hobby=value3&hobby=value4...
服务器想要获取请求的参数,有时还需要进行数据的封装
SpringMVC可以接收如下类型的数据:
1,基本类型参数
2,POJO(简单Bean)类型参数
3,数组类型参数
4,集合类型参数
1.2 获得基本类型参数
对于基本参数类型,Controller中的业务方法的参数与请求的参数名一致时,SpringMVC会自动映射匹配参数且进行类型转换
来自浏览器的请求,传来的是两个基本类型数据:
http://localhost:8080/req1?username=coisini&age=21
Controller层中对应的方法:
// 获取请求中的基本类型参数
@RequestMapping("/req1")
// @ResponseBody代表不进行页面跳转
@ResponseBody
public void method1(String username, int age) {
System.out.println("userName = " + username);
System.out.println("age = " + age);
}
在浏览器地址栏输入请求后,该请求被交给method1,SpringMVC会自动根据参数名匹配参数,且进行类型转换:
1.3 获得POJO类型参数
Controller中业务方法的POJO中的参数与请求参数一致,参数值会自动映射匹配且进行类型转换
来自浏览器的请求,传来的是一个POJO:
http://localhost:8080/req2?username=coisini&age=21
Controller层中对应的方法:
// 获取请求中的POJO参数
@RequestMapping("/req2")
@ResponseBody
public void method2(User user) {
System.out.println(user);
}
在浏览器地址栏输入请求后,该请求被交给method2,SpringMVC会将这些参数封装到POJO中:
1.4 获得数组类型参数
Controller中的业务方法数组名称与请求参数的name一致,参数值会自动匹配映射
来自浏览器的请求,传来的是一个数组类型参数:
http://localhost:8080/req3?hobby=swim&hobby=read&hobby=game
Controller层中对应的方法:
// 获取请求中的数组类型参数
@RequestMapping("/req3")
@ResponseBody
public void method3(String[] hobby) {
System.out.println(Arrays.asList(hobby));
}
在浏览器地址栏输入请求后,该请求被交给method3,SpringMVC会将这些参数封装到数组中:
1.5 获得集合类型参数
1.5.1 将集合封装到VO对象的成员中
获得集合参数时,需要将集合参数包装到一个POJO中才可以,即需要把集合先包装到一个VO对象中
编写一个jsp页面用于提交数据且以POST的方式提交到method4:
Controler层中对应的方法:
// 获取请求中的集合类型参数 将集合封装到VO对象的成员中
@RequestMapping(value = "/req4", method = RequestMethod.POST)
@ResponseBody
public void method4(UserVO userVO) {
List<User> userList = userVO.getUserList();
System.out.println(userList);
}
在表单中填入数据提交后,该请求被交给了method4,SpringMVC会将提交的集合封装到UserVO的成员userList中:
1.5.2 特殊情况将集合直接封装
当使用ajax提交时,可以指定contentType为json形式,那么在方法参数位置使用@RequestBody可以直接接收集合数据,而无需封装到VO对象的成员中
首先导入jQuery,并在spring-mvc.xml文件中导入:
<!-- 开放js目录下的所有资源 -->
<mvc:resources mapping="/js/**" location="/js/"></mvc:resources>
编写一个jsp页面,该页面刚被打开就将一个ajax请求以POST提交到@RequestMapping注解的值为req5的方法:
Controler层中对应的方法:
// 获取ajax请求中的集合类型参数 将集合直接封装到方法参数中
@RequestMapping(value = "/req5", method = RequestMethod.POST)
@ResponseBody
public void method5(@RequestBody List<User> userList) {
System.out.println(userList);
}
在浏览器地址栏访问ajax.jsp页面后,ajax请求将集合发给了method5,method5直接将集合封装到了参数中
2 关于请求的补充
2.1 静态资源访问的开启
在1.5.2中如果没有在spring-mvc.xml中增加:
<mvc:resources mapping="/js/**" location="/js/"></mvc:resources>
就会导致ajax请求发送失败,原因是找不到jQuery.js文件,其原因是SpringMVC框架中所有请求都会先到前端控制器,当在浏览器地址栏输入ajax.jsp时:
前端控制器也会将请求jQuery.js当作一个RequestMapping进行匹配,然而并不存在这个RequestMapping,就会忽略这个请求,导致找不到jQuery.js文件,为此需要先在spring-mvc.xml中预先进行配置,开放对某些静态资源的访问权限
或者在spring-mvc.xml文件中使用如下的配置:
<!-- 交给Tomcat寻找所需的静态资源 -->
<mvc:default-servlet-handler></mvc:default-servlet-handler>
这个配置代表当需要访问静态资源时,交给原始容器(Tomcat)来寻找
2.2 请求数据的中文乱码问题
GET请求一般不会出现请求乱码的问题,而POST请求经常会中文乱码,如:
为此可以在web.xml中配置一个过滤器来进行编码的过滤:
<!-- 配置全局编码过滤器 所有资源都采用UTF-8编码 -->
<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.3 参数绑定注解@RequestParam
当请求的参数名称与Controller的业务方法参数不一致时,就需要通过@RequestParam注解显示地绑定
来自浏览器的请求,传来的是一个基本数据类型:
http://localhost:8080/req6?name=coisini
而Controller层方法的参数是userName,此时参数名称不匹配,无法接收到来自浏览器的参数,为此可以使用@RequestParam进行显示地绑定,将浏览器输入的参数name映射到程序中的参数userName
// @RequestParam注解用于绑定参数
@RequestMapping("/req6")
@ResponseBody
public void method6(@RequestParam(value = "name") String userName) {
System.out.println("userName = " + userName);
}
经过显示的绑定后,就可以完成映射使得Controller层的方法获取到请求参数:
@RequestParam不仅可以用value属性来绑定参数,还有required属性和defaultValue属性
required: 绑定的参数是否必须包括,默认为true,提交时若没有该参数则报错
defaultValue: 当没有指定请求参数时,使用指定的默认值赋值
2.4 解析Restful风格的参数
Restful是一种架构风格,设计风格,而不是标准,只是提供了一组设计原则和约束条件,主要用于客户端和服务器交互类的软件,基于Restful风格设计的软件可以更简洁,更有层次,更易实现缓存机制等
Restful风格的请求是使用url+请求方式表示一次请求,HTTP协议里四个操作方式有:
GET: 获取资源
/user/1 GET: 得到id=1的user
POST: 新建资源(添加数据...)
/user POST: 新增user
PUT: 更新资源
/user/1 PUT: 更新id=1的user
DELETE: 删除资源
/user/1 DELETE: 删除id=1的user
上述url地址/user/1中的1就是要获得的请求参数,在SpringMVC中可以使用占位符进行参数绑定,地址/user/1可以写成/user/{id},占位符{id}对应的就是1的值,在业务方法中可以使用@PathVariable注解进行占位符匹配获取工作
来自浏览器的请求:
http://localhost:8080/req7/coisini
Controller层对应的方法:
// 处理Restful风格的请求 使用/req7/{name}来定位到method7 {name}中name就是url最后的值
// 使用@PathVariable获取url中的name
@RequestMapping("/req7/{name}")
@ResponseBody
public void method7(@PathVariable(value = "name", required = true) String userName) {
System.out.println("userName = " + userName);
}
在浏览器中输入Restful风格的请求,交给method7处理:
2.5 自定义类型转换器
SpringMVC默认提供了一些常用的类型转换器,如请求中的字符串参数转换成int类型,但不是所有数据类型都提供了转换器,没有提供的就需要自定义转换器,如日期类型就需要自定义转换器
Date类型请求的欧美写法以/分隔:
Date类型请求的中国写法以-分隔:
为此需要自定义一个日期类型转换器,使得能够处理以-分隔日期的参数请求
自定义类型转换器开发步骤:
1,自定义类型转换器类实现Converter接口
2,在spring-mvc.xml中声明转换器
3,在<annotation-driven>中引用转换器
1,自定义类型转换器类实现Converter接口
/**
* @author 雫
* @date 2021/7/11 - 4:18
* @function 自定义日期转换器
*/
public class DataConverter implements Converter<String, Date> {
// 将以-分隔的日期字符串转换成真正的日期对象并返回
@Override
public Date convert(String dateStr) {
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
try {
Date date = format.parse(dateStr);
return date;
} catch (ParseException e) {
e.printStackTrace();
}
return null;
}
}
2,在spring-mvc.xml中声明转换器
<!-- 声明日期转换器 -->
<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<list>
<bean class="com.coisini.converter.DataConverter"></bean>
</list>
</property>
</bean>
3,在spring-mvc.xml的注解驱动配置中引用该转换器
<mvc:annotation-driven conversion-service="conversionService"></mvc:annotation-driven>
2.6 获得Servlet相关API
SpringMVC支持使用原始ServletAPI对象作为Controller层方法的参数进行注入,常用的对象有:
HttpServeltRequest,HttpServletResponse,HttpSession
在Controller层方法的参数中注入ServletAPI对象,就可以在方法内使用,这些对象会由SpringMVC来自动注入:
// 在参数中注入ServletAPI相关对象 直接使用
@RequestMapping("/req9")
@ResponseBody
public void method9(HttpServletRequest request, HttpServletResponse response, HttpSession session) {
System.out.println(request);
System.out.println(response);
System.out.println(session);
}
2.7 获得请求头信息&Cookie信息
使用@RequestHeader注解可以获取请求头信息,相当于request.getHeader(name)
@RequestHeader注解的属性如下:
value: 请求头的名称
required: 是否必须携带此请求头
@RequestHeader参数的使用:
// 通过@RequestHeader获取请求头的信息
@RequestMapping("/req10")
@ResponseBody
public void method10(@RequestHeader(value = "User-Agent", required = false) String userAgent) {
System.out.println(userAgent);
}
还可以通过@CookieValue获取指定Cookie值
@CookieValue注解的属性如下:
value: 请求头的名称
required: 是否必须携带此请求头
@CookieValue的使用:
// 通过@CookieValue获取Cookie的值
@RequestMapping("/req11")
@ResponseBody
public void method11(@CookieValue(value = "JSESSIONID", required = false) String jsessionid) {
System.out.println(jsessionid);
}
3 文件上传
3.1 上传文件的表单
1,表单项type="file"
2,表单的提交方式是POST
3,表单的enctype属性是多部分表单形式,即enctype="multipart/form-data"
文件上传的原理:
当form表单的enctype属性默认为"application/x-www-form-urlencoded"
此时form表单的正文内容格式是key=value&key=value...
但当enctype属性修改为"multipart/form-data"时,请求的正文内容就变成多部分内容
request.getParameter()将失效
3.2 单文件上传步骤
1,导入fileupload和io相关jar包
2,在spring-mvc.xml中配置文件上传解析器
3,编写文件上传代码
1,导入fileupload和io相关jar包
<!-- 文件上传相关工具 -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
<!-- 文件上传io工具 -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
2,在spring-mvc.xml中配置文件上传解析器
<!-- 配置文件上传解析器 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 上传文件的编码类型 -->
<property name="defaultEncoding" value="UTF-8"></property>
<!-- 上传文件总大小 -->
<property name="maxUploadSize" value="500000"></property>
</bean>
3,编写文件上传代码
// 处理客户端上传的单个文件 表单name必须与参数名称匹配
@RequestMapping("/req12")
@ResponseBody
public void method12(String name, MultipartFile uploadFile) throws IOException {
// 1,获得上传文件的名称
String fileName = uploadFile.getOriginalFilename();
// 2,将文件转存到指定路径下
uploadFile.transferTo(new File("D:\\tmp\\" + fileName));
}
多文件上传与单文件类似,只需在表单中增加更多的input标签,在对应的方法中增加对应的参数即可