异常拦截类
@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;
}
}