Spring MVC挂在带有Content-Length标头但没有POST正文的POST请求上

时间:2018-10-15 03:25:07

标签: spring-mvc spring-boot tomcat8

我有一台用Java编写的服务器,该服务器具有在Tomcat下运行的Spring MVC(Spring BOOT)。我们注意到有些客户端正在发送带有内容长度标头但没有实体主体的POST请求。当该请求到达时,请求挂起20秒,然后服务器返回响应(400)。

附加分析器显示挂起的服务器线程具有以下堆栈。

“ http-nio-31114-exec-4”#52守护程序prio = 5 os_prio = 31 tid = 0x00007fc26e6b6000 nid = 0x9f03等待条件[0x0000700010a1f000]    java.lang.Thread.State:TIMED_WAITING(停车)     在sun.misc.Unsafe.park(本机方法)     -停车等待(java.util.concurrent.CountDownLatch $ Sync)     在java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215)     在java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireSharedNanos(AbstractQueuedSynchronizer.java:1037)     在java.util.concurrent.locks.AbstractQueuedSynchronizer.tryAcquireSharedNanos(AbstractQueuedSynchronizer.java:1328)     在java.util.concurrent.CountDownLatch.await(CountDownLatch.java:277)     在org.apache.tomcat.util.net.NioEndpoint $ NioSocketWrapper.awaitLatch(NioEndpoint.java:1106)     在org.apache.tomcat.util.net.NioEndpoint $ NioSocketWrapper.awaitReadLatch(NioEndpoint.java:1108)     在org.apache.tomcat.util.net.NioBlockingSelector.read(NioBlockingSelector.java:184)     在org.apache.tomcat.util.net.NioSelectorPool.read(NioSelectorPool.java:235)     在org.apache.tomcat.util.net.NioSelectorPool.read(NioSelectorPool.java:216)     在org.apache.tomcat.util.net.NioEndpoint $ NioSocketWrapper.fillReadBuffer(NioEndpoint.java:1233)     在org.apache.tomcat.util.net.NioEndpoint $ NioSocketWrapper.read(NioEndpoint.java:1182)     在org.apache.coyote.http11.Http11InputBuffer.fill(Http11InputBuffer.java:713)     在org.apache.coyote.http11.Http11InputBuffer.access $ 300(Http11InputBuffer.java:40)     在org.apache.coyote.http11.Http11InputBuffer $ SocketInputBuffer.doRead(Http11InputBuffer.java:1063)     在org.apache.coyote.http11.filters.IdentityInputFilter.doRead(IdentityInputFilter.java:140)     在org.apache.coyote.http11.Http11InputBuffer.doRead(Http11InputBuffer.java:257)     在org.apache.coyote.Request.doRead(Request.java:541)     在org.apache.catalina.connector.InputBuffer.realReadBytes(InputBuffer.java:326)     在org.apache.catalina.connector.InputBuffer.checkByteBufferEof(InputBuffer.java:634)     在org.apache.catalina.connector.InputBuffer.readByte(InputBuffer.java:337)     在org.apache.catalina.connector.CoyoteInputStream.read(CoyoteInputStream.java:93)     在java.io.FilterInputStream.read(FilterInputStream.java:83)     在java.io.PushbackInputStream.read(PushbackInputStream.java:139)     在org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodArgumentResolver $ EmptyBodyCheckingHttpInputMessage。(AbstractMessageConverterMethodArgumentResolver.java:319)     在org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodArgumentResolver.readWithMessageConverters(AbstractMessageConverterMethodArgumentResolver.java:192)     在org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.readWithMessageConverters(RequestResponseBodyMethodProcessor.java:157)     在org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.resolveArgument(RequestResponseBodyMethodProcessor.java:130)处     在org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:124)     在org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:161)     在org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:131)     在org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:102)     在org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:877)     在org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:783)     在org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)     在org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:991)     在org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:925)     在org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:974)     在org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:877)     在javax.servlet.http.HttpServlet.service(HttpServlet.java:707)     在org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:851)     在javax.servlet.http.HttpServlet.service(HttpServlet.java:790)     在org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)     在org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)     在org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)     在org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)     在org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)     在org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)     在org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:109)     在org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)     在org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)     在org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)     在org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:93)     在org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)     在org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)     在org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)     在org.springframework.cloud.sleuth.instrument.web.ExceptionLoggingFilter.doFilter(ExceptionLoggingFilter.java:48)     在org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)     在org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)     在brave.servlet.TracingFilter.doFilter(TracingFilter.java:61)     在org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)     在org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)     在org.springframework.boot.web.servlet.support.ErrorPageFilter.doFilter(ErrorPageFilter.java:130)     在org.springframework.boot.web.servlet.support.ErrorPageFilter.access $ 000(ErrorPageFilter.java:66)     在org.springframework.boot.web.servlet.support.ErrorPageFilter $ 1.doFilterInternal(ErrorPageFilter.java:105)     在org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)     在org.springframework.boot.web.servlet.support.ErrorPageFilter.doFilter(ErrorPageFilter.java:123)     在org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)     在org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)     在org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200)     在org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)     在org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)     在org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)     在org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198)     在org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)     在org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:478)     在org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)     在org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:80)     在org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:624)     在org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)     在com.fabrikam.valve.RequestTraceValve.lambda $ invoke $ 0(RequestTraceValve.java:41)     在com.fabrikam.valve.RequestTraceValve $$ Lambda $ 423 / 855335917.accept(未知来源)     在com.fabrikam.tomcat.request.trace.RequestTraceInitializer.invoke(RequestTraceInitializer.java:140)     在com.fabrikam.valve.RequestTraceValve.invoke(RequestTraceValve.java:39)     在org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)     在org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:799)     在org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)     在org.apache.coyote.AbstractProtocol $ ConnectionHandler.process(AbstractProtocol.java:861)     在org.apache.tomcat.util.net.NioEndpoint $ SocketProcessor.doRun(NioEndpoint.java:1455)     在org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)     -锁定(org.apache.tomcat.util.net.NioEndpoint $ NioSocketWrapper)     在java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)     在java.util.concurrent.ThreadPoolExecutor $ Worker.run(ThreadPoolExecutor.java:617)     在org.apache.tomcat.util.threads.TaskThread $ WrappingRunnable.run(TaskThread.java:61)     在java.lang.Thread.run(Thread.java:745)

该servlet看起来像这样:

    @CrossOrigin     @RequestMapping(path =“ / event / {apikey} / {anonymousId}”,方法= RequestMethod.POST,产生=“ application / json”)     公共无效clickRawPost(             @PathVariable String apikey,             @PathVariable字符串onymousId,             @RequestBody(required = false)字符串postContent,             HttpServletRequest请求,             HttpServletResponse响应)             引发IOException {

repro命令如下:

  

$ time curl -s http://localhost:8080/event/test/foo -H'内容类型:   application / json'-H'内容长度:100'-X POST -v

此命令在20秒后超时。

我期望它很快就会失败,因为请求中没有实体。

0 个答案:

没有答案