使用 Java WebFilter 删除标签
Removing Hashtag using Java WebFilter
我在urlrewrite.xml中有如下配置:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE urlrewrite PUBLIC "-//tuckey.org//DTD UrlRewrite 4.0//EN" "http://www.tuckey.org/res/dtds/urlrewrite4.0.dtd">
<urlrewrite use-query-string="true">
<rule>
<from>^(/event/showEventList)(\.{1})(\bhtm\b|\bhtml\b)(\?{0,1})([a-zA-Z0-9-_=&]{0,}+)(#{0,1})([a-zA-Z0-9-_=&]{0,}+)$</from>
<to type="redirect" last="true">/events</to>
</rule>
</urlrewrite>
正则表达式^(/event/showEventList)(\.{1})(\bhtm\b|\bhtml\b)(\?{0,1})([a-zA-Z0-9-_=&]{0,}+)(#{0,1})([a-zA-Z0-9-_=&]{0,}+)$
有7组,分别是:
(/event/showEventList)
:匹配 /event/showEventList
(\.{1})
:匹配单个点 (.)
(\bhtm\b|\bhtml\b)
: 只匹配 htm 或 html
(\?{0,1})
:匹配可能出现零个或一个的问号 (?)
([a-zA-Z0-9-_=&]{0,}+)
:匹配可以出现零次或多次的查询字符串
(#{0,1})
:匹配可以出现零个或一个的主题标签 (#)
([a-zA-Z0-9-_=&]{0,}+)
:匹配出现零次或多次的片段
如果我用测试 URL: /event/showEventList.html?pageNumber=1#key=val
测试此配置,我希望重定向的 URL 会是 /events?pageNumber=1
,但我得到 /events?pageNumber=1#key=val
我有一个代码片段来测试它,它是:
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class UrlRewriterRegexTest {
public static void main(String[] args) {
String input = "/event/showEventList.html?pageNumber=1#key=val";
String regex = "^(/event/showEventList)(\.{1})(\bhtm\b|\bhtml\b)(\?{0,1})([a-zA-Z0-9-_=&]{0,}+)(#{0,1})([a-zA-Z0-9-_=&]{0,}+)$";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(input);
System.out.println(matcher.replaceFirst("/events"));
}
}
它输出到:/events?pageNumber=1
.
任何指针都会很有帮助。
我会稍微简化一下表达式。
- 转义斜杠,因为它们通常用作正则表达式的分隔符
(\/event\/showEventList)
- 删除多余的量词
(\.)
- 缩短 html 字符串测试
(htm(l)?)
- 小心,这会扰乱您的捕获组编号
- 删除
html
周围的单词边界检查
- 使用
?
代替{0,1}
- 使用
*
代替{0,}
- 删除所有格量词(我不明白你为什么需要它)
- 忽略
#
之后的所有内容,你的替换似乎不需要它
这给了我们 ^(\/event\/showEventList)(\.)(htm(l)?)(\??)([a-zA-Z0-9-_=&]+)*#(.+)$
将您的示例替换为 /events?pageNumber=1
要玩转,请参阅 https://regexr.com/4otp7
我已经简化了表达式,这是有效的解决方案
<from>^(\/event\/showEventList\.html?)(\?[a-zA-Z0-9-_=&]*)\#.*$</from>
<to type="redirect" last="true">/events</to>
这将匹配任何内容,并获取从查询字符串开头到第一次出现 #
的所有内容
解释:
第 1 组:匹配 url /event/showEventList.html 或 /event/showEventList.htm
第 2 组:匹配 o 到 many 之间的所有查询字符串,直到第一次出现 #
第 2 组是您要用于重定向并忽略# 之后的任何内容的字符串,包括#
示例:
我正在回答我自己的问题,以便将来如果其他人遇到同样的问题,这个答案可以帮助他。
与UrlRewriteFilter
框架无关。通过启用此框架的调试日志,我发现它在应用定义的规则之前收到的 URL 没有 URL Hash(#)。从其他 SO 答案以及通过分析浏览器的网络流量,我看到浏览器不会将 URL 片段发送到服务器,因此它在 HttpServletRequest
中不可用。这就是正则表达式不起作用的原因。
自此 hash is available in the client browser and thanks to HTML5 History API 我可以使用 JavaScript:
解决问题
<script type="text/javascript">
window.addEventListener('DOMContentLoaded', (event) => {
const url = new URL(window.location);
url.hash = '';
history.replaceState(null, document.title, url);
});
</script>
我在urlrewrite.xml中有如下配置:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE urlrewrite PUBLIC "-//tuckey.org//DTD UrlRewrite 4.0//EN" "http://www.tuckey.org/res/dtds/urlrewrite4.0.dtd">
<urlrewrite use-query-string="true">
<rule>
<from>^(/event/showEventList)(\.{1})(\bhtm\b|\bhtml\b)(\?{0,1})([a-zA-Z0-9-_=&]{0,}+)(#{0,1})([a-zA-Z0-9-_=&]{0,}+)$</from>
<to type="redirect" last="true">/events</to>
</rule>
</urlrewrite>
正则表达式^(/event/showEventList)(\.{1})(\bhtm\b|\bhtml\b)(\?{0,1})([a-zA-Z0-9-_=&]{0,}+)(#{0,1})([a-zA-Z0-9-_=&]{0,}+)$
有7组,分别是:
(/event/showEventList)
:匹配 /event/showEventList(\.{1})
:匹配单个点 (.)(\bhtm\b|\bhtml\b)
: 只匹配 htm 或 html(\?{0,1})
:匹配可能出现零个或一个的问号 (?)([a-zA-Z0-9-_=&]{0,}+)
:匹配可以出现零次或多次的查询字符串(#{0,1})
:匹配可以出现零个或一个的主题标签 (#)([a-zA-Z0-9-_=&]{0,}+)
:匹配出现零次或多次的片段
如果我用测试 URL: /event/showEventList.html?pageNumber=1#key=val
测试此配置,我希望重定向的 URL 会是 /events?pageNumber=1
,但我得到 /events?pageNumber=1#key=val
我有一个代码片段来测试它,它是:
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class UrlRewriterRegexTest {
public static void main(String[] args) {
String input = "/event/showEventList.html?pageNumber=1#key=val";
String regex = "^(/event/showEventList)(\.{1})(\bhtm\b|\bhtml\b)(\?{0,1})([a-zA-Z0-9-_=&]{0,}+)(#{0,1})([a-zA-Z0-9-_=&]{0,}+)$";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(input);
System.out.println(matcher.replaceFirst("/events"));
}
}
它输出到:/events?pageNumber=1
.
任何指针都会很有帮助。
我会稍微简化一下表达式。
- 转义斜杠,因为它们通常用作正则表达式的分隔符
(\/event\/showEventList)
- 删除多余的量词
(\.)
- 缩短 html 字符串测试
(htm(l)?)
- 小心,这会扰乱您的捕获组编号 - 删除
html
周围的单词边界检查
- 使用
?
代替{0,1}
- 使用
*
代替{0,}
- 删除所有格量词(我不明白你为什么需要它)
- 忽略
#
之后的所有内容,你的替换似乎不需要它
这给了我们 ^(\/event\/showEventList)(\.)(htm(l)?)(\??)([a-zA-Z0-9-_=&]+)*#(.+)$
将您的示例替换为 /events?pageNumber=1
要玩转,请参阅 https://regexr.com/4otp7
我已经简化了表达式,这是有效的解决方案
<from>^(\/event\/showEventList\.html?)(\?[a-zA-Z0-9-_=&]*)\#.*$</from>
<to type="redirect" last="true">/events</to>
这将匹配任何内容,并获取从查询字符串开头到第一次出现 #
的所有内容解释:
第 1 组:匹配 url /event/showEventList.html 或 /event/showEventList.htm
第 2 组:匹配 o 到 many 之间的所有查询字符串,直到第一次出现 #
第 2 组是您要用于重定向并忽略# 之后的任何内容的字符串,包括#
示例:
我正在回答我自己的问题,以便将来如果其他人遇到同样的问题,这个答案可以帮助他。
与UrlRewriteFilter
框架无关。通过启用此框架的调试日志,我发现它在应用定义的规则之前收到的 URL 没有 URL Hash(#)。从其他 SO 答案以及通过分析浏览器的网络流量,我看到浏览器不会将 URL 片段发送到服务器,因此它在 HttpServletRequest
中不可用。这就是正则表达式不起作用的原因。
自此 hash is available in the client browser and thanks to HTML5 History API 我可以使用 JavaScript:
解决问题<script type="text/javascript">
window.addEventListener('DOMContentLoaded', (event) => {
const url = new URL(window.location);
url.hash = '';
history.replaceState(null, document.title, url);
});
</script>