SpringBoot(八) – 统一数据返回,统一分页工具,统一异常处理
1、统一数据返回
使用逆向工程来进行测试,实体,mapper等省略;
1.1 直接使用 RequestResoult
1.1.1 RequestResoult 请求结果返回实体
//统一返回 实体 类
@Data
public class RequestResult<T> {
//状态码
private String code;
//状态说明,对code的说明
private String msg;
//接口数据
private T data;
}
1.1.2 service层
1.1.2.1 接口
public interface EdocEntryService {
//按摘要查询
List<EdocEntry> getEdocEntriesBySummary(String summary);
}
1.1.2.2 实现类
注意记得在 主启动类中添加 mapper接口扫描注解 :@MapperScan(“com.kgc.sbt.mapper”)
@Service
public class EdocEntryServiceImpl implements EdocEntryService {
@Autowired(required = false)
private EdocEntryMapper edocEntryMapper;
@Override
public List<EdocEntry> getEdocEntriesBySummary(String summary) {
//使用逆向工程,封装查询条件
EdocEntryExample edocEntryExample = new EdocEntryExample();
//排序条件
edocEntryExample.setOrderByClause(" id desc ");
//根据摘要 模糊查询
edocEntryExample.createCriteria().andSummaryLike("%" + summary + "%");
//调用持久层 查询数据
return edocEntryMapper.selectByExample(edocEntryExample);
}
}
1.1.3 测试请求
@Slf4j
@RestController
public class EdocEntryController {
@Autowired
private EdocEntryService edocEntrieService;
//根据电子文档,查询文档列表,直接使用 RequestResult
@GetMapping("/edocEntries")
//指定请求返回类型 RequestResult<List<EdocEntry>>
//public RequestResult<List<EdocEntry>> edocEntries(@RequestParam(required = false) String summary){
//自适应请求返回类型 RequestResult<?>
public RequestResult<?> edocEntries(@RequestParam(required = false) String summary){
//调用业务接口,获取文档列表,进行统一返回
//创建统一返回对象
//每次都需要创建返回对象,代码冗余,不利于维护
RequestResult<List<EdocEntry>> requestResult = new RequestResult<>();
requestResult.setCode("200");
requestResult.setMsg("success");
List<EdocEntry> edocEntriesBySummary = edocEntrieService.getEdocEntriesBySummary(summary);
log.info("{}",edocEntriesBySummary);
requestResult.setData(edocEntriesBySummary);
//接口统一返回查询结果
return requestResult;
}
}
测试结果:
1.2 使用 ResultBuildUtil 结果对象构建工具
1.2.1 CommonConstant 常量类
//Description: 系统常量类,统一管理项目中所有的常量
public class CommonConstant {
/*
统一返回成功的状态码
*/
public static final String UNIFY_RESULT_SUCCESS_CODE = "200";
/*
统一返回成功的信息
*/
public static final String UNIFY_RESULT_SUCCESS_MSG = "SUCCESS";
/*
统一返回错误的状态码
*/
public static final String UNIFY_RESULT_FAIL_CODE = "999";
/*
统一返回错误的信息
*/
public static final String UNIFY_RESULT_FAIL_MSG = "FAIL";
/*
分页默认页吗
*/
public static final int DEFAULT_INIT_PAGE_NO = 1;
/*
分页默认条数
*/
public static final int DEFAULT_INIT_PAGE_SIZE = 3;
}
1.2.2 ResultBuildUtil结果对象构建工具列
//Description: 结果构建工具类
public class ResultBuildUtil {
//构建成功返回,支持任意类型参数
public static <T> RequestResult<T> success(T t) {
//创建统一返回成功结果对象
RequestResult<T> requestResult = new RequestResult<>();
requestResult.setCode(CommonConstant.UNIFY_RESULT_SUCCESS_CODE);
requestResult.setMsg(CommonConstant.UNIFY_RESULT_SUCCESS_MSG);
requestResult.setData(t);
return requestResult;
}
//构建成功返回,空参
public static <T> RequestResult<T> success() {
return success(null);
}
//构建 失败返回,支持任意类型参数,用户不便于归类的异常错误结果返回
public static <T> RequestResult<T> fail(T t) {
//创建统一返回失败结果对象
RequestResult<T> requestResult = new RequestResult<>();
requestResult.setCode(CommonConstant.UNIFY_RESULT_FAIL_CODE);
requestResult.setMsg(CommonConstant.UNIFY_RESULT_FAIL_MSG);
requestResult.setData(t);
return requestResult;
}
//构建 失败返回,空参
public static <T> RequestResult<T> fail() {
//创建统一返回失败结果对象
return fail(null);
}
//构建 失败返回,自定义错误码,和说明,支持任意类型参数
public static <T> RequestResult<T> fail(String errCode,String errMsg,T t) {
//创建统一返回失败结果对象
RequestResult<T> requestResult = new RequestResult<>();
requestResult.setCode(errCode);
requestResult.setMsg(errMsg);
requestResult.setData(t);
return requestResult;
}
//构建 失败返回,自定义错误码,和说明,无参
public static <T> RequestResult<T> fail(String errCode,String errMsg) {
//创建统一返回 失败结果对象
RequestResult<T> requestResult = new RequestResult<>();
requestResult.setCode(errCode);
requestResult.setMsg(errMsg);
return requestResult;
}
}
1.2.3 service层
service层不变;
1.2.4 请求测试
@Slf4j
@RestController
public class EdocEntryController {
@Autowired
private EdocEntryService edocEntrieService;
//根据电子文档,查询文档列表, 使用结果构建工具
@GetMapping("/edocEntries")
public RequestResult<?> edocEntries(@RequestParam(required = false) String summary){
//使用结果构建工具,返回成功的结果
return ResultBuildUtil.success(edocEntrieService.getEdocEntriesBySummary(summary));
}
}
测试结果:
2、统一分页工具
2.1 PageSupport 统一分页工具类
// 分页 结果返回类
@Data
public class PageSupport<T> {
//当前页码
private int pageNo;
//页面条数
private int pageSize;
//总条数
private int totalCount;
//总页数
private int totalPage;
//分页数据
private Collection<T> PageData;
//当总条数确定时,总条数确定
public void setTotalCount(int totalCount) {
this.totalCount = totalCount;
totalPage = totalCount % this.pageSize == 0
? totalCount / this.pageSize
: totalCount / this.pageSize + 1;
}
}
2.2 service 层
2.2.1 接口
public interface EdocEntryService {
//条件分页查询
PageSupport<EdocEntry> getEdocEntriesBySummary(String summary,Integer pageNo,Integer pageSize);
}
2.2.2 实现类
@Service
public class EdocEntryServiceImpl implements EdocEntryService {
@Override
public PageSupport<EdocEntry> getEdocEntriesBySummary(String summary, Integer pageNo, Integer pageSize) {
//创建统一返回分页对象
PageSupport<EdocEntry> pageSupport = new PageSupport<>();
//设置分页参数
pageSupport.setPageNo(pageNo < 1 ? CommonConstant.DEFAULT_INIT_PAGE_NO : pageNo);
pageSupport.setPageSize(pageNo < 3 ? CommonConstant.DEFAULT_INIT_PAGE_SIZE : pageSize);
//封装查询条件
EdocEntryExample edocEntryExample = new EdocEntryExample();
//排序条件
edocEntryExample.setOrderByClause(" id desc ");
//根据摘要 模糊查询
edocEntryExample.createCriteria().andSummaryLike("%" + summary + "%");
// 查询满足条件总条数
pageSupport.setTotalCount((int) edocEntryMapper.countByExample(edocEntryExample));
//增加分页参数
edocEntryExample.setOffset((long)(pageSupport.getPageNo()-1)*pageSupport.getPageSize());
edocEntryExample.setLimit(pageSupport.getPageSize());
//增加分页数据
pageSupport.setPageData(edocEntryMapper.selectByExample(edocEntryExample));
//返回分页对象
return pageSupport;
}
}
2.3 commons-lang中 isEmpty 方法和idBlank区别
2.3.1 依赖
<!-- commons-lang start -->
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>
<!-- commons-lang end -->
2.3.2 isEmpty 方法和idBlank区别
isEmpty 和 isBlank ,isEmpty 方法和idBlank区别:只包含空格字符串判断,isEmpty是false,isBlank是true;
2.3.2.1 isEmpty
* <pre>
* StringUtils.isEmpty(null) = true
* StringUtils.isEmpty("") = true
* StringUtils.isEmpty(" ") = false
* StringUtils.isEmpty("bob") = false
* StringUtils.isEmpty(" bob ") = false
* </pre>
2.3.2.2 isBlank
* <pre>
* StringUtils.isBlank(null) = true
* StringUtils.isBlank("") = true
* StringUtils.isBlank(" ") = true
* StringUtils.isBlank("bob") = false
* StringUtils.isBlank(" bob ") = false
* </pre>
2.4 测试请求
//根据电子文档,查询文档列表
@GetMapping("/edocEntriesPage")
public RequestResult<?> edocEntriesPage(@RequestParam(value = "summary",required = false) String summary,
@RequestParam(value = "pageNo",defaultValue = "1") Integer pageNo,
@RequestParam(value = "pageSize",defaultValue = "3") Integer pageSize){
if(StringUtils.isBlank(summary)){
return ResultBuildUtil.fail();
}
//调用业务接口,获取文档列表,进行统一返回
//使用结果构建工具,返回成功的结果
return ResultBuildUtil.success(edocEntrieService.getEdocEntriesBySummary(summary,pageNo,pageSize));
}
测试结果:
2.5 commons-lang3 生成6位随机数
2.5.1 依赖
<!-- commons-lang3 start -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.7</version>
</dependency>
<!-- commons-lang3 end -->
2.5.2 代码
String code = RandomStringUtils.randomNumeric(6);
3、统一异常处理
3.1 EdocExceptionEnum 自定义异常枚举
//自定义异常枚举
public enum EdocExceptionEnum {
/**
* 参数为空
*/
EDOC_REQUEST_PARAM_EMPTY("201", "参数为空"),
/**
* 参数为非法
*/
EDOC_REQUEST_PARAM_ILLEGAL("202", "参数非法"),
/**
* 网络异常
*/
EDOC_NETWORK_ERROR("301", "网络异常"),
/**
* 数据库异常
*/
EDOC_DATABASE_ERROR("401", "数据库异常"),
/**
* 数据库异常
*/
EDOC_SYSTEM_ERROR("501", "系统异常");
/**
* 异常码
*/
private String errCode;
/**
* 异常说明
*/
private String errMsg;
/**
* 提供带有两个参数的构造方法
*/
EdocExceptionEnum(String errCode, String errMsg){
this.errCode = errCode;
this.errMsg = errMsg;
}
public String getErrCode() {
return errCode;
}
public String getErrMsg() {
return errMsg;
}
}
3.2 EdocException 自定义异常类
public class EdocException extends RuntimeException{
/*
异常枚举类型全局私有属性
*/
private EdocExceptionEnum edocExceptionEnum;
//继承 RuntimeException 生成所有的构造方法
public EdocException() {
}
public EdocException(String message) {
super(message);
}
public EdocException(String message, Throwable cause) {
super(message, cause);
}
public EdocException(Throwable cause) {
super(cause);
}
public EdocException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
//自定义枚举异常构造函数
public EdocException(EdocExceptionEnum edocExceptionEnum){
this.edocExceptionEnum = edocExceptionEnum;
}
//获取枚举异常属性
public EdocExceptionEnum getEdocExceptionEnum() {
return edocExceptionEnum;
}
}
3.3 EdocExceptionHandler 自定义异常统一处理类
//自定义异常统一处理类
@ControllerAdvice
public class EdocExceptionHandler {
/**
* @author : huayu
* @date : 19/10/2022
* @param : [edocException]
* @return : requestResoult<?>
* @description : 系统自定义异常处理,对系统中所有抛出自定义的异常,都会进行统一拦截处理,实现统一返回
*/
@ExceptionHandler(EdocException.class) //指定对该自定义异常类 进行处理
@ResponseBody //指定返回的数据 为 json类型
public RequestResult<?> handleEdocException(EdocException edocException){
//统一返回失败的结果(前提:抛出的必须是带枚举类型的异常)
return ResultBuildUtil.fail(edocException.getEdocExceptionEnum().getErrCode(),edocException.getEdocExceptionEnum().getErrMsg());
}
}
3.4 请求测试
@GetMapping("/edocEntriesPage")
public RequestResult<?> edocEntriesPage(@RequestParam(value = "summary",required = false) String summary,
@RequestParam(value = "pageNo",defaultValue = "1") Integer pageNo,
@RequestParam(value = "pageSize",defaultValue = "3") Integer pageSize){
//判断 summary参数是否为空
if(StringUtils.isBlank(summary)){
//抛出自定义异常:使用异常枚举
throw new EdocException(EdocExceptionEnum.EDOC_REQUEST_PARAM_EMPTY);
}
////抛出自定义异常:使用异常枚举
try {
return ResultBuildUtil.success(edocEntrieService.getEdocEntriesBySummary(summary,pageNo,pageSize));
} catch (Exception e) {
//e.printStackTrace();
//抛出自定义异常:使用异常枚举
throw new EdocException(EdocExceptionEnum.EDOC_DATABASE_ERROR);
}
}
测试请求参数为空:
测试数据库密码错误: