Spring MVC打印@RequestBody、@Response日志的方法
问题描述:
使用JSON接收前端参数时,SpringMVC默认输出日志如下:
o.s.web.servlet.DispatcherServlet:POST"/example_project/app/login",parameters={}
parameters={}无法打印出JSON消息内容。
如果自己实现参数打印,则需要从reqeust.getInputStream中获取JSON内容,但是由于流只能读取一次,所以会导致后续SpringMVC解析参数异常。
网上找到一种比较解决方法:用HttpRequestWrapper重新封装Reqeust,使打印日志后SpringMVC能正常解析HttpReqeust。这种方法比较麻烦,这里不去研究
这里主要说说Spring提供的较好的解决方案:
可以通过自定义RequestBodyAdvisor、ResponseBodyAdvisor来实现日志输出。
- RequestBodyAdvisor可以获取到解析后的Controller方法参数对象。
- ResponseBodyAdvisor可以获取到Controller方法返回值对象。
然后将他们注册到requestMappingHandlerAdapter:
//继承WebMvcConfigurationSupport,重写该方法 @Override @Bean publicRequestMappingHandlerAdapterrequestMappingHandlerAdapter(){ RequestMappingHandlerAdapteradapter=super.requestMappingHandlerAdapter(); adapter.setRequestBodyAdvice(Lists.newArrayList(newCustomerRequestBodyAdvisor())); adapter.setResponseBodyAdvice(Lists.newArrayList(newCustomerResponseBodyAdvisor())); returnadapter; }
另附CustomerRequestBodyAdvisor、CustomerResponseBodyAdvisor日志输出实现参考:
RequestBodyAdvisor实现参考:
//CustomerRequestBodyAdvisor.java /** *打印请求参数日志 */ publicclassCustomerRequestBodyAdvisorextendsRequestBodyAdviceAdapter{ privatestaticfinalLoggerlogger=LoggerFactory.getLogger(CustomerRequestBodyAdvisor.class); @Override publicbooleansupports(MethodParametermethodParameter,TypetargetType,Class>converterType){ //只处理@RequestBody注解了的参数 returnmethodParameter.getParameterAnnotation(RequestBody.class)!=null; } @Override publicObjectafterBodyRead(Objectbody,HttpInputMessageinputMessage,MethodParameterparameter,TypetargetType,Class>converterType){ Methodmethod=parameter.getMethod(); //参数对象转JSON字符串 StringjsonBody; if(StringHttpMessageConverter.class.isAssignableFrom(converterType)){ jsonBody=body.toString(); }else{ jsonBody=JSON.toJSONString(body,SerializerFeature.UseSingleQuotes); } //自定义日志输出 if(logger.isInfoEnabled()){ logger.info("{}#{}:{}",parameter.getContainingClass().getSimpleName(),method.getName(),jsonBody); //logger.info("jsonrequest<=========method:{}#{}",parameter.getContainingClass().getSimpleName(),method.getName()); } returnsuper.afterBodyRead(body,inputMessage,parameter,targetType,converterType); } }
ResponseBodyAdvisor实现参考:
//CustomerResponseBodyAdvisor.java /** *打印响应值日志 */ publicclassCustomerResponseBodyAdvisorimplementsResponseBodyAdvice
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。