Spring Web 拦截异常, 封装返回结果并记录入参

异常拦截类
	@ControllerAdvice("com.test.xxxx")
	@ResponseBody
	public class GlobalExceptionHandler {

		// 拦截 ServiceException 异常,并封装返回结果
		@ExceptionHandler(ServiceException.class)
	    public BaseResponse serviceExceptionHandler(HttpServletResponse response, ServiceException ex , ServletRequest request) {
	        response.setStatus(200);
	        // 自定义的类
	        LogInfoHandler.LogServiceException(ex, request,logger);
	        return new BaseResponse(ex.getStatus(), ex.getMessage());
	    }
	    
	}
Request缓存类
	// 缓存request请求的InputStream,否则记录传参时直接获取body流会出现 java.io.IOException: Stream closed 错误
	@Component
	public class RequestWrapperFilter extends OncePerRequestFilter {
	
	    @Override
	    protected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, FilterChain filterChain) throws ServletException, IOException {
	        filterChain.doFilter(new ContentCachingRequestWrapper(httpServletRequest), httpServletResponse);
	    }
	
	}
参数日志记录类
	public class LogInfoHandler {
	
	    public static void LogServiceException(ServiceException ex, ServletRequest request, Logger log) {
	        try {
	            LogInfo logInfo = new LogInfo();
	            // 记录错误信息和抛出的代码位置
	            if (ex.getStackTrace() != null && ex.getStackTrace().length > 0) {
	                logInfo.setErrorMsg(ex.getLocalizedMessage() + "\n" + ex.getStackTrace()[0].toString());
	            } else {
	                logInfo.setErrorMsg(ex.getLocalizedMessage());
	            }
	            // 获取接口所有的参数
	            if (request != null && request instanceof ContentCachingRequestWrapper) {
	                NativeWebRequest webRequest = new ServletWebRequest((HttpServletRequest) request);
	                // 获取路由里的参数
	                Map<String, String> pathVariables = (Map<String, String>) webRequest.getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE, RequestAttributes.SCOPE_REQUEST);
	                // 获取路径后面跟的参数
	                Map<String, String[]> parameterMaps = request.getParameterMap();
	                ContentCachingRequestWrapper wrapper = (ContentCachingRequestWrapper) request;
	                // 获取body里的参数
	                String requestBody = StringUtils.toEncodedString(wrapper.getContentAsByteArray(), Charset.forName(wrapper.getCharacterEncoding()));
	                logInfo.setParameterMaps(JSON.toJSONString(parameterMaps));
	                logInfo.setPathVariables(JSON.toJSONString(pathVariables));
	                logInfo.setRequestBody(requestBody);
	            }
	            // 是否打印出所有的堆栈信息
	            if(ex.isStackLog()) {
	                log.error(JSON.toJSONString(logInfo),ex);
	            } else {
	                log.error(JSON.toJSONString(logInfo));
	            }
	        }catch (Exception e) {
	            log.error("LogServiceException 异常", e);
	            log.error(ex.getMessage(),ex);
	        }
	    }
	
	    @Data
	    private static class LogInfo {
	
	        private String errorMsg;
	
	        private String pathVariables;
	
	        private String parameterMaps;
	
	        private String requestBody;
	
	    }
	
	}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值