[quote]
[color=gray]"URL重写,其实就是把带一大堆参数的url,变成一个看上去很规矩的url。
使用Url重写能给你网站带来哪些好处呢?
第一:有利于搜索引擎的抓取,因为现在大部分的搜索引擎对动态页面的抓取还比较弱,它们更喜欢抓取一些静态的页面。而我们现在的页面大部分的数据都是动态的显示的。这就需要我们把动态页面变成静态的页面,有利于搜索引擎的抓取
第二:让用户更容易理解,很少有用户去关心你网站的页面的地址,但对一般的大中型网站增强可读性还是必须的。这样会让你的网站更加完美
第三:隐藏技术的实现,我们可以通过Url重写可以实现技术的隐藏。不至于暴露你所采用的技术,给一些想攻击你网站的爱好者提供方便
第四:可以很方便的重用,提高网站的移植性。如果我们后台方法改动的话,可以保证前台的页面部分不用改。这样就提高了网站的移植性。
它虽然有这么多的优点,但是也有一点缺点的,因为它是通过过滤器原理来实现的,就意味着又多了一道访问,会多少影响点访问速度的,但这个可以忽略不计"
————以上一段文字内容摘自网络"[/color]
好了,接下来就是实际着手了。首先是web.xml文件的配置:
在WEB-INF下新建一个urlrewrite.xml文件,配置urlrewrite.xml如下:
接下来可以先导包,jar包在下面的附件里面有。将其解压,将得到的urlrewrite-3.2.0.jar文件拷贝到WEB-INF目录下的lib文件夹中,为了消除urlrewrite.xml配置中的警告,可顺便将urlrewrite3.2.dtd拷贝到WEB-INF目录下的lib文件夹中。
接下来是过滤器的实现类:
新建两个测试jsp文件:
1.test.jsp
2.page.jsp
如果想访问test.jsp,在浏览器中输入:
http://localhost:Tomcat端口/项目名/test.html 即可。
如果想访问page.jsp,在浏览器中输入:
http://localhost:Tomcat端口/项目名/page/fanzhongyun.html 即可。
其中,/page/后面的字符串"fanzhongyun"是要传递的参数
[/quote]
[color=gray]"URL重写,其实就是把带一大堆参数的url,变成一个看上去很规矩的url。
使用Url重写能给你网站带来哪些好处呢?
第一:有利于搜索引擎的抓取,因为现在大部分的搜索引擎对动态页面的抓取还比较弱,它们更喜欢抓取一些静态的页面。而我们现在的页面大部分的数据都是动态的显示的。这就需要我们把动态页面变成静态的页面,有利于搜索引擎的抓取
第二:让用户更容易理解,很少有用户去关心你网站的页面的地址,但对一般的大中型网站增强可读性还是必须的。这样会让你的网站更加完美
第三:隐藏技术的实现,我们可以通过Url重写可以实现技术的隐藏。不至于暴露你所采用的技术,给一些想攻击你网站的爱好者提供方便
第四:可以很方便的重用,提高网站的移植性。如果我们后台方法改动的话,可以保证前台的页面部分不用改。这样就提高了网站的移植性。
它虽然有这么多的优点,但是也有一点缺点的,因为它是通过过滤器原理来实现的,就意味着又多了一道访问,会多少影响点访问速度的,但这个可以忽略不计"
————以上一段文字内容摘自网络"[/color]
好了,接下来就是实际着手了。首先是web.xml文件的配置:
<filter>
<filter-name>UrlRewriteFilter</filter-name>
<!-- 过滤器类所在的路径: -->
<filter-class>org.tuckey.web.filters.urlrewrite.UrlRewriteFilter</filter-class>
<!-- 日志级别(可以不配置) -->
<init-param>
<param-name>logLevel</param-name>
<param-value>WARN</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>UrlRewriteFilter</filter-name>
<!-- 拦截所有url -->
<url-pattern>/*</url-pattern>
</filter-mapping>
在WEB-INF下新建一个urlrewrite.xml文件,配置urlrewrite.xml如下:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE urlrewrite PUBLIC "-//tuckey.org//DTD UrlRewrite 3.2//EN"
"\\urlrewrite3.2.dtd">
<urlrewrite>
<rule>
<!--过滤所有html伪地址(以下配置可以无参数,最多带一个参数,参数可以是中文)-->
<from>/([a-zA-Z_0-9]+)/*([a-zA-Z_0-9\u4E00-\u9FA5]*).html</from>
<!--实际url如果是jsp,那就配置.jsp,如果是servlet则配置servl的url,如果是action则配置成.do-->
<to type="forward">/$1.jsp?parameter_1=$2</to>
</rule>
</urlrewrite>
接下来可以先导包,jar包在下面的附件里面有。将其解压,将得到的urlrewrite-3.2.0.jar文件拷贝到WEB-INF目录下的lib文件夹中,为了消除urlrewrite.xml配置中的警告,可顺便将urlrewrite3.2.dtd拷贝到WEB-INF目录下的lib文件夹中。
接下来是过滤器的实现类:
package org.tuckey.web.filters.urlrewrite;
import org.tuckey.web.filters.urlrewrite.utils.Log;
import org.tuckey.web.filters.urlrewrite.utils.ModRewriteConfLoader;
import org.tuckey.web.filters.urlrewrite.utils.NumberUtils;
import org.tuckey.web.filters.urlrewrite.utils.ServerNameMatcher;
import org.tuckey.web.filters.urlrewrite.utils.StringUtils;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Date;
import java.util.Properties;
public class UrlRewriteFilter implements Filter {
private static Log log = Log.getLog(UrlRewriteFilter.class);
public static final String VERSION = "3.2.0";
public static final String DEFAULT_WEB_CONF_PATH = "/WEB-INF/urlrewrite.xml";
private UrlRewriter urlRewriter = null;
private boolean confReloadCheckEnabled = false;
private int confReloadCheckInterval = 0;
private boolean allowConfSwapViaHttp = false;
private long confLastLoad = 0;
private Conf confLastLoaded = null;
private long confReloadLastCheck = 30;
private boolean confLoadedFromFile = true;
private String confPath;
private boolean confReloadInProgress = false;
private boolean statusEnabled = true;
private String statusPath = "/rewrite-status";
private boolean modRewriteStyleConf = false;
public static final String DEFAULT_MOD_REWRITE_STYLE_CONF_PATH = "/WEB-INF/.htaccess";
private ServerNameMatcher statusServerNameMatcher;
private static final String DEFAULT_STATUS_ENABLED_ON_HOSTS = "localhost, local, 127.0.0.1";
private ServletContext context = null;
public void init(final FilterConfig filterConfig) throws ServletException {
log.debug("filter init called");
if (filterConfig == null) {
log.error("unable to init filter as filter config is null");
return;
}
log.debug("init: calling destroy just in case we are being re-inited uncleanly");
destroyActual();
context = filterConfig.getServletContext();
if (context == null) {
log.error("unable to init as servlet context is null");
return;
}
Log.setConfiguration(filterConfig);
String confReloadCheckIntervalStr = filterConfig.getInitParameter("confReloadCheckInterval");
String confPathStr = filterConfig.getInitParameter("confPath");
String statusPathConf = filterConfig.getInitParameter("statusPath");
String statusEnabledConf = filterConfig.getInitParameter("statusEnabled");
String statusEnabledOnHosts = filterConfig.getInitParameter("statusEnabledOnHosts");
String allowConfSwapViaHttpStr = filterConfig.getInitParameter("allowConfSwapViaHttp");
if (!StringUtils.isBlank(allowConfSwapViaHttpStr)) {
allowConfSwapViaHttp = "true".equalsIgnoreCase(allowConfSwapViaHttpStr);
}
if (!StringUtils.isBlank(confReloadCheckIntervalStr)) {
confReloadCheckInterval = 1000 * NumberUtils.stringToInt(confReloadCheckIntervalStr);
if (confReloadCheckInterval < 0) {
confReloadCheckEnabled = false;
log.info("conf reload check disabled");
} else if (confReloadCheckInterval == 0) {
confReloadCheckEnabled = true;
log.info("conf reload check performed each request");
} else {
confReloadCheckEnabled = true;
log.info("conf reload check set to " + confReloadCheckInterval / 1000 + "s");
}
} else {
confReloadCheckEnabled = false;
}
String modRewriteConf = filterConfig.getInitParameter("modRewriteConf");
if (!StringUtils.isBlank(modRewriteConf)) {
modRewriteStyleConf = "true".equals(StringUtils.trim(modRewriteConf).toLowerCase());
}
if (!StringUtils.isBlank(confPathStr)) {
confPath = StringUtils.trim(confPathStr);
} else {
confPath = modRewriteStyleConf ? DEFAULT_MOD_REWRITE_STYLE_CONF_PATH : DEFAULT_WEB_CONF_PATH;
}
log.debug("confPath set to " + confPath);
// status enabled (default true)
if (statusEnabledConf != null && !"".equals(statusEnabledConf)) {
log.debug("statusEnabledConf set to " + statusEnabledConf);
statusEnabled = "true".equals(statusEnabledConf.toLowerCase());
}
if (statusEnabled) {
// status path (default /rewrite-status)
if (statusPathConf != null && !"".equals(statusPathConf)) {
statusPath = statusPathConf.trim();
log.info("status display enabled, path set to " + statusPath);
}
} else {
log.info("status display disabled");
}
if (StringUtils.isBlank(statusEnabledOnHosts)) {
statusEnabledOnHosts = DEFAULT_STATUS_ENABLED_ON_HOSTS;
} else {
log.debug("statusEnabledOnHosts set to " + statusEnabledOnHosts);
}
statusServerNameMatcher = new ServerNameMatcher(statusEnabledOnHosts);
// now load conf from snippet in web.xml if modRewriteStyleConf is set
String modRewriteConfText = filterConfig.getInitParameter("modRewriteConfText");
if (!StringUtils.isBlank(modRewriteConfText)) {
ModRewriteConfLoader loader = new ModRewriteConfLoader();
Conf conf = new Conf();
loader.process(modRewriteConfText, conf);
conf.initialise();
checkConf(conf);
confLoadedFromFile = false;
} else {
loadUrlRewriter(filterConfig);
}
}
protected void loadUrlRewriter(FilterConfig filterConfig) throws ServletException {
loadUrlRewriterLocal();
}
private void loadUrlRewriterLocal() {
InputStream inputStream = context.getResourceAsStream(confPath);
URL confUrl = null;
try {
confUrl = context.getResource(confPath);
} catch (MalformedURLException e) {
log.debug(e);
}
String confUrlStr = null;
if (confUrl != null) {
confUrlStr = confUrl.toString();
}
if (inputStream == null) {
log.error("unable to find urlrewrite conf file at " + confPath);
// set the writer back to null
if (urlRewriter != null) {
log.error("unloading existing conf");
urlRewriter = null;
}
} else {
Conf conf = new Conf(context, inputStream, confPath, confUrlStr, modRewriteStyleConf);
checkConf(conf);
}
}
protected void checkConf(Conf conf) {
checkConfLocal(conf);
}
private void checkConfLocal(Conf conf) {
if (log.isDebugEnabled()) {
if (conf.getRules() != null) {
log.debug("inited with " + conf.getRules().size() + " rules");
}
log.debug("conf is " + (conf.isOk() ? "ok" : "NOT ok"));
}
confLastLoaded = conf;
if (conf.isOk() && conf.isEngineEnabled()) {
urlRewriter = new UrlRewriter(conf);
log.info("loaded (conf ok)");
} else {
if (!conf.isOk()) {
log.error("Conf failed to load");
}
if (!conf.isEngineEnabled()) {
log.error("Engine explicitly disabled in conf"); // not really an error but we want ot to show in logs
}
if (urlRewriter != null) {
log.error("unloading existing conf");
urlRewriter = null;
}
}
}
public void destroy() {
log.info("destroy called");
destroyActual();
}
public void destroyActual() {
destroyUrlRewriter();
context = null;
confLastLoad = 0;
confPath = DEFAULT_WEB_CONF_PATH;
confReloadCheckEnabled = false;
confReloadCheckInterval = 0;
confReloadInProgress = false;
}
protected void destroyUrlRewriter() {
if (urlRewriter != null) {
urlRewriter.destroy();
urlRewriter = null;
}
}
public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain)
throws IOException, ServletException {
UrlRewriter urlRewriter = getUrlRewriter(request, response, chain);
final HttpServletRequest hsRequest = (HttpServletRequest) request;
final HttpServletResponse hsResponse = (HttpServletResponse) response;
UrlRewriteWrappedResponse urlRewriteWrappedResponse = new UrlRewriteWrappedResponse(hsResponse, hsRequest,
urlRewriter);
// check for status request
if (statusEnabled && statusServerNameMatcher.isMatch(request.getServerName())) {
String uri = hsRequest.getRequestURI();
if (log.isDebugEnabled()) {
log.debug("checking for status path on " + uri);
}
String contextPath = hsRequest.getContextPath();
if (uri != null && uri.startsWith(contextPath + statusPath)) {
showStatus(hsRequest, urlRewriteWrappedResponse);
return;
}
}
boolean requestRewritten = false;
if (urlRewriter != null) {
// process the request
requestRewritten = urlRewriter.processRequest(hsRequest, urlRewriteWrappedResponse, chain);
} else {
if (log.isDebugEnabled()) {
log.debug("urlRewriter engine not loaded ignoring request (could be a conf file problem)");
}
}
// if no rewrite has taken place continue as normal
if (!requestRewritten) {
chain.doFilter(hsRequest, urlRewriteWrappedResponse);
}
}
protected UrlRewriter getUrlRewriter(ServletRequest request, ServletResponse response, FilterChain chain) {
// check to see if the conf needs reloading
if (isTimeToReloadConf()) {
reloadConf();
}
return urlRewriter;
}
public boolean isTimeToReloadConf() {
if (!confLoadedFromFile) return false;
long now = System.currentTimeMillis();
return confReloadCheckEnabled && !confReloadInProgress && (now - confReloadCheckInterval) > confReloadLastCheck;
}
public void reloadConf() {
long now = System.currentTimeMillis();
confReloadInProgress = true;
confReloadLastCheck = now;
log.debug("starting conf reload check");
long confFileCurrentTime = getConfFileLastModified();
if (confLastLoad < confFileCurrentTime) {
// reload conf
confLastLoad = System.currentTimeMillis();
log.info("conf file modified since last load, reloading");
loadUrlRewriterLocal();
} else {
log.debug("conf is not modified");
}
confReloadInProgress = false;
}
private long getConfFileLastModified() {
File confFile = new File(context.getRealPath(confPath));
return confFile.lastModified();
}
private void showStatus(final HttpServletRequest request, final ServletResponse response)
throws IOException {
log.debug("showing status");
if ( allowConfSwapViaHttp ) {
String newConfPath = request.getParameter("conf");
if ( !StringUtils.isBlank(newConfPath)) {
confPath = newConfPath;
loadUrlRewriterLocal();
}
}
Status status = new Status(confLastLoaded, this);
status.displayStatusInContainer(request);
response.setContentType("text/html; charset=UTF-8");
response.setContentLength(status.getBuffer().length());
final PrintWriter out = response.getWriter();
out.write(status.getBuffer().toString());
out.close();
}
public boolean isConfReloadCheckEnabled() {
return confReloadCheckEnabled;
}
public int getConfReloadCheckInterval() {
return confReloadCheckInterval / 1000;
}
public Date getConfReloadLastCheck() {
return new Date(confReloadLastCheck);
}
public boolean isStatusEnabled() {
return statusEnabled;
}
public String getStatusPath() {
return statusPath;
}
public boolean isLoaded() {
return urlRewriter != null;
}
public static String getFullVersionString() {
Properties props = new Properties();
String buildNumberStr = "";
try {
InputStream is = UrlRewriteFilter.class.getResourceAsStream("build.number.properties");
if ( is != null ) {
props.load(is);
String buildNumber = (String) props.get("build.number");
if (!StringUtils.isBlank(buildNumber)){
buildNumberStr = " build " + props.get("build.number");
}
}
} catch (IOException e) {
log.error(e);
}
return VERSION + buildNumberStr;
}
}
新建两个测试jsp文件:
1.test.jsp
<%@ page language="java" import="java.util.*" pageEncoding="ISO-8859-1"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Urlrewrite Test</title>
</head>
<body>
Hello!<br>This is test.jsp page ,<br>but my url is test.html <br>
</body>
</html>
2.page.jsp
<%@ page language="java" import="java.util.*" pageEncoding="ISO-8859-1"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Urlrewrite Page</title>
</head>
<body>
<%
String param = request.getParameter("parameter_1");
%>
The parameter message : ${param}
</body>
</html>
如果想访问test.jsp,在浏览器中输入:
http://localhost:Tomcat端口/项目名/test.html 即可。
如果想访问page.jsp,在浏览器中输入:
http://localhost:Tomcat端口/项目名/page/fanzhongyun.html 即可。
其中,/page/后面的字符串"fanzhongyun"是要传递的参数
[/quote]