目录
2、application-dev.properties配置
一、分页插件PageHelper
说明:搭建一个Spring boot + MyBatis的框架,自动生成Mapper的方式,可参考【SpringBoot学习之应用开发篇(二)1.1 搭建项目】
① 先引入分页插件需要的jar包,然后在application-dev.properties文件中配置能扫描到mapper.xml内容
② 自定义一个分页实体bean:PageQuery
③ 最书写一个测试接口(控制层),调用实现类StudentServiceImpl,在实现类中,进行分页查询。
1、pom.xml引入
<!-- pagehelper 分页插件 -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.2.10</version>
</dependency>
<!-- MyBatis依赖:持久层框架,简化了持久层的开发 -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.0.0</version>
</dependency>
2、application-dev.properties配置
# ######################## 如果使用xml方式操作sql,还需要额外的一些配置 ########################
# 别名配置,可以简化xml中的实体类引用方式,直接用名称替代全路径
mybatis.type-aliases-package=org.springboot.springboot01.bean
# 驼峰命名规范,为true时,能识别到userName和username
mybatis.configuration.map-underscore-to-camel-case=true
# mapper映射文件(在resources下)
mybatis.mapper-locations=classpath*:org/springboot/springboot01/mapper/*.xml
3、测试类
3-1、在org.springboot.springboot01.page下(无包则新增),增加PageQuery类
public class PageQuery<T> implements Serializable {
private static final long serialVersionUID = -2053014664193367875L;
public static final String ORDER_DESC = "desc";
public static final String ORDER_ASC = "asc";
/**
* 当前页面数据量
*/
private int pageSize = 10;
/**
* 当前页码
*/
private int pageNum = 1;
/**
* 排序字段
*/
private String field;
/**
* 排序规则,asc升序,desc降序
*/
private String order;
/**
* 返回的结果记录集合
*/
private List<T> records;
/**
* 总记录数
*/
private long total;
// getset...
3-2、在org.springboot.springboot01.controller的StudentController类下,新增分页方法
@RequestMapping("/listAllStudentFromMysqlByPage")
public String listAllStudentFromMysqlByPage(@ModelAttribute Student student, PageQuery<Student> page) {
// 参数初始化
Map<String, String> params = new HashMap<>();
params.put("name", student.getName());
params.put("sex", student.getSex());
// 分页查询
PageQuery<Student> pageQuery = studentService.listAllStudentFromMysqlByPage(params, page);
// 返回分页记录
return JSON.toJSONString(pageQuery);
}
3-3、在org.springboot.springboot01.service和service.impl下新增接口方法
// 1. 在org.springboot.springboot01.service下
import org.springboot.springboot01.bean.Student;
import org.springboot.springboot01.page.PageQuery;
import java.util.Map;
public interface StudentService {
PageQuery<Student> listAllStudentFromMysqlByPage(Map<String, String> params, PageQuery<Student> page);
}
// 2. 在org.springboot.springboot01.service.impl下
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import org.springboot.springboot01.bean.Student;
import org.springboot.springboot01.mysqldao.MysqlStudentMapper;
import org.springboot.springboot01.page.PageQuery;
import org.springboot.springboot01.service.StudentService;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
@Service
public class StudentServiceImpl implements StudentService {
@Resource
private MysqlStudentMapper mysqlStudentMapper;
@Override
public PageQuery<Student> listAllStudentFromMysqlByPage(Map<String, String> params, PageQuery<Student> page) {
// 分页
PageHelper.startPage(page.getPageNum(), page.getPageSize());
// 排序(page.getField()和page.getOrder()的值要不为空,不然需要转换默认排序字段Field和排序规则Order:desc或asc)
PageHelper.orderBy(page.getField() + " " + page.getOrder());
// 查询信息和记录(暂时没有使用params条件查询-主要是用来测试一下)
List<Student> result = mysqlStudentMapper.listAllStudent();
long total = ((Page<Student>) result).getTotal();
page.setRecords(result);
page.setTotal(total);
return page;
}
}
二、参数校验Validator
1、pom.xml引入包
说明:在springboot2.3之前,直接使用spring-boot-starter-web的包就行,它之后参数校验报就拆分了,需要引入下列jar包
<!-- Hibernate Validator参数校验,springboot2.3之后的版本就需要额外添加下列依赖,它之前的版本spring-boot-starter-web会自带 -->
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.0.17.Final</version>
<scope>compile</scope>
</dependency>
<!-- 工具类 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
2、校验拦截结果提示配置
说明:可使用ValidationMessages.properties文件配置拦截结果提示(文件名不可更改,是约定俗成的),内容为中文转Unicode后的值,可以使用http://tool.chinaz.com/tools/unicode.aspx网站转换
# 校验提示信息必须使用ValidationMessages.properties文件,名称不可修改
required=\u4e0d\u80fd\u4e3a\u7a7a
invalid=\u683c\u5f0f\u4e0d\u6b63\u786e
3、校验测试类
3-1、方法参数校验
说明:@Validated注解必须配置,不然方法中@NotBlank、@Email等校验注解不会生效。
@NotBlank 表示不为空
@Email 判断是否是合法的邮箱格式
在org.springboot.springboot01.controller路径下,新建ValidationController类,在类下新增testCheckParam的方法
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.validation.constraints.Email;
import javax.validation.constraints.NotBlank;
@RestController
@Validated
public class ValidationController {
@GetMapping("testCheckParam")
public String testCheckParam(@NotBlank(message = "{required}") String name, @Email(message = "{invalid}") String email) {
return name + "的邮箱是:" + email;
}
}
当name为空、邮箱email=123时,访问http://127.0.0.1:8080/springboot/testCheckParam?email=123后异常如下:
可见,使用这种方式参数校验不通过时,会抛出javax.validation.ConstraintViolationException,我们可使用全局异常捕获来处理这种异常:
在org.springboot.springboot01.handler下,创建GlobalExceptionHandler类,如下:
package org.springboot.springboot01.handler;
import org.apache.commons.lang3.StringUtils;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import javax.validation.Path;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/**
* 注解@Order的作用是定义Spring IOC容器中Bean的执行顺序的优先级,而不是定义Bean的加载顺序,Bean的加载顺序不受@Order的影响
*/
@RestControllerAdvice
@Order(value = Ordered.HIGHEST_PRECEDENCE) // value值越小优先级越高,本次设置最高优先级
public class GlobalExceptionHandler {
@ExceptionHandler(value = ConstraintViolationException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST) // 设置返回报文头的状态
public Map<String, Object> handleConstraintViolationException(ConstraintViolationException e) {
StringBuilder message = new StringBuilder();
Set<ConstraintViolation<?>> violations = e.getConstraintViolations();
for (ConstraintViolation<?> violation : violations) {
Path path = violation.getPropertyPath();
// 分割字符串过程中会按照每个分隔符进行分割,不忽略任何空白项
String [] pathArr = StringUtils.splitByWholeSeparatorPreserveAllTokens(path.toString(), ".");
message.append(pathArr[1]).append(violation.getMessage()).append(",");
}
Map<String, Object> map = new HashMap<>();
map.put("code", HttpStatus.BAD_REQUEST.value());
map.put("message", message.substring(0, message.length() - 1));
return map;
}
}
通过上面的请求地址,测试结果,如图所示:
3-2、实体参数校验
在org.springboot.springboot01.bean路径下,新建UserInfo类
public class UserInfo implements Serializable {
private static final long serialVersionUID = -21204525424000919L;
@NotBlank(message = "{required}")
private String name;
@Email(message = "{invalid}")
private String email;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
在org.springboot.springboot01.controller路径下的ValidationController类,增加testCheckUserInfo的方法
@GetMapping("testCheckUserInfo")
public String testCheckUserInfo(@Valid UserInfo userInfo) {
return userInfo.getName() + "的邮箱是:" + userInfo.getEmail();
}
当访问地址为:http://127.0.0.1:8080/springboot/testCheckUserInfo?email=123时,会出现下列异常
可使用全局异常捕获来处理这种异常:org.springframework.validation.BindException,如下所示
在org.springboot.springboot01.handler路径下,对GlobalExceptionHandler类,添加handleBindException方法:
/**
* 统一处理请求参数校验(实体对象传参)
*
* @param e BindException
* @return Map<String, Object>
*/
@ExceptionHandler(value = BindException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public Map<String, Object> handleBindException(BindException e) {
StringBuilder message = new StringBuilder();
List<FieldError> fieldErrors = e.getBindingResult().getFieldErrors();
for (FieldError error : fieldErrors) {
message.append(error.getField()).append(error.getDefaultMessage()).append(",");
}
Map<String, Object> map = new HashMap<>();
map.put("code", HttpStatus.BAD_REQUEST.value());
map.put("message", message.substring(0, message.length() - 1));
return map;
}
测试结果如图所示: