文章目录
1 参数绑定
- 默认支持的参数绑定
例如,编辑部门,需要传递一个部门 id 到controller,然后在控制器中获取 id,根据这个 id 将数据查询出来并展示到页面。
- 请求url:/dept/edit.action
- 参数:id(部门id)
- 响应结果:部门编辑页面,展示部门详情
代码可参考SSM整合的案例:
https://blog.csdn.net/weixin_45044097/article/details/103081723
-
绑定简单类型
当请求的参数名称和处理器(Controller)形参名称一致时会将请求参数与形参进行绑定。
这样,从 Request 取参数的方法就可以进一步简化。
参数类型推荐使用包装数据类型,因为基础数据类型不可以为 null。
使用@RequestParam 常用于处理简单类型的绑定。
⚫ value:参数名字,即入参的请求参数名字,如 value=“id”表示请求的参数中的名
字为 id 的参数的值将传入
⚫ required:是否必须,默认是 true,表示请求中一定要有相应的参数,否则将报
错:HTTP Status 400 - Required Integer parameter ‘XXXX’ is not present
⚫ defaultValue:默认值,表示如果请求中没有同名参数时的默认值 -
绑定pojo类型
当我们修改部门的时候就需要将部门信息全部提交到 controller。
如果提交的参数很多,或者提交的表单中的内容很多的时候,可以使用简单类型接收数据,也可以使用 pojo 接收数据。 如果使用 pojo 接收,要求 pojo 对象中的属性名和表单中 input 的 name 属性一致。当请求的参数名称和 pojo 的属性名称一致,会自动将请求参数赋值给 pojo 的属性。
例如:SSM整合案例中部门的编辑修改。 -
绑定包装pojo
DeptVo:
private Dept dept;
private Integer[] ids; -
绑定数组
删除多个部门,需要在表格中每一行前面加上复选框,需要传入一个 id 的数组:
-
绑定 list
批量操作添加,更新
2 分页
- 下载依赖
<!-- 使用分页插件-->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.1.2</version>
</dependency>
- 配置:spring-dao.xml
// 在sqlSesionFactory中配置
<!-- 分页插件 -->
<property name="plugins">
<array>
<bean class="com.github.pagehelper.PageInterceptor">
<property name="properties">
<!--使用下面的方式配置参数,一行配置一个 -->
<value>
helperDialect=mysql
</value>
</property>
</bean>
</array>
</property>
- service层
新增方法:
@Override
public PageInfo<Dept> list(Integer page, Integer pageSize) {
// 对数据进行验证
PageHelper.startPage(page,pageSize);
List<Dept> depts = mapper.findAll();
// 把结果包装成pageinfo类
PageInfo<Dept> pageInfo = new PageInfo<>(depts);
return pageInfo;
}
- controller层
Spring4.3中引进了{@GetMapping、@PostMapping、@PutMapping、@DeleteMapping、@PatchMapping},来帮助简化常用的HTTP方法的映射,并更好地表达被注解方法的语义。
@GetMapping是一个组合注解,是@RequestMapping(method = RequestMethod.GET)的缩写。该注解将HTTP Get 映射到 特定的处理方法上。
@PostMapping是一个组合注解,是@RequestMapping(method = RequestMethod.POST)的缩写。
ps : RequestMapping是一个用来处理请求地址映射的注解,可用于类或方法上。用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径。(详情见 第三点)
- json处理数据进行页面的点击显示表格数据,而不是刷新页面,效率低:
https://blog.csdn.net/weixin_45044097/article/details/103143650
官方文档:
https://pagehelper.github.io/docs/howtouse/
3 @RequestMapping
3.1 value的使用
使用在方法上:通过 value 属性来指定,其值是一个数组,可以将多个 url 映射到同一个方法
使用在类上:如果该 controller 的映射路径都有固定的前缀,就写在类的上方
3.2 method请求的方法限定
除了可以对 url 进行设置,还可以限定请求进来的方法:
限定 GET 方法
@RequestMapping(method = RequestMethod.GET)
如果通过 POST 访问则报错:
HTTP Status 405 - Request method ‘POST’ not supported
限定 POST 方法
@RequestMapping(method = RequestMethod.POST)
如果通过 GET 访问则报错:
HTTP Status 405 - Request method ‘GET’ not supported
POST 和 GET 都可以
@RequestMapping(method = {RequestMethod.GET,RequestMethod.POST})
使用postman
测试接口:
指定method请求方法,更加安全。例如规定为get请求,使用post访问就会报错。
4 springMVC数据校验
数据校验就是用来验证客户输入的数据是否合法,比如客户登录时,用户名不能为空,或者不能超出指定长度等要求,这就叫做数据校验。
数据校验分为客户端校验和服务端校验。
客户端校验: js 校验
服务端校验:springMVC使用validation校验,struts2使用 validation校验
数据由 pojo 承载
为什么有了 js 校验,我们还需要服务端校验? 是因为在服务端校验可以不区分前端页面到底是 PC 端,还是移动端,或者是远程调用。
服务端又可以分为 Controller 层校验和 service 层校验,其中 Controller 层的校验主要是校验页面参数,而 Service 校验主要是校验主要的业务数据。
4.1 步骤
- 导入依赖
<!--数据校验-->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.4.1.Final</version>
</dependency>
- 配置校验器 spring-web.xml
// 配置校验器
<bean name="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
<!-- 提供校验器的类-->
<property name="providerClass" value="org.hibernate.validator.HibernateValidator"/>
</bean>
// 注册
<mvc:annotation-driven validator="validator"/>
- 实体类Dept.java
数据最终是绑定在pojo中,所以需要在pojo的属性上指定校验规则。
private Integer id;
// @NotBlank(message = "部门名字不能为空")
@Pattern(regexp = "^[0-9a-zA-Z_]{4,8}$",message = "不符合部门名规则")
private String deptName;
@NotBlank(message = "部门描述不能为空")
private String deptDesc;
// @NotBlank(message="{name.notnull}")
// @Size(min=3,max=10,message="{name.length}")
新增部门信息时,两个属性都不为空,但是编辑时,部门属性可以为空,这样就不行了,所以有了以下分组的方式。
-
让 pojo 注解生效,在 controller 实现
-
前端页面循环展示错误信息
<c:forEach items="${allErrors}" var="error">
<span style="color: red; font-weight: 900">${error.defaultMessage}</span><br/>
</c:forEach>
4.2 分组校验
校验规则是在 pojo 制定的,而同一个 pojo 可以被多个 Controller 使用,此时会有问题。即:不同的 Controller 方法对同一个 pojo 进行校验,这些校验信息是共享在这不同的 Controller 方法中,但是实际上每个 Controller 方法可能需要不同的校验,这种情况下,就需要使用分组校验来解决这种问题。
通俗的讲,一个 pojo 中有很多属性,controller 中的方法 1 可能只需要校验 pojo 中的属性 1,controller 中的方法 2 只需要校验 pojo 中的属性 2,但是 pojo 中的校验注解有很多,怎样才能使方法 1 只校验属性 1,方法二只校验属性 2 呢?就需要用分组校验来解决。
- 定义分组接口
定义空的接口,接口类只作为标识。
- 在pojo属性上的校验规则注解中,添加分组属性
private Integer id;
// @NotBlank(message = "部门名字不能为空")
@Pattern(
regexp = "^[0-9a-zA-Z_]{4,8}$",
message = "不符合部门名规则!",
groups = {Add.class, Update.class})
private String deptName;
@NotBlank(message = "部门描述不能为空",groups = {Add.class})
private String deptDesc;
- controller方法中使用分组
/**
* 编辑页面
*/
@RequestMapping("/dept/edit/page")
public String editDeptPage(Integer id,Model model) {
System.out.println("controller层的edit中的id为:::"+id);
Dept dept = deptService.getDept(id);
model.addAttribute("dept",dept);
return "dept/edit";
}
/**
* 编辑的方法
*/
@RequestMapping("/dept/edit")
public String edit(
@Validated(value = {Update.class}) Dept dept,
BindingResult bindingResult,
Model model) {
// 判断是否有错误
if (bindingResult.hasErrors()) {
// 获取所有的错误信息
List<ObjectError> allErrors = bindingResult.getAllErrors();
model.addAttribute("allErrors",allErrors);
for (ObjectError allError : allErrors) {
System.out.println(allError.getDefaultMessage());
}
return "forward:/dept/edit/page?id="+dept.getId();
}
Boolean edit = deptService.edit(dept);
if(edit) {
return "forward:/dept/deptList";
} else {
return "dept/edit";
}
}
添加方法:
@RequestMapping("/dept/add")
public String add(@Validated(value = {Add.class}) Dept dept,
BindingResult bindingResult, Model model) {
Boolean add = deptService.add(dept);
// 判断是否有错
if(bindingResult.hasErrors()) {
// 获取错误信息
List<ObjectError> allErrors = bindingResult.getAllErrors();
/*for (ObjectError allError : allErrors) {
System.out.println(allError.getDefaultMessage());
}*/
// 将错误信息发送到 添加页面
model.addAttribute("allErrors",allErrors);
return "dept/add";
}
if(add) {
return "forward:/dept/deptList";
} else {
System.out.println("失败");
return "dept/add";
}
}