`
conkeyn
  • 浏览: 1518229 次
  • 性别: Icon_minigender_1
  • 来自: 厦门
社区版块
存档分类
最新评论

把URL Rewriter 与 Strtus 2.0 结合使用(解决一半的问题)

阅读更多

增加一个tld,与struts 2.0.tld 放在一起,其内容如果下(跟<s:url>相当,只是名称及类名改了.):

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN" "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">
<taglib>
  <tlib-version>1.0</tlib-version>
  <jsp-version>1.2</jsp-version>
  <short-name>r</short-name>
  <uri>/urlrewriter-tags</uri>
 <tag>
    <name>urlrewrite</name>
    <tag-class>com.conkeyn.web.taglib.URLRewriterTag</tag-class>
    <body-content>JSP</body-content>
    <description><![CDATA[This tag is used to create a URL]]></description>
    <attribute>
      <name>action</name>
      <required>false</required>
      <rtexprvalue>true</rtexprvalue>
      <description><![CDATA[he action generate url for, if not using value]]></description>
    </attribute>
    <attribute>
      <name>anchor</name>
      <required>false</required>
      <rtexprvalue>true</rtexprvalue>
      <description><![CDATA[The anchor for this URL]]></description>
    </attribute>
    <attribute>
      <name>encode</name>
      <required>false</required>
      <rtexprvalue>true</rtexprvalue>
      <description><![CDATA[Whether to encode parameters]]></description>
    </attribute>
    <attribute>
      <name>id</name>
      <required>false</required>
      <rtexprvalue>true</rtexprvalue>
      <description><![CDATA[id for referencing element. For UI and form tags it will be used as HTML id attribute]]></description>
    </attribute>
    <attribute>
      <name>includeContext</name>
      <required>false</required>
      <rtexprvalue>true</rtexprvalue>
      <description><![CDATA[Whether actual context should be included in url]]></description>
    </attribute>
    <attribute>
      <name>includeParams</name>
      <required>false</required>
      <rtexprvalue>true</rtexprvalue>
      <description><![CDATA[The includeParams attribute may have the value 'none', 'get' or 'all']]></description>
    </attribute>
    <attribute>
      <name>method</name>
      <required>false</required>
      <rtexprvalue>true</rtexprvalue>
      <description><![CDATA[The method of action to use]]></description>
    </attribute>
    <attribute>
      <name>namespace</name>
      <required>false</required>
      <rtexprvalue>true</rtexprvalue>
      <description><![CDATA[The namespace to use]]></description>
    </attribute>
    <attribute>
      <name>portletMode</name>
      <required>false</required>
      <rtexprvalue>true</rtexprvalue>
      <description><![CDATA[The resulting portlet mode]]></description>
    </attribute>
    <attribute>
      <name>portletUrlType</name>
      <required>false</required>
      <rtexprvalue>true</rtexprvalue>
      <description><![CDATA[Specifies if this should be a portlet render or action url]]></description>
    </attribute>
    <attribute>
      <name>scheme</name>
      <required>false</required>
      <rtexprvalue>true</rtexprvalue>
      <description><![CDATA[Set scheme attribute]]></description>
    </attribute>
    <attribute>
      <name>value</name>
      <required>false</required>
      <rtexprvalue>true</rtexprvalue>
      <description><![CDATA[The target value to use, if not using action]]></description>
    </attribute>
    <attribute>
      <name>windowState</name>
      <required>false</required>
      <rtexprvalue>true</rtexprvalue>
      <description><![CDATA[The resulting portlet window state]]></description>
    </attribute>
  </tag>
 
</taglib>

 

增加代码(其实是复制原有<s:url>的类然后进行修改):

package com.conkeyn.web.taglib;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts2.components.Component;
import org.apache.struts2.views.jsp.ComponentTagSupport;

import com.opensymphony.xwork2.util.ValueStack;

/**
 * title: 重新定义<s:url>标签,使之与URL Rewriter结合使用。
 * 
 * @时间 2008-9-24:下午02:16:56
 */
public class URLRewriterTag extends ComponentTagSupport {

	private static final long serialVersionUID = 1722460444125206226L;

	protected String includeParams;
	protected String scheme;
	protected String value;
	protected String action;
	protected String namespace;
	protected String method;
	protected String encode;
	protected String includeContext;
	protected String escapeAmp;
	protected String portletMode;
	protected String windowState;
	protected String portletUrlType;
	protected String anchor;
	protected String forceAddSchemeHostAndPort;

	public Component getBean(ValueStack stack, HttpServletRequest req,
			HttpServletResponse res) {
		return new URLRewriter(stack, req, res);
	}

	protected void populateParams() {
		super.populateParams();
		URLRewriter url = (URLRewriter) component;
		url.setIncludeParams(includeParams);
		url.setScheme(scheme);
		url.setValue(value);
		url.setMethod(method);
		url.setNamespace(namespace);
		url.setAction(action);
		url.setPortletMode(portletMode);
		url.setPortletUrlType(portletUrlType);
		url.setWindowState(windowState);
		url.setAnchor(anchor);
		if (encode != null) {
			url.setEncode(Boolean.valueOf(encode).booleanValue());
		}
		if (includeContext != null) {
			url.setIncludeContext(Boolean.valueOf(includeContext)
					.booleanValue());
		}
		if (escapeAmp != null) {
			url.setEscapeAmp(Boolean.valueOf(escapeAmp).booleanValue());
		}
		if (forceAddSchemeHostAndPort != null) {
			url.setForceAddSchemeHostAndPort(Boolean.valueOf(
					forceAddSchemeHostAndPort).booleanValue());
		}
	}

	public void setEncode(String encode) {
		this.encode = encode;
	}

	public void setIncludeContext(String includeContext) {
		this.includeContext = includeContext;
	}

	public void setEscapeAmp(String escapeAmp) {
		this.escapeAmp = escapeAmp;
	}

	public void setIncludeParams(String name) {
		includeParams = name;
	}

	public void setAction(String action) {
		this.action = action;
	}

	public void setNamespace(String namespace) {
		this.namespace = namespace;
	}

	public void setMethod(String method) {
		this.method = method;
	}

	public void setScheme(String scheme) {
		this.scheme = scheme;
	}

	public void setValue(String value) {
		this.value = value;
	}

	public void setPortletMode(String portletMode) {
		this.portletMode = portletMode;
	}

	public void setPortletUrlType(String portletUrlType) {
		this.portletUrlType = portletUrlType;
	}

	public void setWindowState(String windowState) {
		this.windowState = windowState;
	}

	public void setAnchor(String anchor) {
		this.anchor = anchor;
	}

	public void setForceAddSchemeHostAndPort(String forceAddSchemeHostAndPort) {
		this.forceAddSchemeHostAndPort = forceAddSchemeHostAndPort;
	}
}

 

package com.conkeyn.web.taglib;

import java.io.IOException;
import java.io.InputStream;
import java.io.Writer;
import java.net.URL;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringEscapeUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.struts2.StrutsConstants;
import org.apache.struts2.StrutsException;
import org.apache.struts2.components.Component;
import org.apache.struts2.dispatcher.Dispatcher;
import org.apache.struts2.portlet.context.PortletActionContext;
import org.apache.struts2.portlet.util.PortletUrlHelper;
import org.apache.struts2.views.annotations.StrutsTag;
import org.apache.struts2.views.annotations.StrutsTagAttribute;
import org.apache.struts2.views.util.UrlHelper;
import org.tuckey.web.filters.urlrewrite.Conf;
import org.tuckey.web.filters.urlrewrite.UrlRewriteWrappedResponse;
import org.tuckey.web.filters.urlrewrite.UrlRewriter;

import com.opensymphony.xwork2.inject.Inject;
import com.opensymphony.xwork2.util.ValueStack;

@StrutsTag(name = "urlrewrite", tldTagClass = "com.conkeyn.web.taglib.URLRewriter", description = "This tag is used to create a rewrited URL ")
public class URLRewriter extends Component {
	private static final Log LOG = LogFactory.getLog(URLRewriter.class);

	public static final String NONE = "none";
	public static final String GET = "get";
	public static final String ALL = "all";

	private HttpServletRequest req;
	private HttpServletResponse res;

	protected String includeParams;
	protected String scheme;
	protected String value;
	protected String action;
	protected String namespace;
	protected String method;
	protected boolean encode = true;
	protected boolean includeContext = true;
	protected boolean escapeAmp = true;
	protected String portletMode;
	protected String windowState;
	protected String portletUrlType;
	protected String anchor;
	protected boolean forceAddSchemeHostAndPort;
	protected String urlIncludeParams;
	protected ExtraParameterProvider extraParameterProvider;

	public URLRewriter(ValueStack stack, HttpServletRequest req,
			HttpServletResponse res) {
		super(stack);
		this.req = req;
		this.res = res;
	}

	@Inject(StrutsConstants.STRUTS_URL_INCLUDEPARAMS)
	public void setUrlIncludeParams(String urlIncludeParams) {
		this.urlIncludeParams = urlIncludeParams;
	}

	@Inject(required = false)
	public void setExtraParameterProvider(ExtraParameterProvider provider) {
		this.extraParameterProvider = provider;
	}

	public boolean start(Writer writer) {
		boolean result = super.start(writer);

		if (value != null) {
			value = findString(value);
		}
		try {
			String includeParams = (urlIncludeParams != null ? urlIncludeParams
					.toLowerCase() : GET);
			if (this.includeParams != null) {
				includeParams = findString(this.includeParams);
			}
			if (NONE.equalsIgnoreCase(includeParams)) {
				mergeRequestParameters(value, parameters, Collections.EMPTY_MAP);
			} else if (ALL.equalsIgnoreCase(includeParams)) {
				mergeRequestParameters(value, parameters, req.getParameterMap());
				includeGetParameters();
				includeExtraParameters();
			} else if (GET.equalsIgnoreCase(includeParams)
					|| (includeParams == null && value == null && action == null)) {
				includeGetParameters();
				includeExtraParameters();
			} else if (includeParams != null) {
				LOG
						.warn("Unknown value for includeParams parameter to URL tag: "
								+ includeParams);
			}
		} catch (Exception e) {
			LOG.warn("Unable to put request parameters ("
					+ req.getQueryString() + ") into parameter map.", e);
		}
		return result;
	}

	private void includeExtraParameters() {
		if (extraParameterProvider != null) {
			mergeRequestParameters(value, parameters, extraParameterProvider
					.getExtraParameters());
		}
	}

	private void includeGetParameters() {
		if (!(Dispatcher.getInstance().isPortletSupportActive() && PortletActionContext
				.isPortletRequest())) {
			String query = extractQueryString();
			mergeRequestParameters(value, parameters, UrlHelper
					.parseQueryString(query));
		}
	}

	private String extractQueryString() {
		// Parse the query string to make sure that the parameters come from the
		// query, and not some posted data
		String query = req.getQueryString();
		if (query == null) {
			query = (String) req
					.getAttribute("javax.servlet.forward.query_string");
		}
		if (query != null) {
			// Remove possible #foobar suffix
			int idx = query.lastIndexOf('#');

			if (idx != -1) {
				query = query.substring(0, idx);
			}
		}
		return query;
	}

	public boolean end(Writer writer, String body) {
		String scheme = req.getScheme();

		if (this.scheme != null) {
			scheme = this.scheme;
		}

		String result;
		if (value == null && action != null) {
			if (Dispatcher.getInstance().isPortletSupportActive()
					&& PortletActionContext.isPortletRequest()) {
				result = PortletUrlHelper.buildUrl(action, namespace, method,
						parameters, portletUrlType, portletMode, windowState);
			} else {
				result = determineActionURL(action, namespace, method, req,
						res, parameters, scheme, includeContext, encode,
						forceAddSchemeHostAndPort, escapeAmp);
			}
		} else {
			if (Dispatcher.getInstance().isPortletSupportActive()
					&& PortletActionContext.isPortletRequest()) {
				result = PortletUrlHelper.buildResourceUrl(value, parameters);
			} else {
				String _value = value;

				// We don't include the request parameters cause they would have
				// been
				// prioritised before this [in start(Writer) method]
				if (_value != null && _value.indexOf("?") > 0) {
					_value = _value.substring(0, _value.indexOf("?"));
				}
				result = UrlHelper.buildUrl(_value, req, res, parameters,
						scheme, includeContext, encode,
						forceAddSchemeHostAndPort, escapeAmp);
			}
		}
		if (anchor != null && anchor.length() > 0) {
			result += '#' + anchor;
		}
		String id = getId();
		if (id != null) {
			getStack().getContext().put(id, result);
			// add to the request and page scopes as well
			req.setAttribute(id, result);
		} else {
			try {
				result = rewriteURL(result, req, res);
				writer.write(result);
			} catch (IOException e) {
				throw new StrutsException("IOError: " + e.getMessage(), e);
			} catch (Exception e) {
				throw new StrutsException("Error: " + e.getMessage(), e);
			}
		}
		return super.end(writer, body);
	}

	/**
	 * 加入URL重写功能
	 * 
	 * @param url
	 * @param request
	 * @param response
	 * @return
	 * @throws Exception
	 */
	public String rewriteURL(String url, HttpServletRequest request,
			HttpServletResponse response) throws Exception {
		UrlRewriter urlRewriter = null;
		Conf conf = null;
		String DEFAULT_WEB_CONF_PATH = "/WEB-INF/classes/urlrewrite.xml";
		ServletContext context = request.getSession().getServletContext();
		InputStream inputStream = context
				.getResourceAsStream(DEFAULT_WEB_CONF_PATH);
		URL confUrl = null;
		confUrl = context.getResource(DEFAULT_WEB_CONF_PATH);

		String confUrlStr = null;
		if (confUrl != null) {
			confUrlStr = confUrl.toString();
		}
		if (inputStream == null) {
			System.err.println("unable to find urlrewrite conf file at "
					+ DEFAULT_WEB_CONF_PATH);
			// set the writer back to null
			if (urlRewriter != null) {
				System.err.println("unloading existing conf");
				urlRewriter = null;
			}

		} else {
			conf = new Conf(context, inputStream, DEFAULT_WEB_CONF_PATH,
					confUrlStr, false);
			conf.initialise();
		}
		urlRewriter = new UrlRewriter(conf);
		UrlRewriteWrappedResponse urlRewriteWrappedResponse = new UrlRewriteWrappedResponse(
				response, request, urlRewriter);
		// 把HTML表示符转换成正常的字符
		url = StringEscapeUtils.unescapeHtml(url);
		// 使用URL Rewriter 执行转换
		url = urlRewriteWrappedResponse.encodeURL(url);
		// 再转换成HTML表示符
		url = StringEscapeUtils.escapeHtml(url);
		return url;
	}

	@StrutsTagAttribute(description = "The includeParams attribute may have the value 'none', 'get' or 'all'", defaultValue = "get")
	public void setIncludeParams(String includeParams) {
		this.includeParams = includeParams;
	}

	@StrutsTagAttribute(description = "Set scheme attribute")
	public void setScheme(String scheme) {
		this.scheme = scheme;
	}

	@StrutsTagAttribute(description = "The target value to use, if not using action")
	public void setValue(String value) {
		this.value = value;
	}

	@StrutsTagAttribute(description = "The action to generate the URL for, if not using value")
	public void setAction(String action) {
		this.action = action;
	}

	@StrutsTagAttribute(description = "The namespace to use")
	public void setNamespace(String namespace) {
		this.namespace = namespace;
	}

	@StrutsTagAttribute(description = "The method of action to use")
	public void setMethod(String method) {
		this.method = method;
	}

	@StrutsTagAttribute(description = "Whether to encode parameters", type = "Boolean", defaultValue = "true")
	public void setEncode(boolean encode) {
		this.encode = encode;
	}

	@StrutsTagAttribute(description = "Whether actual context should be included in URL", type = "Boolean", defaultValue = "true")
	public void setIncludeContext(boolean includeContext) {
		this.includeContext = includeContext;
	}

	@StrutsTagAttribute(description = "The resulting portlet mode")
	public void setPortletMode(String portletMode) {
		this.portletMode = portletMode;
	}

	@StrutsTagAttribute(description = "The resulting portlet window state")
	public void setWindowState(String windowState) {
		this.windowState = windowState;
	}

	@StrutsTagAttribute(description = "Specifies if this should be a portlet render or action URL. Default is \"render\". To create an action URL, use \"action\".")
	public void setPortletUrlType(String portletUrlType) {
		this.portletUrlType = portletUrlType;
	}

	@StrutsTagAttribute(description = "The anchor for this URL")
	public void setAnchor(String anchor) {
		this.anchor = anchor;
	}

	@StrutsTagAttribute(description = "Specifies whether to escape ampersand (&) to (&amp;) or not", type = "Boolean", defaultValue = "true")
	public void setEscapeAmp(boolean escapeAmp) {
		this.escapeAmp = escapeAmp;
	}

	@StrutsTagAttribute(description = "Specifies whether to force the addition of scheme, host and port or not", type = "Boolean", defaultValue = "false")
	public void setForceAddSchemeHostAndPort(boolean forceAddSchemeHostAndPort) {
		this.forceAddSchemeHostAndPort = forceAddSchemeHostAndPort;
	}

	
	protected void mergeRequestParameters(String value, Map parameters,
			Map contextParameters) {

		Map mergedParams = new LinkedHashMap(contextParameters);

		// Merge contextParameters (from current request) with parameters
		// specified in value attribute
		// eg. value="someAction.action?id=someId&venue=someVenue"
		// where the parameters specified in value attribute takes priority.

		if (value != null && value.trim().length() > 0
				&& value.indexOf("?") > 0) {
			mergedParams = new LinkedHashMap();

			String queryString = value.substring(value.indexOf("?") + 1);

			mergedParams = UrlHelper.parseQueryString(queryString);
			for (Iterator iterator = contextParameters.entrySet().iterator(); iterator
					.hasNext();) {
				Map.Entry entry = (Map.Entry) iterator.next();
				Object key = entry.getKey();

				if (!mergedParams.containsKey(key)) {
					mergedParams.put(key, entry.getValue());
				}
			}
		}

		// Merge parameters specified in value attribute
		// eg. value="someAction.action?id=someId&venue=someVenue"
		// with parameters specified though param tag
		// eg. <param name="id" value="%{'someId'}" />
		// where parameters specified through param tag takes priority.

		for (Iterator iterator = mergedParams.entrySet().iterator(); iterator
				.hasNext();) {
			Map.Entry entry = (Map.Entry) iterator.next();
			Object key = entry.getKey();

			if (!parameters.containsKey(key)) {
				parameters.put(key, entry.getValue());
			}
		}
	}

	public static interface ExtraParameterProvider {
		public Map getExtraParameters();
	}
}

rewriteURL()方法做出来挺庸肿的,谁能想出更好的办法.多多指教哦.

 

以上的代码功能是<outbound-rule>使用的.<rule>的问题目前还没有解决.正待解决....

 

分享到:
评论
2 楼 conkeyn 2009-02-12  
libin2722 写道

漂亮,我项目已经做好了,现在正在搞URLRewrite,有点头大,就是所有已经写好的连接都需要重新改,改成静态连接,不知道主楼有没有什么好办法

什么静态的?应该是在配置里头吧?
1 楼 libin2722 2009-02-06  
漂亮,我项目已经做好了,现在正在搞URLRewrite,有点头大,就是所有已经写好的连接都需要重新改,改成静态连接,不知道主楼有没有什么好办法

相关推荐

    url_rewriter

    * Download http://cesars.users.phpclasses.org/url_rewriter * Edit url_handler.php * Add a new rule $url-&gt;add_rule("foo.php","/entry-[:number1].html"); * Change all your links foo....

    [其他类别]UrlRewriter Java v2.0 RC1_urlrewriterjava.zip

    5. **集成与使用**: - 开发者需要在Web应用的配置文件中引入UrlRewriter的过滤器,设置相应的配置路径。 - 使用提供的API或者XML配置文件定义重写规则。 - 在服务器启动后,UrlRewriter会自动处理所有入站请求,...

    ReWriter

    综合以上分析,"ReWriter"程序的问题可能与URL重写规则在IIS中的处理、环境配置差异或权限设置相关。解决这个问题需要深入理解IIS的工作原理、ASP.NET的部署以及URL重写机制。通过细致的调试和对比分析,通常可以...

    UrlRewritingNet_2.0

    总之,`UrlRewritingNet_2.0` 是一个针对.NET Framework 2.0和VS2008的URL重写解决方案,对于想要优化网站结构和提升SEO效果的开发者来说,是一个有价值的工具。通过学习和应用这个库,开发者可以实现更优雅、更利于...

    rewriter 离线版.rar

    总的来说,这个压缩包提供了在IIS服务器上安装和配置URL Rewrite工具的完整解决方案,包括离线安装程序和详细的使用指南,对于管理和优化基于IIS的网站的URL结构非常有帮助。用户可以通过下载、解压并按照说明进行...

    Rabbit URL Rewriter-crx插件

    - 您可以使用“从”URL模式中的“正则表达式匹配”组和“目标”URL模式中的“从”ull模式中的匹配组。 示例:如果“来自”URL是:https://example.com/ (.*)您可以设置“目标”URL模式,如...

    iis rewriter 重写URL

    可以使用正则表达式来匹配特定的URL模式。 3. **重写模式**: 确定如何重写匹配到的URL。可以设置一个新的URL,也可以是内部重定向,即服务器内部处理,但对外显示的URL保持不变。 4. **条件**: 可选地,你可以添加...

    UrlRewriter2_51

    《UrlRewriter2_51:理解与应用URL重写技术》 UrlRewriter2_51是一款专门用于处理和管理URL重写的工具,它基于ASP.NET环境,为开发者提供了强大的URL管理功能,使得网站的URL更加友好、简洁且易于理解。在本文中,...

    URL Rewriter-crx插件

    URL Rewriter在导航到URL之前通过一组规则编辑某些URL,无论是否键入或链接。规则由捕获组中指定的正则表达式,捕获组号替换为替换,以及该组的替换文本。单击“链接”或在地址栏中键入URL时,将针对每个规则检

    IIRF_URLRewrite基于IIS层的IIRF实现URL重写+完美解决POSTBACK问题

    然而,URL重写可能会导致POSTBACK时的问题,因为服务器可能无法识别原始的URL,这通常与会话状态管理、回退按钮和书签功能有关。 IIRF_URLRewrite提供的解决方案是通过配置规则来确保POSTBACK请求能够正确地路由到...

    urlrewriter

    这样,用户在浏览器中看到的URL与服务器实际处理的URL不同,提升了用户体验并可能提高网站的搜索引擎排名。 在IIS(Internet Information Services)中安装`URLRewriter`,你需要进行以下步骤: 1. 下载并安装`...

    url重写的方法~很详细

    ### URL重写方法详解 #### 一、URL重写的概念与意义 URL重写是一种将一个URL转换为另一个URL的技术,常用于隐藏真实的路径、优化...通过使用MS URL Rewriter或其他内置方法,开发者可以轻松地实现复杂的URL重写需求。

    Java URLRewriter使用小节

    源码中包含了规则解析、匹配、执行等核心逻辑,这有助于定制化开发和解决遇到的问题。 总之,Java URLRewriter是Web开发中的一个重要工具,它可以帮助我们构建更加优雅、易于理解和维护的URL结构,同时也提供了灵活...

    URL重写DEMOURL重写DEMO

    在"URL重写DEMO"中,我们可能还会遇到如何处理查询字符串、如何处理路径中的参数、如何处理应用程序内部的路由等实际问题。开发者可能会创建不同的重写规则来处理不同类型的URL,确保每个请求都能被正确地重定向到...

    IIS反向代理工具包

    1.在Windows Server 2012 R2上 安装ARR,URL Rewriter组件。... URL Rewriter2.0(For IIS7.0,支持Win 2012 R2)直接安装即可。 依次安装完如上组件后,可以在IIS控制台中看到 ARR 和 URL重写 安装成功

    Url-Rewriter:允许您从 Sitecore 客户端内管理 URL 重写规则的 Sitecore 模块

    安装后: 可以在/sitecore/System/Modules/URL Rewriter rules下找到用于存储重写规则的默认文件夹。 在发布功能区中可以找到一个新按钮,用于清除模块的缓存。 安装成功后,您需要设置自己的重写规则。用法重写...

    url重写工具,重写二级域名

    描述中的“.net重写url的工具”进一步确认了我们正在讨论的是一个专门针对.NET环境的URL重写解决方案。 URL重写在现代Web开发中扮演着关键角色,因为它有助于提高用户体验,改善搜索引擎优化(SEO),并使网站保持...

    新云4.0伪静态规则和绿色Rewriter

    `软件说明.txt`应该包含新云4.0的使用指南和详细功能解释,包括如何设置和使用伪静态规则,以及`Rewriter`的配置方法。建议仔细阅读这个文件,以便更好地理解和利用新云4.0的功能。 `flydown.net.url`可能是一个...

Global site tag (gtag.js) - Google Analytics