文档章节

使用EhCache时,用户按住F5刷新页面,导致socket write error错误的解决方法

RJKD
 RJKD
发布于 2016/03/30 14:29
字数 515
阅读 4402
收藏 1

在使用Ehcache作为网站的页面缓存时,可能会遇到一个问题:当用户按住F5不断刷新页面,在Tomcat的输出日志中会产生如下错误:

ClientAbortException:  java.net.SocketException: Software caused connection abort: socket write error
...
Caused by: java.net.SocketException: Software caused connection abort: socket write error

总之,就是socket write error错误。

实际上,这是由于用户在按住F5时,不断的发出请求,但是,每一次请求并不完整。用户发出一个请求,立马又中断了这个请求。在服务器端,由于Ehcache对页面进行了缓存,Ehcache负责向用户输出缓存的内容。我们查看EhCache的CachingFilter的源代码,其中,writeContent方法即负责向用户输出内容(当然,一般我们选择配置net.sf.ehcache.constructs.web.filter.SimplePageCachingFilter,SimplePageCachingFilter继承了CachingFilter类):

protected void writeContent(final HttpServletRequest request,
            final HttpServletResponse response, final PageInfo pageInfo)
            throws IOException, ResponseHeadersNotModifiableException {
        byte[] body;

        boolean shouldBodyBeZero = ResponseUtil.shouldBodyBeZero(request,
                pageInfo.getStatusCode());
        if (shouldBodyBeZero) {
            body = new byte[0];
        } else if (acceptsGzipEncoding(request)) {
            body = pageInfo.getGzippedBody();
            if (ResponseUtil.shouldGzippedBodyBeZero(body, request)) {
                body = new byte[0];
            } else {
                ResponseUtil.addGzipHeader(response);
            }

        } else {
            body = pageInfo.getUngzippedBody();
        }

        response.setContentLength(body.length);
        OutputStream out = new BufferedOutputStream(response.getOutputStream());
        out.write(body);
        out.flush(); // 这里会产生socket write error
    }

在这里,out.flush()方法负责输出内容的最后刷新。显然,如果用户在服务器向用户发送数据的时候,中断了请求,服务器则会产生ClientAbortException:  java.net.SocketException: Software caused connection abort: socket write error的错误。

当然,这是一种合理的机制。但是,如果后台一直在输出大量的错误日志信息,那么无疑不是我们想要的。那么,如何解决这个问题?

这里,我们可以通过继承net.sf.ehcache.constructs.web.filter.SimplePageCachingFilter,实现一个自己的Filter类:

import java.io.IOException;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.sf.ehcache.constructs.web.PageInfo;
import net.sf.ehcache.constructs.web.ResponseHeadersNotModifiableException;
import net.sf.ehcache.constructs.web.filter.SimplePageCachingFilter;

public class MySimplePageCachingFilter extends SimplePageCachingFilter {
	protected void writeContent(final HttpServletRequest request, final HttpServletResponse response, final PageInfo pageInfo) throws IOException,
			ResponseHeadersNotModifiableException {
		try {
			super.writeContent(request, response, pageInfo);
		} catch (IOException e) {
			System.out.println("访问频率过快!");
		}
	}
}

这里,我们重写writeContent方法,用try catch处理该方法,此时,可以保证在Tomcat的日志记录中,不出现大量的socket write error日志信息。

© 著作权归作者所有

共有 人打赏支持
RJKD
粉丝 8
博文 31
码字总数 7244
作品 0
北碚
程序员
私信 提问
网站出现 502 Bad Gateway 怎么解决?

打开某网站出现一个问题如下图(这里就不说是哪个网站了),那么下面就针对这个问题分享下解决思路。 1、什么是 502 badgateway 报错 ? 简单来说 502 是报错类型代码,bad gateway 错误的网...

几个栗子
2018/08/13
0
0
Caused by: java.io.IOException: 您的主机中的软件中止了一个已建立的连接。

网站架构:Spring 4.1.6 + EhCache 2.6.11 + Tomcat,当按住F5不放,不断刷新网站页面的时候,出现: 的错误。详细堆栈信息如下: 求问大神们,这是为何?...

RJKD
2016/03/30
8.1K
1
502 Bad GateWay是什么意思?

打开网页显示502 Bad GateWay 是什么意思? 关于502是报错类型代买BadGateWay报错的解决方法 -、(通俗解释下:502 Bad Gateway是指错误网关;无效网关;在互联网中表示一种网络错误。表现在...

宵衣旰食
2016/10/29
0
0
flask 不停刷新页面,崩溃

我在本地电脑上安装了flask,并且用例子建了一个web服务器,一切正常 我开始玩了,我用浏览器按住F5不停的刷新页面时,flask就崩溃了。 例子: 报错: Traceback (most recent call last): F...

天国王朝
2016/07/27
1K
2
Jetty8 开启SSL 刷新报错

我用Vaadin(框架)做一个界面的系统,Jetty8做服务器,开启8443作sll端口后,我按住F5刷新,就会报Eof的错误,普通8080端口连接则没问题。是jetty配置的问题还是我Vaadin的配置问题?该如何...

Jian_Ming
2015/01/07
593
1

没有更多内容

加载失败,请刷新页面

加载更多

再谈使用开源软件搭建数据分析平台

三年前,我写了这篇博客使用开源软件快速搭建数据分析平台, 当时收到了许多的反馈,有50个点赞和300+的收藏。到现在我还能收到一些关于dataplay2的问题。在过去的三年,开源社区和新技术的发...

naughty
今天
3
0
C++网络编程(一)gRPC的编译

Google是真滴烦,整个编译链全是自家产品,在编译之前先来安装一堆东西 安装环境依赖 chocolatey Windows下的包管理系统,没有他就慢慢去下载下面的一堆乱七八糟的东西吧。CMD下执行下面这句...

Pulsar-V
今天
3
0
Python3的日期和时间

python 中处理日期时间数据通常使用datetime和time库 因为这两个库中的一些功能有些重复,所以,首先我们来比较一下这两个库的区别,这可以帮助我们在适当的情况下时候合适的库。 在Python文...

编程老陆
今天
2
0
分布式面试整理

并发和并行 并行是两个任务同时进行,而并发呢,则是一会做一个任务一会又切换做另一个任务。 临界区 临界区用来表示一种公共资源或者说是共享数据,可以被多个线程使用,但是每一次,只能有...

群星纪元
今天
3
0
手机通过wifi遥控arduino

手机下载Blinker 从Blinker官网下载手机App,安装到手机。 手机连接WiFi。 点击我的设备右上角的"+"添加设备,选择Arduino -> wifi接入,复制密钥以备后续使用。 点击新建的设备,可以在新界...

davidwbnu
昨天
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部