基于urlrewrite的网页静态化解决方案

   在互连网应用中,提高页面展示速度和针对搜索引擎优化都是必须要考虑和解决的问题,而解决这两个问题就必须要尽可能实现页面静态化和URL重写.静态化的页面是提高服务器性能最有效的手段之一了,而URL重写又是SEO优化的首要步骤.
   URL重写大部分都在http服务器端操作如apache,但是apache又不能根据参数的不同缓存不同的页面,所以大部分jsp页面都无法被缓存。Google之后发现有个urlrewrite可以在tomcat中重写url, 看过源码之后,决定改造一下,在重写url的同时将内容缓存至磁盘或内存,这样不是一举两得吗。
    (后来又发现,原来还有更好的解决方法 http://ariesmonster.iteye.com/blog/807666) 
主要代码如下:
public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain chain) throws IOException, ServletException {
		HttpServletRequest httpRequest = (HttpServletRequest) request;
		HttpServletResponse httpResponse = (HttpServletResponse) response;

		String originalUrl = httpRequest.getRequestURI();
		if (originalUrl.startsWith(contextPath)) {
			originalUrl = originalUrl.substring(contextPath.length());
		}
		LOG.info("Handle request: {}", originalUrl);
		originalUrl = URLDecoder.decode(originalUrl, "UTF-8");

		Cache cache = memoryCache.get(originalUrl);
		if (cache != null && cache.isValid()) {
			LOG.info("Hit memory cache for request {}", originalUrl);
			response.setContentType("text/html;charset=utf-8");
			response.getWriter().print(cache.getContent());
			return;
		} else if (cache != null) {
			CachedResponse cachedResponse = new CachedResponse(httpResponse);
			RequestDispatcher rd = request.getRequestDispatcher(cache
					.getTargetUrl());
			rd.forward(httpRequest, cachedResponse);

			if (!cachedResponse.isCommitted()
					&& cachedResponse.getStatus() == 200) {
				String responseBody = cachedResponse.getContent();
				response.setContentType("text/html;charset=utf-8");
				response.getWriter().print(responseBody);
				LOG.info("Update memory cache for request {}", cache
						.getTargetUrl());
				cache.setContent(responseBody);
				memoryCache.put(originalUrl, cache);
			}
			return;
		}

		String targetUrl = null;
		Rule matchedRule = null;
		for (Rule rule : rules) {
			targetUrl = rule.execute(originalUrl);
			if (targetUrl != null) {
				matchedRule = rule;
				break;
			}
		}

		if (targetUrl == null) {
			LOG.info("No rule matched request: {}", originalUrl);
			chain.doFilter(request, response);
			return;
		} else {
			short cacheType = matchedRule.getCacheType();
			if (cacheType == 0) {
				LOG.info("Rewrite request {} to {}", originalUrl, targetUrl);
				RequestDispatcher rd = request.getRequestDispatcher(targetUrl);
				rd.forward(request, response);
				return;
			} else if (cacheType == 1) {
				File cacheFile = new File(cacheDir, originalUrl);

				if (isValid(cacheFile, matchedRule.getTimeout())) {
					LOG.info("Hit disk cache for request {}", targetUrl);
					response.setContentType("text/html;charset=utf-8");
					String cacheContent = FileUtils.readFileToString(cacheFile,
							"UTF-8");
					response.getWriter().print(cacheContent);
					return;
				} else {
					CachedResponse cachedResponse = new CachedResponse(
							httpResponse);
					RequestDispatcher rd = request
							.getRequestDispatcher(targetUrl);
					rd.forward(httpRequest, cachedResponse);

					if (!response.isCommitted()
							&& cachedResponse.getStatus() == 200) {
						String responseBody = cachedResponse.getContent();
						response.setContentType("text/html;charset=utf-8");
						response.getWriter().print(responseBody);
						LOG.info("Update disk cache for request {}", targetUrl);
						FileUtils.writeStringToFile(cacheFile, responseBody,
								"UTF-8");
					}

					return;
				}
			} else if (cacheType == 2) {
				CachedResponse cachedResponse = new CachedResponse(httpResponse);
				RequestDispatcher rd = request.getRequestDispatcher(targetUrl);
				rd.forward(httpRequest, cachedResponse);

				if (!response.isCommitted()
						&& cachedResponse.getStatus() == 200) {
					String responseBody = cachedResponse.getContent();
					response.setContentType("text/html;charset=utf-8");
					response.getWriter().print(responseBody);
					LOG.info("Create memory cache for request {}", targetUrl);
					Cache memCache = new Cache();
					memCache.setTimeOut(matchedRule.getTimeout());
					memCache.setContent(responseBody);
					memCache.setTargetUrl(targetUrl);
					memoryCache.put(originalUrl, memCache);
				}

				return;
			}
		}
	}

使用也很简单:
在web.xml中增加
<filter>
		<filter-name>HtmlCache</filter-name>
		<filter-class>com.hanvon.htmlcache.HtmlCacheFilter</filter-class>
		<init-param>
			<param-name>logLevel</param-name>
			<param-value>DEBUG</param-value>
		</init-param>
		<init-param>
			<param-name>cacheDir</param-name>
			<param-value>/data/htmlcache/</param-value>
		</init-param>
	</filter>
	<filter-mapping>
		<filter-name>HtmlCache</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>

在WEB-INF下新建配置文件htmlcache.xml
<?xml version="1.0" encoding="utf-8"?>
<urlrewrite>
	<rule>
		<from>/index.html</from>
		<to>/home/index.html</to>
		<cache type="memory" timeout="30" />
                  <!--缓存至内存,刷新间隔30分钟-->
	</rule>
	<rule>
		<from>/category/([0-9]+).html</from>
		<to>/getBookListByCategory.action?clickedCategoryId=$1</to>
		<cache type="memory" timeout="60" />
                  <!--缓存至内存,刷新间隔60分钟-->
	</rule>
	<rule>
		<from>/book/([0-9]+).html</from>
		<to>/showBookDetail.action?bookId=$1</to>
		<cache type="disk" timeout="10" />
                  <!--缓存至磁盘,刷新间隔10分钟-->
	</rule>
	<rule>
		<from>/search/(.*)/(.*).html</from>
		<to>/searchBookByConditionLike.action?searchName=$2&amp;searchType=$1</to>
		<cache type="disk" timeout="60" />
	</rule>
</urlrewrite>
   
改造之后的urlrewrite可以将/book/234.html映射为/book.jsp?id=234,并且缓存至磁盘或内存,测试结果还不错,简单实用

猜你喜欢

转载自ariesmonster.iteye.com/blog/804023
今日推荐