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

在使用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日志信息。

转载于:https://my.oschina.net/seava/blog/649852

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值