详解java封装返回结果与RestControllerAdvice注解

2023-05-16 0 4,545

目录

1.为什么要把结果封装成统一格式

异常正常情况无法区分:异常情况返回数据为null,正常情况下查询结果也为null,返回给前端无法区分

显示抛出异常信息:前端需要显示抛出的异常信息

@AllArgsConstructor
public enum ResultCode {
    CODE_200(200, \"success\"),
    CODE_1000(1000, \"fail\");
    @Getter
    private Integer code;
    @Getter
    private String msg;
}
@Data
public class Result<T> {
    private String msg;
    private Integer code;
    private T data;
    private Result(String msg, Integer code) {
        this.msg = msg;
        this.code = code;
    }
    private Result(ResultCode resultCode, String msg) {
        this(msg, resultCode.getCode());
    }
    private Result(ResultCode resultCode) {
        this(resultCode.getMsg(), resultCode.getCode());
    }
    public static <T>Result<T> result(ResultCode resultCode,T data) {
        Result result = new Result(resultCode);
        result.setData(data);
        return result;
    }
    public static <T>Result<T> fail(ResultCode resultCode,String message) {
        Result result = new Result(resultCode, message);
        result.setData(null);
        return result;
    }
    public static <T>Result<T> fail(T data) {
        Result result = new Result(ResultCode.CODE_1000);
        result.setData(data);
        return result;
    }
    public static <T>Result<T> success(T data) {
        Result result = new Result(ResultCode.CODE_200);
        result.setData(data);
        return result;
    }
}

不封装:

详解java封装返回结果与RestControllerAdvice注解

封装:

详解java封装返回结果与RestControllerAdvice注解

2.统一异常接收

为什么要用统一异常接收?

通常在service层抛异常,涉及到事务时不会进行try-catch,需要在controller里处理异常。即使能够进行try-catch的地方也需要统一返回格式,造成重复代码很多,可读性比较差。

如何实现统一的异常接收?

@Slf4j
@RestControllerAdvice
public class GlobalException {
    @ExceptionHandler(Exception.class)
    public Result<?> handlerException(Exception exception) {
        log.info(\"Exception异常信息:\" + exception.getMessage());
        return Result.fail(ResultCode.CODE_1000, exception.getMessage());
    }
    @ExceptionHandler(value = {MyException.class})
    public Result<?> handlerMyException(Exception exception) {
        log.info(\"MyException异常信息:\" + exception.getMessage());
        return Result.fail(ResultCode.CODE_1000, exception.getMessage());
    }
}

抛出异常后,会进入到@RestControllerAdvice注解的方法,过滤出和抛出异常相同的class的方法,执行相应的方法。

protected ModelAndView doResolveHandlerMethodException(HttpServletRequest request, HttpServletResponse response, @Nullable HandlerMethod handlerMethod, Exception exception) {
    //根据异常类型过滤方法
    ServletInvocableHandlerMethod exceptionHandlerMethod = this.getExceptionHandlerMethod(handlerMethod, exception);
    if (exceptionHandlerMethod == null) {
        return null;
    } else {
        if (this.argumentResolvers != null) {
            exceptionHandlerMethod.setHandlerMethodArgumentResolvers(this.argumentResolvers);
        }
        if (this.returnValueHandlers != null) {
            exceptionHandlerMethod.setHandlerMethodReturnValueHandlers(this.returnValueHandlers);
        }
        ServletWebRequest webRequest = new ServletWebRequest(request, response);
        ModelAndViewContainer mavContainer = new ModelAndViewContainer();
        ArrayList<Throwable> exceptions = new ArrayList();
        try {
            if (this.logger.isDebugEnabled()) {
                this.logger.debug(\"Using @ExceptionHandler \" + exceptionHandlerMethod);
            }
            Throwable cause;
            for(Throwable exToExpose = exception; exToExpose != null; exToExpose = cause != exToExpose ? cause : null) {
                exceptions.add(exToExpose);
                cause = ((Throwable)exToExpose).getCause();
            }
            Object[] arguments = new Object[exceptions.size() + 1];
            exceptions.toArray(arguments);
            arguments[arguments.length - 1] = handlerMethod;
            //执行方法
            exceptionHandlerMethod.invokeAndHandle(webRequest, mavContainer, arguments);
        } catch (Throwable var13) {
            if (!exceptions.contains(var13) && this.logger.isWarnEnabled()) {
                this.logger.warn(\"Failure in @ExceptionHandler \" + exceptionHandlerMethod, var13);
            }
            return null;
        }
        if (mavContainer.isRequestHandled()) {
            return new ModelAndView();
        } else {
            ModelMap model = mavContainer.getModel();
            HttpStatus status = mavContainer.getStatus();
            ModelAndView mav = new ModelAndView(mavContainer.getViewName(), model, status);
            mav.setViewName(mavContainer.getViewName());
            if (!mavContainer.isViewReference()) {
                mav.setView((View)mavContainer.getView());
            }
            if (model instanceof RedirectAttributes) {
                Map<String, ?> flashAttributes = ((RedirectAttributes)model).getFlashAttributes();
                RequestContextUtils.getOutputFlashMap(request).putAll(flashAttributes);
            }
            return mav;
        }
    }
}
protected ServletInvocableHandlerMethod getExceptionHandlerMethod(@Nullable HandlerMethod handlerMethod, Exception exception) {
    Class<?> handlerType = null;
    if (handlerMethod != null) {
        handlerType = handlerMethod.getBeanType();
        ExceptionHandlerMethodResolver resolver = (ExceptionHandlerMethodResolver)this.exceptionHandlerCache.get(handlerType);
        if (resolver == null) {
            resolver = new ExceptionHandlerMethodResolver(handlerType);
            this.exceptionHandlerCache.put(handlerType, resolver);
        }
        Method method = resolver.resolveMethod(exception);
        if (method != null) {
            return new ServletInvocableHandlerMethod(handlerMethod.getBean(), method, this.applicationContext);
        }
        if (Proxy.isProxyClass(handlerType)) {
            handlerType = AopUtils.getTargetClass(handlerMethod.getBean());
        }
    }
    //初始化的时候已经将beanType作为key,标注@ExceptionHandler的方法包装成resolve作为value放到exceptionHandlerAdviceCache中
    Iterator var9 = this.exceptionHandlerAdviceCache.entrySet().iterator();
    while(var9.hasNext()) {
        Map.Entry<ControllerAdviceBean, ExceptionHandlerMethodResolver> entry = (Map.Entry)var9.next();
        ControllerAdviceBean advice = (ControllerAdviceBean)entry.getKey();
        if (advice.isApplicableToBeanType(handlerType)) {
            ExceptionHandlerMethodResolver resolver = (ExceptionHandlerMethodResolver)entry.getValue();
            //根据class进行筛选
            Method method = resolver.resolveMethod(exception);
            if (method != null) {
                return new ServletInvocableHandlerMethod(advice.resolveBean(), method, this.applicationContext);
            }
        }
    }
    return null;
}

直接在service层抛出异常,controller中返回正常的结果,由标注了@RestControllerAdvice的类对异常进行处理

@RestController
@RequestMapping(\"/user\")
public class UserController {
    @GetMapping(\"/test\")
    public Result<Boolean> testGlobalException() {
        globalException.throwException();
        return Result.success(Boolean.TRUE);
    }
}

以上就是详解java封装返回结果与RestControllerAdvice注解的详细内容,更多关于java RestControllerAdvice 封装返回的资料请关注其它相关文章!

资源下载此资源下载价格为1小猪币,终身VIP免费,请先
由于本站资源来源于互联网,以研究交流为目的,所有仅供大家参考、学习,不存在任何商业目的与商业用途,如资源存在BUG以及其他任何问题,请自行解决,本站不提供技术服务! 由于资源为虚拟可复制性,下载后不予退积分和退款,谢谢您的支持!如遇到失效或错误的下载链接请联系客服QQ:442469558

:本文采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可, 转载请附上原文出处链接。
1、本站提供的源码不保证资源的完整性以及安全性,不附带任何技术服务!
2、本站提供的模板、软件工具等其他资源,均不包含技术服务,请大家谅解!
3、本站提供的资源仅供下载者参考学习,请勿用于任何商业用途,请24小时内删除!
4、如需商用,请购买正版,由于未及时购买正版发生的侵权行为,与本站无关。
5、本站部分资源存放于百度网盘或其他网盘中,请提前注册好百度网盘账号,下载安装百度网盘客户端或其他网盘客户端进行下载;
6、本站部分资源文件是经压缩后的,请下载后安装解压软件,推荐使用WinRAR和7-Zip解压软件。
7、如果本站提供的资源侵犯到了您的权益,请邮件联系: 442469558@qq.com 进行处理!

猪小侠源码-最新源码下载平台 Java教程 详解java封装返回结果与RestControllerAdvice注解 http://www.20zxx.cn/705796/xuexijiaocheng/javajc.html

猪小侠源码,优质资源分享网

常见问题
  • 本站所有资源版权均属于原作者所有,均只能用于参考学习,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担
查看详情
  • 最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,建议提前注册好百度网盘账号,使用百度网盘客户端下载
查看详情

相关文章

官方客服团队

为您解决烦忧 - 24小时在线 专业服务