我正在Tomcat 7环境中使用Java访问Oracle 9数据库。

在context.xml中,我有

<Resource type="javax.sql.DataSource" auth="Container"
    name="jdbc/myDB"
    factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
    driverClassName="oracle.jdbc.OracleDriver"
    url="jdbc:oracle:thin:@localhost:1521:db" maxwait="10000"
     username="temp" password="temp" maxActive="20" maxIdle="10"/>


我的Java代码大多数时候都可以工作,但是有时我会随机收到Stream Closed异常。我怀疑这可能是因为用户过快地按下了应用程序中的按钮,从而在完成另一个查询之前开始了一个查询。

此异常是由以下代码中的doEndTag函数引起的。

public class SQLIteratorTag extends BodyTagSupport
{
public SQLIteratorTag()
{
    query = "";
    rs = null;
    stmt = null;
    rsmd = null;
    dbConn = null;
    con = null;
}

public int doStartTag()
    throws JspTagException
{
    String fieldName = "";
    try
    {
        DBConnection d=DBConnection.getInstance();

        con = d.getConnection();
       ...

public int doAfterBody()
    throws JspException
{
    try
    {
    ....


public int doEndTag()
    throws JspException
{
    try
    {
        if(bodyContent != null)
        {
            bodyContent.writeOut(bodyContent.getEnclosingWriter());
        }
    }
    catch(IOException ex)
    {
        Log.getIns


我不想发布太多代码,但是我可能发布的太少。我不知道问题可能在哪里,但是如有必要,我将更新问题。

异常本身是:

SEVERE: Servlet.service() for servlet [jsp] in context with path [/charm] threw  exception [javax.servlet.ServletException: javax.servlet.jsp.JspTagException: Stream    closed] with root cause
javax.servlet.jsp.JspTagException: Stream closed
at c.tags.sql.SQLIteratorTag.doEndTag(SQLIteratorTag.java:218)
at   org.apache.jsp.comp_005fpara_jsp._jspService(comp_005fpara_jsp.java:708)
at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:432)
at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:390)
at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:334)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at com.jspbook.GZIPFilter.doFilter(Unknown Source)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:224)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:169)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:927)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:987)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:579)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:309)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
at java.lang.Thread.run(Thread.java:722)

最佳答案

从堆栈跟踪来看,这似乎与数据库连接无关,但与用户从后端提交两个请求有关。我已经更改了标签,但是您可能需要改写一些问题并更改标题以引起更多关注。

本质上,您的应用程序接收两个请求,并同时处理它们。自从我看到这种情况已经有一段时间了,但是据我所记得,第一个出现此错误是因为浏览器已关闭TCP / IP连接以便为第二个请求打开一个新的连接。 (对于HTTP / 1.1,由于它重用了连接,因此可能有点简单)。

我认为我们可以通过在页面上隐藏唯一的标识符来解决此问题,然后在同一个会话中检测是否有第二个POST请求与该UID一起使用-表示他们提交了两次。但是,这是前一阵子,所以我对所做的事情以及如何阻止它对用户可见的意义不甚了解。我确实记得我们将第二个请求的HttpServletRequest包装在一个HttpServletRequestWrapper中,该外观似乎将请求从POST更改为GET,但是我必须做一些挖掘才能弄清楚发生了什么。

编辑:This link已经很老了,但是似乎有比我可以拖延的任何古老方式更好的方法(这似乎是该帖子中的选项2)。可能有几种常见的方法可以解决此问题。

07-27 14:04