«Поток закрыт» Ошибка, вызванная, по-видимому, несколькими отправками - PullRequest
1 голос
/ 29 февраля 2012

Я обращаюсь к базе данных Oracle 9 с использованием Java в среде Tomcat 7.

В 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)

1 Ответ

2 голосов
/ 29 февраля 2012

Судя по трассировке стека, это не имеет ничего общего с подключением к базе данных, но похоже, связано с тем, что пользователь отправляет два запроса от серверной части. Я изменил теги, но вы можете немного перефразировать вопрос и изменить заголовок, чтобы привлечь больше внимания.

По сути, ваше приложение получает два запроса и обрабатывает их оба. Я уже давно это видел, но, насколько я помню, первый получает эту ошибку, потому что браузер закрыл соединение TCP / IP, чтобы открыть новое для второго запроса. (Вероятно, это немного упрощает HTTP / 1.1, так как он использует соединения).

Я думаю, что мы решили эту проблему, скрыв уникальный идентификатор на странице в том виде, как он был сгенерирован, и затем обнаружив, получили ли мы второй запрос POST в том же сеансе с этим UID - указывая, что они были отправлены дважды. Это было какое-то время назад, поэтому я довольно размышляю о том, что именно мы сделали, и о том, как мы перестали быть видимыми для пользователя; Напомню, что мы завернули HttpServletRequest для второго запроса в HttpServletRequestWrapper, который, по-видимому, изменил запрос с POST на GET, но мне пришлось бы немного покопаться, чтобы понять, что происходит.

Редактировать: Эта ссылка довольно старая, но, кажется, есть лучший способ справиться с ней, чем что-либо древнее, которое я могу перетащить (что, по сути, является вариантом 2 в этом сообщение). Вероятно, есть несколько распространенных способов справиться с этим.

...