diff --git a/axzo-common-autoconfigure/src/main/java/cn/axzo/framework/autoconfigure/web/exception/ExceptionHandlerAutoConfiguration.java b/axzo-common-autoconfigure/src/main/java/cn/axzo/framework/autoconfigure/web/exception/ExceptionHandlerAutoConfiguration.java index f9b8629..67c2290 100644 --- a/axzo-common-autoconfigure/src/main/java/cn/axzo/framework/autoconfigure/web/exception/ExceptionHandlerAutoConfiguration.java +++ b/axzo-common-autoconfigure/src/main/java/cn/axzo/framework/autoconfigure/web/exception/ExceptionHandlerAutoConfiguration.java @@ -10,7 +10,9 @@ import cn.axzo.framework.autoconfigure.web.exception.support.GlobalExceptionHand import cn.axzo.framework.domain.web.result.Result; import cn.axzo.framework.web.exception.BasicRecordExceptionHandler; import cn.axzo.framework.web.feign.FeignRecordExceptionInterceptor; +import cn.axzo.framework.web.filter.BasicRecordExceptionFilter; import feign.RequestInterceptor; +import org.slf4j.MDC; import org.springframework.boot.autoconfigure.AutoConfigureBefore; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; @@ -25,6 +27,7 @@ import org.springframework.context.annotation.Configuration; import org.springframework.security.oauth2.common.exceptions.OAuth2Exception; import org.springframework.security.oauth2.provider.error.DefaultWebResponseExceptionTranslator; import org.springframework.security.oauth2.provider.error.WebResponseExceptionTranslator; +import org.springframework.web.filter.OncePerRequestFilter; import org.springframework.web.servlet.DispatcherServlet; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler; @@ -200,5 +203,11 @@ public class ExceptionHandlerAutoConfiguration implements WebMvcConfigurer { public BasicRecordExceptionHandler basicRecordExceptionHandler() { return new BasicRecordExceptionHandler(); } + + @Bean + @ConditionalOnClass(MDC.class) + public OncePerRequestFilter oncePerRequestFilter() { + return new BasicRecordExceptionFilter(); + } } } diff --git a/axzo-common-web/src/main/java/cn.axzo.framework.web/exception/BasicRecordExceptionHandler.java b/axzo-common-web/src/main/java/cn.axzo.framework.web/exception/BasicRecordExceptionHandler.java index cecb3f3..ab61b7e 100644 --- a/axzo-common-web/src/main/java/cn.axzo.framework.web/exception/BasicRecordExceptionHandler.java +++ b/axzo-common-web/src/main/java/cn.axzo.framework.web/exception/BasicRecordExceptionHandler.java @@ -58,17 +58,17 @@ public final class BasicRecordExceptionHandler implements PriorityOrdered { @ExceptionHandler(value = Throwable.class) public ApiResult globalException(HttpServletRequest request, HttpServletResponse response, Throwable e) throws Throwable { - String headerValue; - if (StringUtils.hasText(recordExceptionHeaderName) && Objects.nonNull(headerValue = request.getHeader(recordExceptionHeaderName))) { - log.debug("recordException HeaderName: {}", headerValue); - if (Boolean.parseBoolean(headerValue)) { - ApiResult error = ApiResult.err(500, "discovery server internal error"); - Map recordExceptionMap = new HashMap<>(); - recordExceptionMap.put(StringUtils.hasText(applicationName) ? applicationName : "not applicationName found", e); - error.setData(rebuildThrowable(e, request)); - return error; - } - throw e; + String headerValue = request.getHeader(recordExceptionHeaderName); + if (!StringUtils.hasText(headerValue)) { + headerValue = MDC.get(recordExceptionHeaderName); + } + log.debug("recordException HeaderName: {}", headerValue); + if (Boolean.parseBoolean(headerValue)) { + ApiResult error = ApiResult.err(500, "discovery server internal error"); + Map recordExceptionMap = new HashMap<>(); + recordExceptionMap.put(StringUtils.hasText(applicationName) ? applicationName : "not applicationName found", e); + error.setData(rebuildThrowable(e, request)); + return error; } // 重新抛出 throw e; @@ -96,8 +96,10 @@ public final class BasicRecordExceptionHandler implements PriorityOrdered { } String[] parameterValues = request.getParameterValues(MICRO_SERVER_RECORD_ERROR_GET_PARAM_NAME); List filterPackageNames = Lists.newArrayList(MICRO_SERVER_RECORD_ERROR_FILTER_PACKAGE_VALUE); - if(Objects.nonNull(parameterValues) && parameterValues.length > 0) { + if (Objects.nonNull(parameterValues) && parameterValues.length > 0) { filterPackageNames = Arrays.asList(parameterValues); + } else if (StringUtils.hasText(MDC.get(MICRO_SERVER_RECORD_ERROR_GET_PARAM_NAME))) { + filterPackageNames = Arrays.asList(StringUtils.commaDelimitedListToStringArray(MDC.get(MICRO_SERVER_RECORD_ERROR_GET_PARAM_NAME))); } for (StackTraceElement e : elements) { if (StringUtils.hasText(e.getClassName())) { diff --git a/axzo-common-web/src/main/java/cn.axzo.framework.web/feign/FeignRecordExceptionInterceptor.java b/axzo-common-web/src/main/java/cn.axzo.framework.web/feign/FeignRecordExceptionInterceptor.java index 35c9e88..9e61580 100644 --- a/axzo-common-web/src/main/java/cn.axzo.framework.web/feign/FeignRecordExceptionInterceptor.java +++ b/axzo-common-web/src/main/java/cn.axzo.framework.web/feign/FeignRecordExceptionInterceptor.java @@ -43,7 +43,7 @@ public class FeignRecordExceptionInterceptor implements RequestInterceptor { template.header(MICRO_SERVER_RECORD_ERROR_HEADER_NAME, originalRequest.getHeader(MICRO_SERVER_RECORD_ERROR_HEADER_NAME)); } - public HttpServletRequest getOriginalRequest() { + public static HttpServletRequest getOriginalRequest() { try { ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); return attributes.getRequest(); diff --git a/axzo-common-web/src/main/java/cn.axzo.framework.web/filter/BasicRecordExceptionFilter.java b/axzo-common-web/src/main/java/cn.axzo.framework.web/filter/BasicRecordExceptionFilter.java new file mode 100644 index 0000000..28616ba --- /dev/null +++ b/axzo-common-web/src/main/java/cn.axzo.framework.web/filter/BasicRecordExceptionFilter.java @@ -0,0 +1,42 @@ +package cn.axzo.framework.web.filter; + +import cn.axzo.framework.validator.constraints.UTF8; +import com.google.common.collect.Lists; +import jdk.nashorn.internal.runtime.JSONFunctions; +import org.slf4j.MDC; +import org.springframework.core.Ordered; +import org.springframework.core.PriorityOrdered; +import org.springframework.util.StringUtils; +import org.springframework.web.filter.OncePerRequestFilter; + +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.Arrays; + +import static cn.axzo.framework.web.exception.BasicRecordExceptionHandler.MICRO_SERVER_RECORD_ERROR_GET_PARAM_NAME; +import static cn.axzo.framework.web.exception.BasicRecordExceptionHandler.MICRO_SERVER_RECORD_ERROR_HEADER_NAME; + +/** + * TODO + * + * @author wangli + * @since 2024/6/25 09:40 + */ +public class BasicRecordExceptionFilter extends OncePerRequestFilter implements PriorityOrdered { + @Override + public int getOrder() { + return Ordered.HIGHEST_PRECEDENCE; + } + + @Override + protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { + String[] packageNames = request.getParameterValues(MICRO_SERVER_RECORD_ERROR_GET_PARAM_NAME); + MDC.put(MICRO_SERVER_RECORD_ERROR_GET_PARAM_NAME, StringUtils.arrayToCommaDelimitedString(packageNames)); + + // 需要传递外部传入的标识 + MDC.put(MICRO_SERVER_RECORD_ERROR_HEADER_NAME, request.getHeader(MICRO_SERVER_RECORD_ERROR_HEADER_NAME)); + } +}