使用EhCache時,用戶按住F5刷新頁面,致使socket write error錯誤的解決方法

在使用Ehcache做爲網站的頁面緩存時,可能會遇到一個問題:當用戶按住F5不斷刷新頁面,在Tomcat的輸出日誌中會產生以下錯誤:java

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錯誤。web

實際上,這是因爲用戶在按住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的錯誤。服務器

固然,這是一種合理的機制。可是,若是後臺一直在輸出大量的錯誤日誌信息,那麼無疑不是咱們想要的。那麼,如何解決這個問題?socket

這裏,咱們能夠經過繼承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日誌信息。spa

相關文章
相關標籤/搜索