標籤:pat 過濾 cep parameter author lte main component str
一個網站的首頁一般不會頻繁變動,而大多數使用者在訪問網站時不過瀏覽一下首頁(未登陸)。然後就離開了。對於這類訪問請求。假設每次都要通過查詢資料庫來顯示首頁的話,顯然會給server帶來多餘的壓力。
這時候我們能夠將首頁靜態化。在減輕資料庫server壓力的同一時候又能大大提高首頁高訪問速度。
對於Java來說,如今有非常多架構但是實現首頁的靜態化。事實上這並不難。我們也能夠自己手動實現。
思路例如以下:
首先編寫一個小程式類比瀏覽器向webserver發送GET請求。得到首頁的HTML代碼後,將其儲存到檔案裡。
然後寫一個過濾器攔截訪問請求。一旦發現訪問的是首頁。那麼就直接將儲存好的靜態HTML檔案返回給client。這樣就避開了架構(如 Spring MVC),更避開了資料庫查詢。假設首頁內容發生了變化,我們能夠再執行一下小程式以得到最新的首頁HTML代碼。
編寫HTTPclient程式類比瀏覽器這裡我使用 apache 的 HttpClient 庫編寫這個小程式。例如以下例。我們通過向 http://locahost:8080/codeschool/ 發送GET請求來得到server返回的HTML代碼:
/** * 向localhost:8080發送GET請求,擷取返回的HTML代碼並儲存到檔案裡 * @author whf * */public class Client {public static void main(String[] args) throws Exception {CloseableHttpClient httpclient = HttpClients.createDefault();try {HttpGet httpGet = new HttpGet("http://127.0.0.1:8080/codeschool");CloseableHttpResponse response = httpclient.execute(httpGet);try {System.out.println(response.getStatusLine());HttpEntity entity = response.getEntity();// entity封裝了server返回的資料String html = EntityUtils.toString(entity);// 將HTML代碼寫入到檔案裡saveContent(html, "/home/whf/workspace-sts/codeschool/home.html");EntityUtils.consume(entity);} finally {response.close();}} finally {httpclient.close();}}/** * 將HTML寫入到指定檔案裡 * * @param html * @param path 檔案路徑 * @throws IOException */private static void saveContent(String html, String path) throws IOException {FileOutputStream fos = new FileOutputStream(path);BufferedOutputStream bos = new BufferedOutputStream(fos);bos.write(html.getBytes());bos.close();}}
所需的 dependency 例如以下:
<dependencies><dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpclient</artifactId><version>4.3.4</version></dependency></dependencies>
運行一下該程式,就會得到 home.html 檔案。
編寫過濾器編寫一個 url-pattern 為 /* 的 Filter 過濾器,一旦發現使用者訪問的是首頁,則直接返回上面產生的 home.html 檔案,關閉輸出資料流。代碼例如以下:
public class SecureFilter implements Filter {private static final Logger logger = LoggerFactory.getLogger(SecureFilter.class);private ServletContext ctx;@Overridepublic void destroy() {}@Overridepublic void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) throws IOException, ServletException {// 防止中文亂碼request.setCharacterEncoding("UTF-8");HttpServletRequest req = (HttpServletRequest) request;String path = req.getRequestURI();// 請求的是資源。跳過if (true == path.startsWith("/codeschool/resources")) {chain.doFilter(request, response);return;}// 使用者未登陸// 使用者訪問首頁// 返回靜態頁面if (path.equals("/codeschool/") || path.equals("/")) {writeStaticHomePage(req, (HttpServletResponse) response);return;}chain.doFilter(request, response);}/** * 將靜態首頁返回給client * * @param req * @param resp * @throws IOException */private void writeStaticHomePage(HttpServletRequest req,HttpServletResponse resp) throws IOException {// 返回靜態化頁面// 得到home.html路徑String pagePath = (String) ctx.getInitParameter("HOME_PAGE_PATH");if (logger.isDebugEnabled()) {logger.debug("首頁靜態頁面路徑:{}", pagePath);}// 將homt.html返回給clientServletOutputStream out = resp.getOutputStream();FileInputStream pageInStream = new FileInputStream(pagePath);BufferedInputStream bufInStream = new BufferedInputStream(pageInStream);byte[] buf = new byte[2048];int len = 0;while ((len = bufInStream.read(buf)) != -1) {out.write(buf, 0, len);}bufInStream.close();out.close();}@Overridepublic void init(FilterConfig cfg) throws ServletException {this.ctx = cfg.getServletContext();}}
能夠在web.xml裡配置 home.html 的路徑:
<!-- 靜態首頁的路徑 --><context-param><param-name>HOME_PAGE_PATH</param-name><param-value>/home/whf/workspace-sts/codeschool/home.html</param-value></context-param>
這樣在我們在訪問首頁的時候就能明顯感覺到速度大大加快。
「Java Web」首頁靜態化的實現