九天猎人 发表于 2022-10-19 15:32:01

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;
      
    }

}测试结果:
https://img2022.cnblogs.com/blog/2793469/202210/2793469-20221019154047737-209933000.png
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));

    }

}测试结果:
https://img2022.cnblogs.com/blog/2793469/202210/2793469-20221019154108504-965026408.png
2、统一分页工具

2.1 PageSupport 统一分页工具类

// 分页 结果返回类
@Data
public classPageSupport<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 依赖

<dependency>
    <groupId>commons-lang</groupId>
    <artifactId>commons-lang</artifactId>
    <version>2.6</version>
</dependency>2.3.2isEmpty 方法和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));
   
}测试结果:
https://img2022.cnblogs.com/blog/2793469/202210/2793469-20221019154209232-1118498334.png
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.2EdocException 自定义异常类

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:
   * @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);
    }

}测试请求参数为空:
https://img2022.cnblogs.com/blog/2793469/202210/2793469-20221019154234098-1995567789.png
测试数据库密码错误:
https://img2022.cnblogs.com/blog/2793469/202210/2793469-20221019154245187-2081940472.png




免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
页: [1]
查看完整版本: SpringBoot(八) - 统一数据返回,统一分页工具,统一异常处理