jetty和ajaxanywhere有冲突

探讨了在Jetty服务器上部署使用AjaxAnywhere的应用时出现的问题,详细分析了Jetty与Tomcat在处理forward调用上的差异,指出Jetty会先后尝试关闭writer和outputStream,导致了兼容性问题。

有同事反映jetty下部署的应用程序有问题,而这个应用部署在tomcat则没有问题,这个应用使用了ajaxanywhere,同组的人判断jetty和ajaxanywhere不兼容,到底那里出了问题呢?还要从源码看起。

 

org.ajaxanywhere.BufferResponseWrapper类包装了原始的HttpServletResponse,并重写了getWriter和getOutputStream方法:

    public PrintWriter getWriter() throws IOException {
        if (writerBuffer == null) {
            writerBuffer = new StringWriter();
            pw = new PrintWriter(writerBuffer);
        }
        return pw;
    }

    public ServletOutputStream getOutputStream() throws IOException {
        if (streamBuffer == null) {
            streamBuffer = new ByteArrayOutputStream();
            sos = new ServletOutputStream() {
                public void write(int b) throws IOException {
                    streamBuffer.write(b);
                }

                public void write(byte b[]) throws IOException {
                    streamBuffer.write(b);
                }

                public void write(byte b[], int off, int len) throws IOException {
                    streamBuffer.write(b, off, len);
                }
            };
        }
        return sos;
    }

 在tomcat下发现只调用了getWriter方法,而在jetty下则同时调用了getWriter和getOutputStream方法,为什么会有这种差别呢?

 

问题出在jetty中的一个类:org.eclipse.jetty.server.Dispatcher,这个类的forward方法有问题,和tomcat中的对应的方法逻辑不一样,jetty在处理完forward调用后,有以下的代码:

                if (baseRequest.getResponse().isWriting())
                {
                    try {response.getWriter().close();}
                    catch(IllegalStateException e) 
                    { 
                        response.getOutputStream().close(); 
                    }
                }
                else
                {
                    try {response.getOutputStream().close();}
                    catch(IllegalStateException e) 
                    { 
                        response.getWriter().close(); 
                    }
                }

 tomcat在处理完forward调用后,有以下的代码:

                try {
                    PrintWriter writer = response.getWriter();
                    writer.close();
                } catch (IllegalStateException e) {
                    try {
                        ServletOutputStream stream = response.getOutputStream();
                        stream.close();
                    } catch (IllegalStateException f) {
                        ;
                    } catch (IOException f) {
                        ;
                    }
                } catch (IOException e) {
                    ;
                }

 

tomcat中的逻辑是先关闭writer,如果出错了,再尝试关闭outputStream

jetty中的逻辑是,如果baseRequest中有writer,则先关闭writer,如果没有writer,则先关闭outputStream

而BufferResponseWrapper调用getWriter或getOutputStream并不会触发被包装的HttpServletResponse创建底层的writer或outputStream,所有jetty中永远都会先关闭outputStream,这就会调用BufferResponseWrapper中的getOutputStream方法了。

 

解决的办法是用Tomcat中相关的代码替换Jetty相关的代码

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值