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
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。