SpringMVC 应用开发
1 基础概念介绍
2 返回值处理
3 参数绑定处理
4 RequestMapping注解
5 RESTful支持
6 拦截器应用
7 CORS跨域解决方案
8 Mock测试(模拟测试)
9 ControllerAdvice
10 乱码解决
11 非注解开发方式
参数绑定处理
参数绑定内容介绍了,将请求参数串中的value值,赋值给Controller 类中方法的形参。
示例中给出了JSP页面到 Controller类方法形参的代码。
一、参数绑定介绍
1.1 什么是参数绑定
就是将请求参数串中的value值获取到之后,再进行类型转换,然后将转换后的值赋值给Controller 类中方法的形参,这个过程就是参数绑定。
总结参数绑定需要两步:
- 类型转换(请求中的String类型值—>Controller各种数据类型的方法形参)
- 赋值操作,将转换之后的值赋值给Controller方法形参
1、 请求参数格式
默认是key/value格式,比如: http://XXXXX?id=1&type=301
2、请求参数值的数据类型; 是String类型的各种值
3、 请求参数值要绑定的目标类型: Controller类中的方法参数,比如简单类型、POJO类型、集合类型等
SpringMVC内置的参数解析组件,内置了24种参数解析组件(ArgumentResolver),一般不需要我们自己来处理。
1.2 默认支持的参数类型
Controller方法形参中可以随时添加如下类型的参数(Servlet API支持),处理适配器会自动识别并
进行赋值
1、HttpServletRequest
通过 request 对象获取请求信息
2、HttpServletResponse
通过 response 处理响应信息
3、HttpSession
通过 session 对象得到 session 中存放的对象
4、InputStream、OutputStream
5、Reader、Writer
6、Model/ModelMap
ModelMap 继承自 LinkedHashMap ,Model是一个接口,它们的底层实现都是同一个类
( BindingAwareModelMap ),作用就是向页面传递数据,相当于 Request 的作用,如下:
model.addAttribute("msg", “测试springmvc”);
二、参数绑定使用要求
2.1 简单类型
1、 直接绑定 http请求参数的【key】和controller方法的【形参名称】一致
2、注解绑定 请求参数的【key】和controller方法的【形参名称】不一致时,需要使用【@RequestParam】注解才能 将请求参数绑定成功。
2.1 RequestParam注解
- value: 参数名字,即入参的请求参数名字,如value=“itemid”表示请求的参数中的名字为itemid的参数的值将传 入
- required: 是否必须,默认是true,表示请求中一定要有相应的参数,否则将报; TTP Status 400 - Required Integer parameter ‘XXXX’ is not present
- defaultValue: 默认值,表示如果请求中没有同名参数时的默认值
2.2 绑定POJO类型
“Plain Ordinary Java Object”,简单普通的java对象。
有一些private的参数作为对象的属性,然后针对每一个参数定义get和set方法访问的接口。
没有从任何类继承、也没有实现任何接口,更没有被其它框架侵入的java对象。
要求表单中【参数名称】和Controller方法中的【POJO形参的属性名称】保持一致。
2.3 绑定集合或者数组类型
-
简单类型数组
通过HTTP请求批量传递简单类型数据的情况,Controller方法中可以用String[]或者pojo的String[] 属性接收(两种方式任选其一),但是不能使用List集合接收。 -
POJO类型集合或者数组
批量传递的请求参数,最终要使用List来接收,那么这个List必须放在另一个POJO类中。
三、 参数绑定示例
3.1 自定义日期参数绑定
对于springmvc无法解析的参数绑定类型,比如[年月日时分秒格式的日期]绑定到Date类型会报错,此时需要自定义[参数转换器]进行参数绑定。实现 convert 接口。
Converter代码
public class DateConverter implements Converter<String, Date> {
@Override
public Date convert(String source) {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
try {
return simpleDateFormat.parse(source);
} catch (ParseException e) {
e.printStackTrace();
}
return null;
}
}
Converter配置
在springMVC 中配置
<!--自定义日期参数绑定-->
<!-- 加载注解驱动 -->
<mvc:annotation-driven conversion-service="conversionService"/>
<!-- 转换器配置 -->
<bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean ">
<property name="converters">
<set>
<bean class="com.kkb.springmvc.service.DateConverter"/>
</set>
</property>
</bean>
3.2 JSP 代码
整体示例:JSP 与 Controller 直接的参数绑定用法。
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>参数绑定演示demo</title></head>
<body>
<!-- request请求的内容类型主要分为:K/V类型、Multipart类型、JSON类型 -->
<!-- 将request请求参数,绑定到简单类型(基本类型和String类型)方法参数 -->
<!-- 直接绑定 -->
<a href="${pageContext.request.contextPath}/user/findUserById? id=1&name=bingbing">查询用户1</a>
<!-- @RequestParam注解绑定,对应查看Control 代码 -->
<a href="${pageContext.request.contextPath}/user/findUserById2?uid=1">查询用 户2</a>
<!-- 将request请求参数,绑定到POJO类型(简单POJO和包装POJO的)方法参数 -->
<form action="${pageContext.request.contextPath}/user/saveUser" method="post">
用户名称:<input type="text" name="username"><br/>
用户性别:<input type="text" name="sex"><br/>
所属省份:<input type="text" name="address.provinceName"><br/>
所属城市:<input type="text" name="address.cityName"><br/>
<input type="submit" value="保存">
</form>
<!-- 将request请求参数,绑定到[元素是简单类型的集合或数组]参数 -->
<!-- 使用数组接收 -->
<a href="${pageContext.request.contextPath}/user/findUserByIds? id=1&id=2&id=3">根据ID批量删除用户</a>
<!-- 使用List接收(错误示例) -->
<a href="${pageContext.request.contextPath}/user/findUserByIds2? id=1&id=2&id=3">根据ID批量删除用户</a>
<!-- 使用Bean的List属性接收 -->
<a href="${pageContext.request.contextPath}/user/findUserByIds3? uid=1&uid=2&uid=3">根据ID批量删除用户</a>
<!-- 将request请求参数,绑定到[元素是POJO类型的List集合或Map集合]参数 -->
<form action="${pageContext.request.contextPath}/user/updateUser" method="post">
用户名称:<input type="text" name="username"><br/>
用户性别:<input type="text" name="sex"><br/>
<!-- itemList[集合下标]:集合下标必须从0开始 -->
<!-- 辅助理解:先将name属性封装到一个Item对象中,再将该Item对象放入itemList集合的 指定下标处 -->
购买商品1名称:<input type="text" name="itemList[0].name"><br/>
购买商品1价格:<input type="text" name="itemList[0].price"><br/>
购买商品2名称:<input type="text" name="itemList[1].name"><br/>
购买商品2价格:<input type="text" name="itemList[1].price"><br/>
<!-- itemMap['item3']:其中的item3、item4就是Map集合的key -->
<!-- 辅助理解:先将name属性封装到一个Item对象中,再将该Item对象作为value放入 itemMap集合的指定key处 -->
购买商品3名称:<input type="text" name="itemMap['item3'].name"><br/>
购买商品3价格:<input type="text" name="itemMap['item3'].price"><br/>
购买商品4名称:<input type="text" name="itemMap['item4'].name"><br/>
购买商品4价格:<input type="text" name="itemMap['item4'].price"><br/>
<input type="submit" value="保存">
</form>
<!-- 将request请求参数,绑定到Date类型方法参数 -->
<!-- 请求参数是:【年月日】 格式 -->
<a href="${pageContext.request.contextPath}/user/deleteUser?birthday=2018- 01-01">根据日期删除用户(String)</a>
<!-- 请求参数是:【年月日 时分秒】 格式 -->
<a href="${pageContext.request.contextPath}/user/deleteUser2?birthday=2018- 01-01 12:10:33">根据日期删除用户(Date)</a>
<!-- 文件类型参数绑定 -->
<form action="${pageContext.request.contextPath}/fileupload" method="post" enctype="multipart/form-data">
图片:<input type="file" name="uploadFile"/><br/>
<input type="submit" value="上传"/>
</form>
</body>
</html>
3.3 Controller代码
import java.util.*;
public class User {
private int id;
private String username;
private Date birthday;
private String sex;
// 演示包装POJO参数绑定
private Address address;
// 演示批量简单类型参数接收
private List<Integer> uid = new ArrayList<>();
// 将request请求参数,绑定到[元素是POJO类型的List集合]参数
private List<Item> itemList = new ArrayList<>();
// 将request请求参数,绑定到[元素是POJO类型的Map集合]参数
private Map<String, Item> itemMap = new HashMap<>();
// setter/getter方法
}