From c905b8d635199afd9cb0ab6d7f69970923af7500 Mon Sep 17 00:00:00 2001 From: ningxiangsanri Date: Fri, 15 Nov 2019 12:53:41 +0800 Subject: [PATCH 1/3] =?UTF-8?q?=E8=A7=A3=E5=86=B3=20swaggerui=20=E4=B8=8D?= =?UTF-8?q?=E6=98=BE=E7=A4=BA=E9=97=AE=E9=A2=98=EF=BC=8C=E4=BC=98=E5=8C=96?= =?UTF-8?q?=E8=BE=93=E5=87=BA=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../configs/AbstractResponseBodyAdvice.java | 34 +++++ .../web/configs/CustomResponseBodyAdvice.java | 117 ------------------ .../configs/ExceptionResponseBodyAdvice.java | 93 ++++++++++++++ .../web/configs/NormalResponseBodyAdvice.java | 87 +++++++++++++ .../web/configs/SupportOldProjectAdvice.java | 36 ++++++ .../java/com/sanri/web/configs/WebConfig.java | 12 +- 6 files changed, 260 insertions(+), 119 deletions(-) create mode 100644 src/main/java/com/sanri/web/configs/AbstractResponseBodyAdvice.java delete mode 100644 src/main/java/com/sanri/web/configs/CustomResponseBodyAdvice.java create mode 100644 src/main/java/com/sanri/web/configs/ExceptionResponseBodyAdvice.java create mode 100644 src/main/java/com/sanri/web/configs/NormalResponseBodyAdvice.java create mode 100644 src/main/java/com/sanri/web/configs/SupportOldProjectAdvice.java diff --git a/src/main/java/com/sanri/web/configs/AbstractResponseBodyAdvice.java b/src/main/java/com/sanri/web/configs/AbstractResponseBodyAdvice.java new file mode 100644 index 0000000..c38c726 --- /dev/null +++ b/src/main/java/com/sanri/web/configs/AbstractResponseBodyAdvice.java @@ -0,0 +1,34 @@ +package com.sanri.web.configs; + +import org.apache.commons.lang3.ClassUtils; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.core.MethodParameter; +import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice; + +import java.lang.reflect.Executable; + +public abstract class AbstractResponseBodyAdvice implements ResponseBodyAdvice { + /** + * 对于像 swaggerui 等,排除部分包的处理,使用它本身的映射 + * 这里写正则表达式 + */ + @Value("${webui.advice.ignore.package:}") + protected String adviceIgnorePackage; + + public boolean supports(MethodParameter returnType, Class converterType) { + Executable executable = returnType.getExecutable(); + Class declaringClass = executable.getDeclaringClass(); + String packageName = ClassUtils.getPackageName(declaringClass); + + //添加常用技术的过滤支持,如 swagger-ui + if(packageName.startsWith("springfox.documentation.swagger")){ + return false; + } + + if(StringUtils.isNotBlank(adviceIgnorePackage) && packageName.matches(adviceIgnorePackage)){ + return false; + } + return true; + } +} diff --git a/src/main/java/com/sanri/web/configs/CustomResponseBodyAdvice.java b/src/main/java/com/sanri/web/configs/CustomResponseBodyAdvice.java deleted file mode 100644 index 98d7386..0000000 --- a/src/main/java/com/sanri/web/configs/CustomResponseBodyAdvice.java +++ /dev/null @@ -1,117 +0,0 @@ -package com.sanri.web.configs; - -import com.sanri.web.dto.ResponseDto; -import com.sanri.web.dto.TreeResponseDto; -import com.sanri.web.helper.TreeResponseDtoHelper; -import org.apache.commons.lang3.StringUtils; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController; -import org.springframework.cglib.core.ReflectUtils; -import org.springframework.core.MethodParameter; -import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; -import org.springframework.http.ResponseEntity; -import org.springframework.http.server.ServerHttpRequest; -import org.springframework.http.server.ServerHttpResponse; -import org.springframework.web.bind.annotation.RestControllerAdvice; -import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice; -import sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl; - -import java.lang.reflect.AnnotatedType; -import java.lang.reflect.Executable; -import java.lang.reflect.ParameterizedType; -import java.lang.reflect.Type; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.Objects; - -/** - * 可以定义空返回的时候返回正确的信息,如成功信息 - */ -@RestControllerAdvice -public class CustomResponseBodyAdvice implements ResponseBodyAdvice { - @Autowired(required = false) - private ResponseHandler responseHandler; - - public boolean supports(MethodParameter returnType, Class converterType) { - return true; - } - - public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) { - Executable executable = returnType.getExecutable(); - AnnotatedType annotatedReturnType = executable.getAnnotatedReturnType(); - Type type = annotatedReturnType.getType(); - - // 对于异常的处理 - ResponseDto errorResponse = null; - if(executable.getDeclaringClass() == BasicErrorController.class){ - // 如果是方法参数错误 ,被 BasicErrorController 拦截,则只需要取其中的 message 信息做返回 - ResponseEntity responseEntity = (ResponseEntity) body; - HttpStatus statusCode = responseEntity.getStatusCode(); - Map map = (Map) responseEntity.getBody(); - Object message = map.get("message"); - errorResponse = ResponseDto.err(statusCode.value() + "").message(Objects.toString(message)); - } - if(executable.getDeclaringClass() == GlobalExceptionHandler.class){ - //如果是出异常了,直接返回错误处理,如果在异常处理中没有包裹消息,则包裹 - if(type != ResponseDto.class){ //暂时只支持 String 类型,后面可以扩展成层级对象 - String errorInfo = Objects.toString(body); - errorResponse = ResponseDto.err().message(errorInfo); - } - errorResponse = (ResponseDto) body; - } - if(errorResponse != null){ - if(responseHandler != null) { - Object handlerError = responseHandler.handlerError(errorResponse); - return handlerError; - } - return errorResponse; - } - - // 对于正常输出的处理 - ResponseDto outResponse = null; - if(type == ResponseDto.class){ - // 如果本身就返回的是结果类型,则不用转换 - outResponse = (ResponseDto) body; - } - if(type == Void.TYPE){ - // 空返回直接返回成功 - outResponse = ResponseDto.ok(); - } - - if(type instanceof ParameterizedTypeImpl) { - // 如果是 List 类型,并明确说明结果要返回树结构,则做树结构返回 - if (((ParameterizedTypeImpl) type).getRawType() == List.class) { - TreeResponse treeResponse = executable.getAnnotation(TreeResponse.class); - if (treeResponse != null) { - List modifyList = new ArrayList(); - Class treeReposeDtoClass = treeResponse.type(); - String rootId = treeResponse.rootId(); - String rootParentId = treeResponse.rootParentId(); - - // 转换结构成可支持树结构 - List results = (List) body; - for (Object result : results) { - TreeResponseDto newInstance = (TreeResponseDto) ReflectUtils.newInstance(treeReposeDtoClass, new Class[]{result.getClass()}, new Object[]{result}); - modifyList.add(newInstance); - } - - //转换成树结构 - if (StringUtils.isNotBlank(rootId)) { - body = TreeResponseDtoHelper.fastConvertTree(modifyList, rootId); - } else if (StringUtils.isNotBlank(rootParentId)) { - body = TreeResponseDtoHelper.fastConvertForest(modifyList, rootParentId); - } - } - } - } - - // 否则使用成功消息包裹数据 - outResponse = ResponseDto.ok().data(body); - if(responseHandler != null){ - return responseHandler.handlerOut(outResponse); - } - return outResponse; - } -} diff --git a/src/main/java/com/sanri/web/configs/ExceptionResponseBodyAdvice.java b/src/main/java/com/sanri/web/configs/ExceptionResponseBodyAdvice.java new file mode 100644 index 0000000..9db47be --- /dev/null +++ b/src/main/java/com/sanri/web/configs/ExceptionResponseBodyAdvice.java @@ -0,0 +1,93 @@ +package com.sanri.web.configs; + +import com.sanri.web.dto.ResponseDto; +import lombok.extern.slf4j.Slf4j; +import org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController; +import org.springframework.core.MethodParameter; +import org.springframework.core.Ordered; +import org.springframework.core.annotation.Order; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.http.server.ServerHttpRequest; +import org.springframework.http.server.ServerHttpResponse; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.RestControllerAdvice; +import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice; + +import java.lang.reflect.AnnotatedType; +import java.lang.reflect.Executable; +import java.lang.reflect.Method; +import java.lang.reflect.Type; +import java.util.Map; +import java.util.Objects; + +/** + * 异常信息收集处理 + */ +@RestControllerAdvice +@Slf4j +@Order(Ordered.LOWEST_PRECEDENCE - 3) +public class ExceptionResponseBodyAdvice extends AbstractResponseBodyAdvice { + @Override + public boolean supports(MethodParameter returnType, Class converterType) { + boolean supports = super.supports(returnType, converterType); + if(!supports)return supports; + + Executable executable = returnType.getExecutable(); + Class declaringClass = executable.getDeclaringClass(); + ControllerAdvice controllerAdvice = declaringClass.getAnnotation(ControllerAdvice.class); + ExceptionHandler exceptionHandler = executable.getAnnotation(ExceptionHandler.class); + if(declaringClass == BasicErrorController.class){ + return true; + } + if(controllerAdvice != null && exceptionHandler != null){ + return true; + } + return false; + } + + @Override + public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) { + Executable executable = returnType.getExecutable(); + Method method = returnType.getMethod(); + + AnnotatedType annotatedReturnType = executable.getAnnotatedReturnType(); + Type type = annotatedReturnType.getType(); + Class declaringClass = executable.getDeclaringClass(); + ControllerAdvice controllerAdvice = declaringClass.getAnnotation(ControllerAdvice.class); + + if(declaringClass == BasicErrorController.class){ + // 如果已经被 BasicErrorController 拦截,则只需要取其中的 message 信息做返回 + ResponseEntity responseEntity = (ResponseEntity) body; + HttpStatus statusCode = responseEntity.getStatusCode(); + Map map = (Map) responseEntity.getBody(); + Object message = map.get("message"); + return ResponseDto.err(statusCode.value() + "").message(Objects.toString(message)); + } + + // 经测试,这里的值只能有一个,方法可以返回 void ,表示不处理异常 + ExceptionHandler exceptionHandler = executable.getAnnotation(ExceptionHandler.class); + if(controllerAdvice != null && exceptionHandler != null){ //当前方法必须保证是 ControllerAdvice 并且是 ExceptionHandler + Class[] exceptions = exceptionHandler.value(); + Class exception = exceptions[0]; + //如果是进入全局异常处理,则处理全局异常中的返回 + if(type == Void.class){ + //如果返回空,不处理异常,返回前端成功,给出一个警告信息 + log.warn("异常未处理,异常处理方法为:{},异常类为:",method,exception); + return ResponseDto.ok(); + } + if(type == ResponseDto.class){ + return body; + } + + // 将会把返回值转 String,请事先实现 toString 接口 + String errorInfo = Objects.toString(body); + + return ResponseDto.err(exception.getSimpleName()).message(errorInfo); + } + + return body; + } +} diff --git a/src/main/java/com/sanri/web/configs/NormalResponseBodyAdvice.java b/src/main/java/com/sanri/web/configs/NormalResponseBodyAdvice.java new file mode 100644 index 0000000..e376287 --- /dev/null +++ b/src/main/java/com/sanri/web/configs/NormalResponseBodyAdvice.java @@ -0,0 +1,87 @@ +package com.sanri.web.configs; + +import com.sanri.web.dto.ResponseDto; +import com.sanri.web.dto.TreeResponseDto; +import com.sanri.web.helper.TreeResponseDtoHelper; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.ClassUtils; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.cglib.core.ReflectUtils; +import org.springframework.core.MethodParameter; +import org.springframework.core.Ordered; +import org.springframework.core.annotation.Order; +import org.springframework.http.MediaType; +import org.springframework.http.server.ServerHttpRequest; +import org.springframework.http.server.ServerHttpResponse; +import org.springframework.web.bind.annotation.RestControllerAdvice; +import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice; +import sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl; + +import java.lang.reflect.AnnotatedType; +import java.lang.reflect.Executable; +import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.List; + +/** + * 正常数据收集处理 + */ +@RestControllerAdvice +@Slf4j +@Order(Ordered.LOWEST_PRECEDENCE - 2) +public class NormalResponseBodyAdvice extends AbstractResponseBodyAdvice { + + + public boolean supports(MethodParameter returnType, Class converterType) { + boolean supports = super.supports(returnType, converterType); + if(!supports)return supports; + return true; + } + + public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) { + Executable executable = returnType.getExecutable(); + AnnotatedType annotatedReturnType = executable.getAnnotatedReturnType(); + Type type = annotatedReturnType.getType(); + + // 如果空,则为成功 + if(type == Void.TYPE){ + // 空返回直接返回成功 + return ResponseDto.ok(); + } + //如果本身返回 ResponseDto 则不处理 + if(type == ResponseDto.class){ + return body; + } + //检查是否需要树状结构返回 + TreeResponse treeResponse = executable.getAnnotation(TreeResponse.class); + if(treeResponse != null){ + //检查原始返回类型是否为 List 类型,否则给出异常 + if((type instanceof ParameterizedTypeImpl) && ((ParameterizedTypeImpl) type).getRawType() == List.class) { + List modifyList = new ArrayList(); + Class treeReposeDtoClass = treeResponse.type(); + String rootId = treeResponse.rootId(); + String rootParentId = treeResponse.rootParentId(); + + // 转换结构成可支持树结构 + List results = (List) body; + for (Object result : results) { + TreeResponseDto newInstance = (TreeResponseDto) ReflectUtils.newInstance(treeReposeDtoClass, new Class[]{result.getClass()}, new Object[]{result}); + modifyList.add(newInstance); + } + + //转换成树结构,根据需要转成森林或树结构 + if (StringUtils.isNotBlank(rootId)) { + body = TreeResponseDtoHelper.fastConvertTree(modifyList, rootId); + } else if (StringUtils.isNotBlank(rootParentId)) { + body = TreeResponseDtoHelper.fastConvertForest(modifyList, rootParentId); + } + + return ResponseDto.ok().data(body); + } + throw new IllegalArgumentException("树类型返回要求原始数据为 List 类型"); + } + + return ResponseDto.ok().data(body); + } +} diff --git a/src/main/java/com/sanri/web/configs/SupportOldProjectAdvice.java b/src/main/java/com/sanri/web/configs/SupportOldProjectAdvice.java new file mode 100644 index 0000000..e23044c --- /dev/null +++ b/src/main/java/com/sanri/web/configs/SupportOldProjectAdvice.java @@ -0,0 +1,36 @@ +package com.sanri.web.configs; + +import com.sanri.web.dto.ResponseDto; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.MethodParameter; +import org.springframework.core.Ordered; +import org.springframework.core.annotation.Order; +import org.springframework.http.MediaType; +import org.springframework.http.server.ServerHttpRequest; +import org.springframework.http.server.ServerHttpResponse; +import org.springframework.web.bind.annotation.RestControllerAdvice; +import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice; + +@RestControllerAdvice +@Order(Ordered.LOWEST_PRECEDENCE) +public class SupportOldProjectAdvice extends AbstractResponseBodyAdvice { + @Autowired(required = false) + private ResponseHandler responseHandler; + + @Override + public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) { + if((body instanceof ResponseDto) && responseHandler != null){ + ResponseDto responseDto = (ResponseDto) body; + String code = responseDto.getCode(); + Object newBody = null; + if("0".equals(code)){ + newBody = responseHandler.handlerError(responseDto); + }else{ + newBody = responseHandler.handlerOut(responseDto); + } + + return newBody; + } + return body; + } +} diff --git a/src/main/java/com/sanri/web/configs/WebConfig.java b/src/main/java/com/sanri/web/configs/WebConfig.java index c863265..1b58547 100644 --- a/src/main/java/com/sanri/web/configs/WebConfig.java +++ b/src/main/java/com/sanri/web/configs/WebConfig.java @@ -43,8 +43,16 @@ public class WebConfig { * @return */ @Bean - public CustomResponseBodyAdvice customResponseBodyAdvice(){ - return new CustomResponseBodyAdvice(); + public ExceptionResponseBodyAdvice exceptionResponseBodyAdvice(){ + return new ExceptionResponseBodyAdvice(); + } + @Bean + public NormalResponseBodyAdvice normalResponseBodyAdvice(){ + return new NormalResponseBodyAdvice(); + } + @Bean + public SupportOldProjectAdvice supportOldProjectAdvice(){ + return new SupportOldProjectAdvice(); } /** -- Gitee From 26dce9cb096cdf2430fb5dc1048503de45301edc Mon Sep 17 00:00:00 2001 From: ningxiangsanri Date: Fri, 15 Nov 2019 14:44:58 +0800 Subject: [PATCH 2/3] =?UTF-8?q?=E5=A4=84=E7=90=86=E4=B8=80=E4=BA=9B?= =?UTF-8?q?=E4=BC=98=E5=85=88=E7=BA=A7=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../configs/ExceptionResponseBodyAdvice.java | 4 ++-- .../web/configs/GlobalExceptionHandler.java | 8 +++++++- .../web/configs/NormalResponseBodyAdvice.java | 10 ++++++++++ .../web/configs/SupportOldProjectAdvice.java | 18 ++++++++++++++++++ 4 files changed, 37 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/sanri/web/configs/ExceptionResponseBodyAdvice.java b/src/main/java/com/sanri/web/configs/ExceptionResponseBodyAdvice.java index 9db47be..5ca205e 100644 --- a/src/main/java/com/sanri/web/configs/ExceptionResponseBodyAdvice.java +++ b/src/main/java/com/sanri/web/configs/ExceptionResponseBodyAdvice.java @@ -37,7 +37,7 @@ public class ExceptionResponseBodyAdvice extends AbstractResponseBodyAdvice { Executable executable = returnType.getExecutable(); Class declaringClass = executable.getDeclaringClass(); - ControllerAdvice controllerAdvice = declaringClass.getAnnotation(ControllerAdvice.class); + RestControllerAdvice controllerAdvice = declaringClass.getAnnotation(RestControllerAdvice.class); ExceptionHandler exceptionHandler = executable.getAnnotation(ExceptionHandler.class); if(declaringClass == BasicErrorController.class){ return true; @@ -56,7 +56,7 @@ public class ExceptionResponseBodyAdvice extends AbstractResponseBodyAdvice { AnnotatedType annotatedReturnType = executable.getAnnotatedReturnType(); Type type = annotatedReturnType.getType(); Class declaringClass = executable.getDeclaringClass(); - ControllerAdvice controllerAdvice = declaringClass.getAnnotation(ControllerAdvice.class); + RestControllerAdvice controllerAdvice = declaringClass.getAnnotation(RestControllerAdvice.class); if(declaringClass == BasicErrorController.class){ // 如果已经被 BasicErrorController 拦截,则只需要取其中的 message 信息做返回 diff --git a/src/main/java/com/sanri/web/configs/GlobalExceptionHandler.java b/src/main/java/com/sanri/web/configs/GlobalExceptionHandler.java index 1e4a1fc..8a5081e 100644 --- a/src/main/java/com/sanri/web/configs/GlobalExceptionHandler.java +++ b/src/main/java/com/sanri/web/configs/GlobalExceptionHandler.java @@ -8,6 +8,8 @@ import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.ArrayUtils; import org.springframework.beans.factory.annotation.Value; import org.springframework.core.MethodParameter; +import org.springframework.core.Ordered; +import org.springframework.core.annotation.Order; import org.springframework.validation.BindException; import org.springframework.validation.BindingResult; import org.springframework.validation.FieldError; @@ -21,8 +23,12 @@ import java.io.IOException; import java.util.ArrayList; import java.util.List; +/** + * 全局异常处理具有较低的优先级 + */ @RestControllerAdvice @Slf4j +@Order(Ordered.LOWEST_PRECEDENCE) public class GlobalExceptionHandler { @Value("${sanri.webui.package.prefix:com.sanri}") @@ -101,7 +107,7 @@ public class GlobalExceptionHandler { } /** - * 异常处理,可以绑定多个 + * 异常处理,如果子类没有覆盖特定异常的话,将使用默认处理 * @return */ @ExceptionHandler(Exception.class) diff --git a/src/main/java/com/sanri/web/configs/NormalResponseBodyAdvice.java b/src/main/java/com/sanri/web/configs/NormalResponseBodyAdvice.java index e376287..a1a7017 100644 --- a/src/main/java/com/sanri/web/configs/NormalResponseBodyAdvice.java +++ b/src/main/java/com/sanri/web/configs/NormalResponseBodyAdvice.java @@ -14,6 +14,7 @@ import org.springframework.core.annotation.Order; import org.springframework.http.MediaType; import org.springframework.http.server.ServerHttpRequest; import org.springframework.http.server.ServerHttpResponse; +import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RestControllerAdvice; import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice; import sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl; @@ -36,6 +37,15 @@ public class NormalResponseBodyAdvice extends AbstractResponseBodyAdvice { public boolean supports(MethodParameter returnType, Class converterType) { boolean supports = super.supports(returnType, converterType); if(!supports)return supports; + + Executable executable = returnType.getExecutable(); + Class declaringClass = executable.getDeclaringClass(); + RestControllerAdvice controllerAdvice = declaringClass.getAnnotation(RestControllerAdvice.class); + ExceptionHandler exceptionHandler = executable.getAnnotation(ExceptionHandler.class); + if(controllerAdvice != null && exceptionHandler != null){ + return false; + } + return true; } diff --git a/src/main/java/com/sanri/web/configs/SupportOldProjectAdvice.java b/src/main/java/com/sanri/web/configs/SupportOldProjectAdvice.java index e23044c..0d2f44f 100644 --- a/src/main/java/com/sanri/web/configs/SupportOldProjectAdvice.java +++ b/src/main/java/com/sanri/web/configs/SupportOldProjectAdvice.java @@ -8,15 +8,33 @@ import org.springframework.core.annotation.Order; import org.springframework.http.MediaType; import org.springframework.http.server.ServerHttpRequest; import org.springframework.http.server.ServerHttpResponse; +import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RestControllerAdvice; import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice; +import java.lang.reflect.Executable; + @RestControllerAdvice @Order(Ordered.LOWEST_PRECEDENCE) public class SupportOldProjectAdvice extends AbstractResponseBodyAdvice { @Autowired(required = false) private ResponseHandler responseHandler; + @Override + public boolean supports(MethodParameter returnType, Class converterType) { + boolean supports = super.supports(returnType, converterType); + if(!supports)return supports; + + Executable executable = returnType.getExecutable(); + Class declaringClass = executable.getDeclaringClass(); + RestControllerAdvice controllerAdvice = declaringClass.getAnnotation(RestControllerAdvice.class); + ExceptionHandler exceptionHandler = executable.getAnnotation(ExceptionHandler.class); + if(controllerAdvice != null && exceptionHandler != null){ + return false; + } + return true; + } + @Override public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) { if((body instanceof ResponseDto) && responseHandler != null){ -- Gitee From c18beaff70e65e27d541c19134c54ac5362d87bd Mon Sep 17 00:00:00 2001 From: ningxiangsanri Date: Fri, 15 Nov 2019 14:57:30 +0800 Subject: [PATCH 3/3] =?UTF-8?q?=E5=A4=84=E7=90=86=E4=B8=80=E4=BA=9B?= =?UTF-8?q?=E4=BC=98=E5=85=88=E7=BA=A7=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index ff7104d..3fb9474 100644 --- a/README.md +++ b/README.md @@ -599,6 +599,36 @@ public ParamHandler paramHandler(){ ApprovedFileValidator.mimeTypeMagic.put(MimeTypeUtils.parseMimeType("image/png"),"89504e47"); ``` - + ### update 2019/11/15 支持自定义异常处理 + 在此之前,都是框架帮忙把所有异常进行了拦截,但如果用户需要自己定义异常拦截时将没有任何办法,此次更新兼容了用户的异常处理,并将我的全局异常处理定义为最低优先级,如果你发现你的异常处理没有生效(大部分情况下会优先加载应用中的,虽然是同一优先级),请将你的异常处理优先级提高,设置如下 + + ```java + @Order(Ordered.LOWEST_PRECEDENCE - 20) // 数字越小,优先级越高 + public class CustomExceptionHandler + ``` + + 并且将返回类型定义为你自定义的返回类型 ,像这样 + + ```java + @ExceptionHandler(IllegalArgumentException.class) + public ResponseDto exception(IllegalArgumentException e){ + return ResponseDto.err("222").message(e.getMessage()); + } + ``` + + 如果你的异常处理没有拦截到异常,将继续进入我的全局异常处理 ,把异常类名做为 code,把消息放入 message + + + + **解决 bug** + + 支持将一些其它框架的返回忽略全局输出,像 swagger-ui 使用了自己的数据结构,在此之前,框架是照样拦截导致 swagger-ui 无法打开,目前已经支持 swaggerui 无需配置,如果有其它的框架类,你可以这样进行配置 + + ```properties + webui.advice.ignore.package=正则包路径过滤,忽略框架包 + ``` + + + -- Gitee