背景系统需要上报每一次请求信息,并将数据上报给监控平台。问题获取接口返回的对象系统接口为RestController,返回结果均为@ResponseBody对象。上报数据时,需要解析返回的结果对象,提取对象中的状态码。从response对象中获取返回结果对象,之前是在filter中通过ContentCachingResponseWrapper方式来获取:publicclassAccessLogFilterextendsOncePerRequestFilterimplementsOrdered{@OverrideprotectedvoiddoFilterInternal(HttpServletRequestrequest,HttpServletResponseresponse,FilterChainfilterChain)throwsServletException,IOException{longbiginTime=System.currentTimeMillis();HttpServletRequesthttpServletRequest=请求;HttpServletResponsehttpServletResponse=响应;如果(!(httpServletRequestinstanceofContentCachingRequestWrapper)){httpServletRequest=newContentCachingRequestWrapper(request);}if(!(httpServletResponseinstanceofContentCachingResponseWrapper)){httpServletResponse=newContentCachingResponseWrapper(response);}try{...//其他操作filterChain.doFilter(httpServletRequest,httpServletResponse);字符串响应正文=invokeHttpByteResponseData((ContentCachingResponseWrapper)httpServletResponse);……//上报等其他操作}finally{((ContentCachingResponseWrapper)httpServletResponse).copyBodyToResponse();AccessLogEntityHolder.remove();}}publicStringinvokeHttpByteResponseData(ContentCachingResponseWrapperresponse){try{Stringcharset=getResponseCharset(response);返回IOUtils.toString(response.getContentAsByteArray(),字符集);}catch(IOExceptione){thrownewRuntimeException("访问日志解析器解析接口返回数据异常!",e);}}protectedStringgetResponseCharset(ContentCachingResponseWrapperresponse){if(response.getContentType()==null){returnStandardCharsets.UTF_8.name();}booleanisStream=response.getContentType().equalsIgnoreCase(MediaType.APPLICATION_OCTET_STREAM;返回isStream&&StringUtils.isNotBlank(response.getCharacterEncoding())?response.getCharacterEncoding():StandardCharsets.UTF_8.name();现在由于担心和引入的第三个插件包中的filter冲突,改为UsingtheInterceptor方法,spring的Interceptor不能像filter一样构造新的请求和响应。这里的解决方案是通过ControllerAdvice获取存储对象,即ControllerAdvice中的beforeBodyWrite方法,在执行时将body临时存储在参数中。这里的存储采用了ThreadLocal的方案。方法如下:@ControllerAdvicepublicclassXXXMetricInterceptorimplementsHandlerInterceptor,Ordered,ResponseBodyAdvice