ARTS打卡计划第一周-Tips-ControllerAdvice的使用

时间:2019-04-20
本文章向大家介绍ARTS打卡计划第一周-Tips-ControllerAdvice的使用,主要包括ARTS打卡计划第一周-Tips-ControllerAdvice的使用使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

通常在开发具体项目过程中我们可能会面临如下问题:

  1. 统一所有的json返回结果
  2. 统一处理所有controller中的异常,并且给不同异常不同的返回状态值
  3. 统一对返回的接口做数据校验或者加密,防止篡改

在spring中的处理方式是使用@RestControllerAdvice注解。下面是一个例子,可以将所有的controller中的返回结果,包装成一个CommonResponse。

@RestControllerAdvice
public class CommonResponseDataAdvice implements ResponseBodyAdvice<Object> {

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

        if (methodParameter.getDeclaringClass().isAnnotationPresent(
                IgnoreResponseAdvice.class
        )) {
            return false;
        }

        if (methodParameter.getMethod().isAnnotationPresent(
                IgnoreResponseAdvice.class
        )) {
            return false;
        }

        return true;
    }

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

        CommonResponse<Object> response = new CommonResponse<>(0, "");
        if (null == o) {
            return response;
        } else if (o instanceof CommonResponse) {
            response = (CommonResponse<Object>) o;
        } else {
            response.setData(o);
        }

        return response;
    }
}

  上述代码中定义了一个注解IgnoreResponseAdvice,如果controller的类或者方法有这个注解就不做处理。下面这个例子展现的是如何在controller抛出异常的时候,自动包装成为commonRespons。

@RestControllerAdvice
public class GlobalExceptionAdvice {

    @ExceptionHandler(value = ParamException.class)
    public CommonResponse<String> handlerParamException(HttpServletRequest req,
    		ParamException ex) {
        CommonResponse<String> response = new CommonResponse<>(400,
                "param error");
        response.setData(ex.getMessage());
        return response;
    }
    @ExceptionHandler(value = BusinessException.class)
    public CommonResponse<String> handlerBusinessException(HttpServletRequest req,
    		BusinessException ex) {
        CommonResponse<String> response = new CommonResponse<>(500,
                "business error");
        response.setData(ex.getMessage());
        return response;
    }
    
    @ExceptionHandler(value = SystemException.class)
    public CommonResponse<String> handlerSystemException(HttpServletRequest req,
    		SystemException ex) {
        CommonResponse<String> response = new CommonResponse<>(700,
                "system error");
        response.setData(ex.getMessage());
        return response;
    }
}

  对比下面的controller能更清楚的明白如何使用。

@RestController
public class IndexController {
	
	@RequestMapping("/")
	String home() {
		return "Hello World!";
	}
	@IgnoreResponseAdvice
	@RequestMapping("/hi")
	String hi() {
		return "Hello World!";
	}

	@RequestMapping("/param")
	String param() throws Exception {
		throw new ParamException("参数错误");
	}

	@RequestMapping("/business")
	String business() throws Exception {
		throw new BusinessException("业务错误");
	}
	@RequestMapping("/system")
	String system() throws Exception {
		throw new SystemException("系统错误");
	}
}

  详细的代码见 https://gitee.com/dongqihust/arst/tree/master/custom-response

  特别的,这个文章提供了几种其他的解决方案:https://www.baeldung.com/exception-handling-for-rest-with-spring