Springboot中使用ResponseBodyAdvice对异常,分页等请求进行封装

在java 中,我们常常需要对接口返回的数据进行统一的封装,如调用接口异常的时候,我们不希望直接在后台报错,而是需要给前端或者友好提示是什么异常。又或者在处理分页请求的时候,我们可能需要对数据进行统一的封装(返回总条数,数据集等),对于这个需求,我们可以使用ResponseBodyAdvice 这个接口实现。

以下是几个效果图

1.在这里插入图片描述
2.在这里插入图片描述
3.在这里插入图片描述
4.在这里插入图片描述
5.在这里插入图片描述

ResponseBodyAdvice 是 spring 框架中提供的一个接口,其有两个方法,如下:

如图

supports :返回参数是一个boolean类型的数据,表示是否进行响应特殊处理
beforeBodyWrite:表示需要进行特殊处理的时候,需要做的具体处理逻辑

由此可见,通过这两个方法,我们就可以对响应体进行封装。

1.我们新建一个配置类,实现ResponseBodyAdvice 接口,具体代码如下:
package com.xhw.demo.config;

import com.github.pagehelper.Page;
import com.xhw.demo.exception.ResponseErrorBody;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;


/**
 * @author: XiaTian
 * @create-time 16:17 2021/11/19
 */
@ControllerAdvice
public class ResponseConfig implements ResponseBodyAdvice<Object> {

    @Override
    public boolean supports(MethodParameter methodParameter,
                            Class<? extends HttpMessageConverter<?>> aClass) {

        Class<?>  clazz = methodParameter.getParameterType();
        if (clazz.equals(String.class) || clazz.equals(ResponseErrorBody.class)){
            return false;
        }
        // todo 可以配置 需要放过的路由等,自行定义
        return true;
    }

    @Override
    public Object beforeBodyWrite(Object o,
                                  MethodParameter methodParameter,
                                  MediaType mediaType,
                                  Class<? extends HttpMessageConverter<?>> aClass,
                                  ServerHttpRequest serverHttpRequest,
                                  ServerHttpResponse serverHttpResponse) {

        Class<?> clazz = methodParameter.getParameterType();
        Map rtnMap = new HashMap(3 << 1);
        rtnMap.put("status","ok");
        rtnMap.put("timestamp",new Date());
        if (clazz.equals(Page.class)){
            // 对分页的请求进行特殊处理
            Page page = (Page)o;
            rtnMap.put("data",page.getResult());
            rtnMap.put("total",page.getTotal());
            rtnMap.put("pageNum",page.getPageNum());
            rtnMap.put("pageSize",page.getPageSize());
            return rtnMap;
        }
        rtnMap.put("data",o);
        return rtnMap;
    }
}

2.controller 类
package com.xhw.demo.controller;

import com.github.pagehelper.PageHelper;
import com.xhw.demo.entity.User;
import com.xhw.demo.exception.AuthException;
import com.xhw.demo.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.List;


/**
 * @author: XiaTian
 * @create-time 15:30 2021/11/19
// */
@Controller
@ResponseBody
public class TestController {

    @Autowired
    private UserMapper userMapper;

    /**
     * 此接口中 抛出了一个 自定义 认证 异常
     * @return
     */
    @RequestMapping("/test01")
    public String test01(){
        throw new AuthException();
    }

    /**
     * 次接口 返回的是一个字符串, 在 ResponseConfig 中,
     * 我们 不对 返回类型是 String 类型的接口做出做出处理(前提是此接口没有抛出异常)
     * @return
     */
    @RequestMapping(value = "/test02",method = RequestMethod.GET)
    public String test02(){
        return "test02";
    }

    /**
     * 此接口返回的是一个 User 对象
     * @return
     */
    @RequestMapping(value = "/test03",method = RequestMethod.GET)
    public User test03(){
        return new User(1,"user_001","法半夏");
    }

    /**
     * 此接口 必须一个参数
     * @param param
     */
    @RequestMapping(value = "/test04",method = RequestMethod.GET)
    public void test04(@RequestParam  Integer param){

    }

    /**
     * 此接口是一个分页请求
     * @return
     */
    @RequestMapping(value = "/test05",method = RequestMethod.GET)
    public List<User> test05(){
        PageHelper.startPage(1,10);
        return userMapper.getUserList();
    }

}
3. 实体User
package com.xhw.demo.entity;

import lombok.Data;

/**
 * @author: XiaTian
 * @create-time 17:52 2021/11/19
 */
@Data
public class User {

    private Integer id;

    private String uid;

    private String username;


    public User(Integer id, String uid, String username) {
        this.id = id;
        this.uid = uid;
        this.username = username;
    }
}

4. 关于异常的类
4.1 自定义 AuthException
package com.xhw.demo.exception;

/**
 * 自定义异常
 * @author: XiaTian
 * @create-time 16:09 2021/11/19
 */
public class AuthException extends RuntimeException{
    public AuthException(){}

    public AuthException(String message){
        super(message);
    }
}
4.2 异常枚举类ExceptionEnum
package com.xhw.demo.exception;


/**
 * @author: XiaTian
 * @create-time 16:10 2021/11/19
 */
public enum ExceptionEnum {
    /**
     * 认证异常
     */
    AUTH_EXCEPTION(1001,"接口认证失败"),

    /**
     * 缺少请求参数
     */
    MISSING_REQUEST_PARAM_EXCEPTION(2001,"缺少请求参数"),

    /**
     * 请求方法不支持
     */
    REQUEST_METHOD_NOT_SUPPORT(2002,"请求方法不支持");

    /**
     * 响应码
     */
    private Integer code;

    /**
     * 响应消息
     */
    private String message;

    ExceptionEnum(Integer code,String message){
        this.code = code;
        this.message = message;
    }

    public Integer getCode(){
        return this.code;
    }
    public String getMessage() {
        return this.message;
    }

}
4.3 异常处理类
package com.xhw.demo.exception;

import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;


/**
 * @author: XiaTian
 * @create-time 16:14 2021/11/19
 */
@ControllerAdvice
@ResponseBody
public class ExceptionHandlerClass {

    /**
     * 自定义 exception, 认证异常
     * @return
     */
    @ExceptionHandler(AuthException.class)
    public ResponseErrorBody authExceptionHandler(){
        return new ResponseErrorBody(ExceptionEnum.AUTH_EXCEPTION.getCode(),
                ExceptionEnum.AUTH_EXCEPTION.getMessage());
    }

    /**
     *  缺少请求参数
     * @return
     */
    @ExceptionHandler(MissingServletRequestParameterException.class)
    public ResponseErrorBody missingParamHandler(){
        return new ResponseErrorBody(ExceptionEnum.MISSING_REQUEST_PARAM_EXCEPTION.getCode(),
                ExceptionEnum.MISSING_REQUEST_PARAM_EXCEPTION.getMessage());
    }

    /**
     * 请求方法不支持
     * @return
     */
    @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
    public ResponseErrorBody requestMethodExceptionHandler(){
        return new ResponseErrorBody(ExceptionEnum.REQUEST_METHOD_NOT_SUPPORT.getCode(),
                ExceptionEnum.REQUEST_METHOD_NOT_SUPPORT.getMessage());
    }
}

4.4 异常响应体类 ResponseErrorBody
package com.xhw.demo.exception;

/**
 * 异常响应体
 *
 * @author: XiaTian
 * @create-time 16:13 2021/11/19
 */
public class ResponseErrorBody {
    /**
     * 返回码
     */
    private Integer code;

    /**
     * 返回消息
     */
    private String message;

    public ResponseErrorBody(Integer code, String message) {
        this.code = code;
        this.message = message;
    }

    public Integer getCode() {
        return code;
    }

    public void setCode(Integer code) {
        this.code = code;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}

5. UserMapper 类
package com.xhw.demo.mapper;

import com.xhw.demo.entity.User;
import org.apache.ibatis.annotations.Mapper;

import java.util.List;

/**
 * @author: XiaTian
 * @create-time 19:15 2021/11/19
 */
@Mapper
public interface UserMapper {
    List<User> getUserList();
}
6. UserMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.xhw.demo.mapper.UserMapper" >
  <select id="getUserList" resultType="com.xhw.demo.entity.User">
    
    SELECT * FROM user
    
  </select>
</mapper>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值