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

Ehcache2 解决办法

方法一

在使用 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.SimplePageCachingFilterSimplePageCachingFilter继承了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日志信息。

方法二

httpServletResponse.setHeader("Content-Type","text/html;charset=UTF-8");
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值