在使用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