java - Jetty、Spring 和 SPDY 的 Web 服务器日志中出现异常

标签 java spring spring-mvc jetty spdy

对 Spring MVC Web 应用程序进行休息调用时,我收到以下错误。浏览器收到正确的响应,但我希望异常消失。任何帮助都会很棒。

我正在使用 Jetty 9.2.0.v20140526、Spring 框架 4.0.5.RELEASE 和 NPN 1.1.6.v20130911 (SPDY) 运行 Web 服务器

错误消息

[STDERR] java.lang.IllegalStateException: not lastContent, no content and no responseInfo!
[STDERR]    at org.eclipse.jetty.spdy.server.http.HttpTransportOverSPDY.send(HttpTransportOverSPDY.java:164)
[STDERR]    at org.eclipse.jetty.spdy.server.http.HttpTransportOverSPDY.send(HttpTransportOverSPDY.java:97)
[STDERR]    at org.eclipse.jetty.server.HttpChannel.sendResponse(HttpChannel.java:733)
[STDERR]    at org.eclipse.jetty.server.HttpChannel.write(HttpChannel.java:766)
[STDERR]    at org.eclipse.jetty.server.HttpOutput.write(HttpOutput.java:134)
[STDERR]    at org.eclipse.jetty.server.HttpOutput.write(HttpOutput.java:127)
[STDERR]    at org.eclipse.jetty.server.HttpOutput.flush(HttpOutput.java:229)
[STDERR]    at java.io.FilterOutputStream.flush(FilterOutputStream.java:140)
[STDERR]    at org.eclipse.jetty.servlets.gzip.AbstractCompressedStream.flush(AbstractCompressedStream.java:125)
[STDERR]    at org.springframework.http.converter.AbstractHttpMessageConverter.write(AbstractHttpMessageConverter.java:209)
[STDERR]    at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:143)
[STDERR]    at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:89)
[STDERR]    at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.handleReturnValue(RequestResponseBodyMethodProcessor.java:193)
[STDERR]    at org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite.handleReturnValue(HandlerMethodReturnValueHandlerComposite.java:71)
[STDERR]    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:122)
[STDERR]    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:749)
[STDERR]    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:689)
[STDERR]    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:83)
[STDERR]    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:938)
[STDERR]    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:870)
[STDERR]    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:961)
[STDERR]    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:852)
[STDERR]    at javax.servlet.http.HttpServlet.service(HttpServlet.java:687)
[STDERR]    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:837)
[STDERR]    at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
[STDERR]    at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:751)
[STDERR]    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1666)
[STDERR]    at org.eclipse.jetty.servlets.UserAgentFilter.doFilter(UserAgentFilter.java:83)
[STDERR]    at org.eclipse.jetty.servlets.GzipFilter.doFilter(GzipFilter.java:351)
[STDERR]    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1645)
[STDERR]    at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:564)
[STDERR]    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143)
[STDERR]    at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:578)
[STDERR]    at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:221)
[STDERR]    at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1111)
[STDERR]    at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:498)
[STDERR]    at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:183)
[STDERR]    at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1045)
[STDERR]    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
[STDERR]    at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:199)
[STDERR]    at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:109)
[STDERR]    at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:98)
[STDERR]    at org.eclipse.jetty.server.Server.handle(Server.java:461)
[STDERR]    at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:284)
[STDERR]    at org.eclipse.jetty.server.HttpChannel.run(HttpChannel.java:241)
[STDERR]    at org.eclipse.jetty.spdy.server.http.HttpChannelOverSPDY.run(HttpChannelOverSPDY.java:87)
[STDERR]    at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:607)
[STDERR]    at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:536)
[STDERR]    at java.lang.Thread.run(Thread.java:744)

Spring 代码来 self 的 Controller

@Controller
public class TestController {
    @RequestMapping(value="/run/test", method=RequestMethod.GET, produces="text/plain")
    @ResponseBody
    protected String runTest() throws IOException {
        return "1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012";
    }
}

如果我将返回值的大小变小,它最终会正常工作,不会出现异常。不知道为什么大尺寸是一个问题......

Maven Plugin Config从pom.xml启动Jetty

<plugin>
    <groupId>org.eclipse.jetty</groupId>
    <artifactId>jetty-maven-plugin</artifactId>
    <version>9.2.0.v20140526</version>
    <configuration>
        <scanIntervalSeconds>5</scanIntervalSeconds>
        <stopKey>STOP</stopKey>
        <stopPort>9999</stopPort>
        <jettyXml>src/main/etc/jetty.xml, src/main/etc/jetty-spdy.xml</jettyXml>
        <contextXml>src/main/etc/context.xml</contextXml>
        <waitForChild>true</waitForChild>
        <jvmArgs>-Xbootclasspath/p:${settings.localRepository}/org/mortbay/jetty/npn/npn-boot/1.1.6.v20130911/npn-boot-1.1.6.v20130911.jar -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005 -Dspring.profiles.active=dev</jvmArgs>
    </configuration>
    <dependencies>
        <dependency>
            <groupId>org.eclipse.jetty.spdy</groupId>
            <artifactId>spdy-http-server</artifactId>
            <version>9.2.0.v20140526</version>
        </dependency>
        <dependency>
            <groupId>org.eclipse.jetty</groupId>
            <artifactId>jetty-servlets</artifactId>
            <version>9.2.0.v20140526</version>
        </dependency>
        <dependency>
          <groupId>org.eclipse.jetty</groupId>
          <artifactId>jetty-rewrite</artifactId>
          <version>9.2.0.v20140526</version>
        </dependency>
        <dependency>
          <groupId>org.eclipse.jetty</groupId>
          <artifactId>jetty-jsp</artifactId>
          <version>9.2.0.v20140526</version>
        </dependency>
    </dependencies>
</plugin>

更新:如果我删除 gzip 的 servlet 过滤器,它就会起作用。

来自 web.xml

<filter>
    <filter-name>GzipFilter</filter-name>
    <filter-class>org.eclipse.jetty.servlets.GzipFilter</filter-class>
    <init-param>
        <param-name>mimeTypes</param-name>
        <param-value>text/html,text/plain,text/xml,application/xhtml+xml,text/css,application/javascript,image/svg+xml,application/json</param-value>
    </init-param>
</filter>

<filter-mapping>
    <filter-name>GzipFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

最佳答案

当我尝试对空流进行 flush() 时,我遇到了类似的异常。它只发生在 SPDY 中,因此对于这个协议(protocol),我有特殊版本的 flush() 来检查是否可以刷新流。

在我的输出流中 flush() 看起来像:

synchronized public void flush()
        throws IOException
    {
    // out.flush() do not work on an empty SPDY output stream!!!
    // it ends with:
    // java.lang.IllegalStateException: not lastContent, no content and no responseInfo!
    //    at org.eclipse.jetty.spdy.server.http.HttpTransportOverSPDY.send(HttpTransportOverSPDY.java:164)
    // this is a reason for "flushed" variable
    if (flushed)
        return;
    out.flush();
    flushed = true;
    } // flush

write() 方法中,如果我向输出流写入一些字节,我会设置 flushed = false

我的类使用 out = response.getOutputStream() ,它可以是 SPDY 输出流(引发异常),也可以是 HTTP/HTTPS 输出流,它可以 flush() 清空流而不会出现错误。

关于java - Jetty、Spring 和 SPDY 的 Web 服务器日志中出现异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24544699/

相关文章:

java - 从 application.properties 初始化的类中的最终字段

java - 以 Spring MVC 形式验证整数

hibernate - EntityMode.Map 与 Hibernate 4.2.6+ Spring 3.2

java - Spinner onClick 监听器

java - 除非在双引号中,否则在空格上拆分字符串,但双引号可以附加一个前面的字符串

java - 帮助 : Java web app framework like ASP. 网络

java - 闲置一段时间后或重新启动 mysql 服务器时出现通信链路故障错误

tomcat - 如何在 Tomcat 上将 SPRING MVC Web 应用程序上下文设置为 ROOT (/)?

spring - IntelliJ 需要将 tomcat/conf 目录复制到项目目录

java - 如何在方法抛出 Checked-Exception 时使用 Suppliers.memoize