美文网首页
SpringBoot-@ControllerAdvice中获取泛

SpringBoot-@ControllerAdvice中获取泛

作者: dothetrick | 来源:发表于2020-01-22 15:53 被阅读0次

1.这个需求的背景

​不知大家项目是否碰到过这个场景:

​作为一个后端开发,你提供了十几个不同的api给前端调用,联调的时候突然发现,新来的前端妹子没有在返回值展示时做非null判断,所有异常时要展示0或空字符的值,都要你按完整结构返回,而不是只返回空结构,前端自己填默认值。返回空js就会报错。。。

​例如下面这个返回值,异常时要返回这个:

{
    "code": 1000,
    "data": {
        "fwzy": 0,
        "yyfz": 0,
        "yyzg": "",
    }
}

ok,这个时候你是跟老大反馈呢?还是要前端妹子加班改?

作为一个有追求的程序员,为了项目进度,当然是想个最简单的修改方案,那么思路如下:

  • 通常web api项目中,都会使用@ControllerAdvice统一处理抛出的异常,然后返回错误信息。
    • controller一般会定义一个通用返回类,实际的返回值用泛型标识
    • 例如这样:
import lombok.Data;

@Data
public class CommonResVo<T> {
    private Integer code;
    private String info;
    private T data;
}

  • 如果异常时要保持返回的字段完整,就需要在统一异常处理中根据返回的泛型,创建实际的对象,然后返回。

2. @ControllerAdvice中如何获取返回的实际类型呢?

  • 使用@ExceptionHandler注解的方法,可以使用参数类型为org.springframework.web.method.HandlerMethod的参数获取要处理的类的对象
  • 这里的原理是
    • mvc中检测到Controller抛出的异常后,会通过org.springframework.web.servlet.DispatcherServlet#processHandlerException进行处理,该函数的定义如下:
protected ModelAndView processHandlerException(HttpServletRequest request, 
                                               HttpServletResponse response, 
                                               @Nullable Object handler, 
                                               Exception ex) throws Exception;
  • 处理时会根据对应参数的类型载入参数并调用异常处理方法。
  • 这里有一个注意点
    • @ExceptionHandler修饰的方法的参数中,有类型获取不到的,则这个处理函数不会被触发,相当于没有异常处理了。这个一定要注意。

3. 完整示例

@ControllerAdvice
public class GlobalExceptionHandler {
    private static final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);

    /**
     * 统一异常处理
     *
     * @param var1
     * @param var2
     * @param handlerMethod //抛出异常的controller类
     * @return
     */
    @ExceptionHandler(Exception.class)
    @ResponseBody
    public CommonResVo handleException(HttpServletRequest var1, HttpServletResponse var2, HandlerMethod handlerMethod, Exception e) {
        logger.error("Exception " + e.getMessage());
        Object data = new Object();
        //业务需求,不返回错误,记录异常,返回空对象
        try {
            //获取方法返回类型中,CommonResVo中的泛型对象
            String typeName = ((ParameterizedType) handlerMethod.getMethod().getGenericReturnType()).getActualTypeArguments()[0].getTypeName();
            data = Class.forName(typeName).newInstance();
        } catch (Exception ex) {
            logger.error("获取返回值中泛型类对象失败");
        }
        CommonResVo result = new CommonResVo();
        result.setCode(1000);
        result.setData(data);

        return result;
    }

以上内容属个人学习总结,如有不当之处,欢迎在评论中指正

相关文章

  • SpringBoot-@ControllerAdvice中获取泛

    1.这个需求的背景 ​不知大家项目是否碰到过这个场景: ​作为一个后端开发,你提供了十几个不同的api给前端调用,...

  • 通过反射获取泛型

    获取泛型参数的信息:1、通过Field.getGenericType()方法获取到Type类型(该对象中包含了泛型...

  • Scala 类型系统

    1.在scala泛型中获取其 Class[T] 需求:获取一个泛型 T 的 class 类型的 Class[T],...

  • java 泛型

    1,如何实例化泛型 2,如何获取java中的泛型类型 调用(通常在构造方法中调用):

  • Java泛型的原始类型

    众所周知,Java中的泛型在编译期被擦除,那有没有办法在运行时获取到泛型的原始类型呢?有的。 获取泛型类型 如果定...

  • Scala中泛型类型获取

    背景 笔者最近尝试使用case class作为ActiveMQ消息的定义。同时实现,在消息发送前,将case cl...

  • Java 完美获取泛型类型(包含嵌套的泛型)

    完美获取泛型类型(包含嵌套多层的泛型) 1. 工具类 获取泛型类型工具类 2. 使用方法 2.1. 集成接口带有泛...

  • 关于反射的使用

    反射中获取泛型参数信息

  • Java--size()、length、length()

    size() : 获取泛型集合的长度 length : 获取数组的长度 length : 获取字符串的长度。

  • Java获取泛型参数的Class类型

    需求:两个类:A带泛型参数T,B继承A并给出泛型参数类型,现在想在A中获取T的Class类型。 执行一下代码:

网友评论

      本文标题:SpringBoot-@ControllerAdvice中获取泛

      本文链接:https://www.haomeiwen.com/subject/crouzctx.html