最近有同事说之前写的全局异常告警,如果有@Valid的注解,在接入新写的插件告警后,返回信息不打印了。全局异常是基于@ExceptionHandler的全局异常类,主要是Servlet MVC的ModelAndView返回的错误信息的捕获。代码如下:
/** * @author xxx */ @RestControllerAdvice public class DefaultGlobalExceptionHandler { private static final Logger log = LoggerFactory.getLogger(DefaultGlobalExceptionHandler.class); /** * @param ex * @return 响应对象 * @description 基础异常 */ @ExceptionHandler(value = {BaseException.class}) public Result baseException(BaseException ex) { log.error("baseException:{}", ex); return Result.fail(ex.getErrorCode(), ex.getErrorMsg()); } @ExceptionHandler(value = {Exception.class}) public Result exception(Exception ex) { log.error("Exception:{}", ex); return Result.fail(); } @ExceptionHandler(value = {MaxUploadSizeExceededException.class}) public Result exception(MaxUploadSizeExceededException ex) { log.error("RuntimeException:{}", ex); return Result.error(CommonResultStatus.COMMON_ERROR_UPLOAD_SIZE_EXCEED.getCode(),"上传文件大小超出限制!"); } @ExceptionHandler(value = {RuntimeException.class}) public Result exception(RuntimeException ex) { log.error("RuntimeException:{}", ex); return Result.fail(); } /** * 处理Get请求中 使用@Valid 验证路径中请求实体校验失败后抛出的异常 * * @param ex * @return com.gwm.marketing.common.result.Result * @author xxx * @date 15:01 2021/6/11 */ @ExceptionHandler(BindException.class) @ResponseStatus(HttpStatus.BAD_REQUEST) public Result validExceptionHandler(BindException ex) { String message = ex.getBindingResult().getAllErrors().stream().map(DefaultMessageSourceResolvable::getDefaultMessage).collect(Collectors.joining(",")); return Result.error(CommonResultStatus.COMMON_INVALID_PARAM.getCode(),CommonResultStatus.COMMON_INVALID_PARAM.getMessage()+":["+message+"]"); } /** * 处理请求参数格式错误 @RequestParam上validate失败后抛出的异常 * * @param ex * @return * @author * @date 15:15 2021/6/11 */ @ExceptionHandler(ConstraintViolationException.class) @ResponseStatus(HttpStatus.BAD_REQUEST) public Result ConstraintViolationExceptionHandler(ConstraintViolationException ex) { String message = ex.getConstraintViolations().stream().map(ConstraintViolation::getMessage).collect(Collectors.joining(",")); return Result.error(CommonResultStatus.COMMON_INVALID_PARAM.getCode(),CommonResultStatus.COMMON_INVALID_PARAM.getMessage()+":["+message+"]"); } /** * 处理请求参数格式错误 @RequestBody上validate失败后抛出的异常 * * @param ex * @return com.gwm.marketing.common.result.Result * @author xxx * @date 15:16 2021/6/11 */ @ExceptionHandler(MethodArgumentNotValidException.class) @ResponseStatus(HttpStatus.BAD_REQUEST) public Result MethodArgumentNotValidExceptionHandler(MethodArgumentNotValidException ex) { String message = ex.getBindingResult().getAllErrors().stream().map(DefaultMessageSourceResolvable::getDefaultMessage).collect(Collectors.joining(",")); return Result.error(CommonResultStatus.COMMON_INVALID_PARAM.getCode(),CommonResultStatus.COMMON_INVALID_PARAM.getMessage()+":["+message+"]"); } @ExceptionHandler(value = {Throwable.class}) @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) public Result throable() { return Result.fail(); } }
加入的插件告警是基于@WebMvcConfigurer,里面重写了对于异常的处理,重写了HandlerExceptionResolver,如果有异常信息,通过钉钉告警的方式实时通知。加了这么一个功能。同事给我说了之后,我本地使用postman发现本地是能复现的,于是开始一点点的调试追踪。
首先是重写WebMvcConfigurer
package com.gwm.marketing.filter; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.databind.ObjectMapper; import com.gwm.marketing.filter.exception.DingdingHandleException; import com.gwm.marketing.filter.intercepter.*; import okhttp3.Interceptor; import okhttp3.Request; import okhttp3.Response; import org.jetbrains.annotations.NotNull; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.format.FormatterRegistry; import org.springframework.http.converter.*; import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import org.springframework.validation.MessageCodesResolver; import org.springframework.validation.Validator; import org.springframework.web.method.support.HandlerMethodArgumentResolver; import org.springframework.web.method.support.HandlerMethodReturnValueHandler; import org.springframework.web.servlet.DispatcherServlet; import org.springframework.web.servlet.HandlerExceptionResolver; import org.springframework.web.servlet.config.annotation.*; import java.io.IOException; import java.util.List; import java.util.Optional; /** * @Author fanht * @Description 拦截器参数校验 * @Date 2021/11/12 2:05 下午 * @Version 1.0 */ @Configuration public class OraDingdingConfigurer implements WebMvcConfigurer, Interceptor { /** * 拦截器参数校验 * * @param interceptorRegistry */ @Override public void addInterceptors(InterceptorRegistry interceptorRegistry) { //注意拦截器的顺序 interceptorRegistry.addInterceptor(new CharacterValidInterceptors()); interceptorRegistry.addInterceptor(new HttpParamVerifyInterceptor()); interceptorRegistry.addInterceptor(new HttpRequestStatisticsInterceptor()); } @Override public void configurePathMatch(PathMatchConfigurer pathMatchConfigurer) { } @Override public void configureContentNegotiation(ContentNegotiationConfigurer contentNegotiationConfigurer) { } @Override public void configureAsyncSupport(AsyncSupportConfigurer asyncSupportConfigurer) { } @Override public void configureDefaultServletHandling(DefaultServletHandlerConfigurer defaultServletHandlerConfigurer) { } @Override public void addFormatters(FormatterRegistry formatterRegistry) { } @Override public void addResourceHandlers(ResourceHandlerRegistry resourceHandlerRegistry) { } @Override public void addCorsMappings(CorsRegistry corsRegistry) { } @Override public void addViewControllers(ViewControllerRegistry viewControllerRegistry) { } @Override public void configureViewResolvers(ViewResolverRegistry viewResolverRegistry) { } @Override public void addArgumentResolvers(List<HandlerMethodArgumentResolver> list) { } @Override public void addReturnValueHandlers(List<HandlerMethodReturnValueHandler> list) { } @Override public void configureMessageConverters(List<HttpMessageConverter<?>> list) { } @Override public void extendMessageConverters(List<HttpMessageConverter<?>> list) { //新版本中的 Optional<HttpMessageConverter<?>> optional = list.stream() .filter(o -> o instanceof MappingJackson2HttpMessageConverter) .findFirst(); if (optional.isPresent()) { MappingJackson2HttpMessageConverter converter = (MappingJackson2HttpMessageConverter) optional.get(); ObjectMapper mapper = converter.getObjectMapper(); mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); } } @Override public void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> list) { } @Override public void extendHandlerExceptionResolvers(List<HandlerExceptionResolver> list) { //todo 添加全局异常,因为HandlerInterceptor不能显示异常 之前是写到了configureHandlerExceptionResolvers 里面,使用哪个会和全局异常DefaultGlobalExceptionHandler有先后顺序问题 list.add(0,new DingdingHandleException()); } @Override public Validator getValidator() { return null; } @Override public MessageCodesResolver getMessageCodesResolver() { return null; } @NotNull @Override public Response intercept(@NotNull Chain chain) throws IOException { Request request = chain.request(); return chain.proceed(request); } @Bean public DispatcherServlet dispatcherServlet(){ return new OraDispatcherServlet(); } }
原来我是直接实现configureHandlerExceptionResolvers,在
@Override public void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> list) { list.add(new DingdingHandleException()); }
DingdingHandleException()代码如下
但是每次调试发现,哪个全局异常确实是走到了,但是在走到下一步的ModelAndView的解析器时候,
标签:void,ExceptionHandler,HandlerExceptionResolver,ex,Override,import,告警,public,Resu From: https://www.cnblogs.com/thinkingandworkinghard/p/17408899.html