vancefantasy / flyer-maker

a scaffold tool of java project
MIT License
111 stars 15 forks source link

Post请求RequestBody是空问题 #3

Open vancefantasy opened 6 years ago

vancefantasy commented 6 years ago

为了在一个地方记录请求、响应、响应时间等,在拦截器的preHandle方法中读取了一遍HttpServletRequest,导致在controller读取到的RequestBody是空的。@RequestBody的required默认是true,导致抛出以下异常。

HttpServletRequest的流只能读取一次,当前还未找到好的解决办法。

2018-10-25 21:59:14.712 [http-bio-8080-exec-8] ERROR c.f.s.r.c.e.GlobalExceptionHandler: - systemErrorHandler error, URI: /user/edit org.springframework.http.converter.HttpMessageNotReadableException: Required request body is missing: public com.flyer.springmvc.rest.common.BaseResponse com.flyer.springmvc.rest.web.UserController.editUser(com.flyer.springmvc.rest.web.req.SaveOrUpdateUser,org.springframework.validation.BindingResult) at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.readWithMessageConverters(RequestResponseBodyMethodProcessor.java:154) ~[spring-webmvc-4.3.18.RELEASE.jar:4.3.18.RELEASE] at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.resolveArgument(RequestResponseBodyMethodProcessor.java:128) ~[spring-webmvc-4.3.18.RELEASE.jar:4.3.18.RELEASE] at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:121) ~[spring-web-4.3.18.RELEASE.jar:4.3.18.RELEASE] at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:158) ~[spring-web-4.3.18.RELEASE.jar:4.3.18.RELEASE] at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:128) ~[spring-web-4.3.18.RELEASE.jar:4.3.18.RELEASE] at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:97) ~[spring-webmvc-4.3.18.RELEASE.jar:4.3.18.RELEASE] at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827) ~[spring-webmvc-4.3.18.RELEASE.jar:4.3.18.RELEASE] at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738) ~[spring-webmvc-4.3.18.RELEASE.jar:4.3.18.RELEASE] at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85) ~[spring-webmvc-4.3.18.RELEASE.jar:4.3.18.RELEASE] at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:967) ~[spring-webmvc-4.3.18.RELEASE.jar:4.3.18.RELEASE] at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:901) ~[spring-webmvc-4.3.18.RELEASE.jar:4.3.18.RELEASE] at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970) [spring-webmvc-4.3.18.RELEASE.jar:4.3.18.RELEASE] at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:872) [spring-webmvc-4.3.18.RELEASE.jar:4.3.18.RELEASE] at javax.servlet.http.HttpServlet.service(HttpServlet.java:650) [servlet-api.jar:na] at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846) [spring-webmvc-4.3.18.RELEASE.jar:4.3.18.RELEASE] at javax.servlet.http.HttpServlet.service(HttpServlet.java:731) [servlet-api.jar:na] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303) [catalina.jar:7.0.77] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) [catalina.jar:7.0.77] at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197) [spring-web-4.3.18.RELEASE.jar:4.3.18.RELEASE] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.3.18.RELEASE.jar:4.3.18.RELEASE] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) [catalina.jar:7.0.77] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) [catalina.jar:7.0.77] at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) [tomcat7-websocket.jar:7.0.77] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) [catalina.jar:7.0.77] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) [catalina.jar:7.0.77] at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:218) [catalina.jar:7.0.77] at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:110) [catalina.jar:7.0.77] at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:169) [catalina.jar:7.0.77] at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103) [catalina.jar:7.0.77] at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:962) [catalina.jar:7.0.77] at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116) [catalina.jar:7.0.77] at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:445) [catalina.jar:7.0.77] at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1115) [tomcat-coyote.jar:7.0.77] at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:637) [tomcat-coyote.jar:7.0.77] at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:316) [tomcat-coyote.jar:7.0.77] at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_181] at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_181] at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-coyote.jar:7.0.77] at java.lang.Thread.run(Thread.java:748) [na:1.8.0_181]

SoberChina commented 6 years ago

处理流可以读一次可以cash起来,但是在记录rest日志(请求、响应、响应时间等),我感觉aop更适合做日志记录,拦截器从字面意思上理解是拦截请求。环绕通知代理ProceedingJoinPoint 处理起来比较方便。

vancefantasy commented 6 years ago
{
  "general": {
    "requestTime": 1540560781809,
    "method": "POST",
    "latency": 224,
    "queryString": "",
    "URI": "/user/edit"
  },
  "parameters": {
    "a":1
  },
  "requestBody": {"id":1,"openId":"test1"},
  "responseBody": {
    "code": 0,
    "message": "success",
    "data": null
  }
}

@SoberChina 我想要的是这样的结构,我会尝试用AOP的方式写一下,谢谢。

SoberChina commented 6 years ago

@vancefantasy 这样结构完全可以满足。