zoukankan      html  css  js  c++  java
  • 「Java Web」主页静态化的实现

    一个站点的主页一般不会频繁变动,而大多数用户在訪问站点时不过浏览一下主页(未登陆)。然后就离开了。对于这类訪问请求。假设每次都要通过查询数据库来显示主页的话,显然会给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;
    
    	@Override
    	public void destroy() {
    
    	}
    
    	@Override
    	public 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返回给client
    		ServletOutputStream 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();
    	}
    
    	@Override
    	public 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>


    这样在我们在訪问主页的时候就能明显感觉到速度大大加快。
  • 相关阅读:
    Navicat Premium15安装与激活
    JDK13.0.1安装与环境变量的配置(Win10平台为例)
    Linux系统手动安装Firefox浏览器
    Debian 9.5 解决中文显示乱码
    debian 安装后需做的几件事
    Windows10 Linux子系统安装图形化界面的两种方法及其对比
    线程池大小设置,CPU的核心数、线程数的关系和区别,同步与堵塞完全是两码事
    Java学习笔记八(反射)
    高速排序法(一)
    Java深入
  • 原文地址:https://www.cnblogs.com/llguanli/p/6731492.html
Copyright © 2011-2022 走看看