使用 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-_=&amp;]{0,}+)(#{0,1})([a-zA-Z0-9-_=&amp;]{0,}+)$</from>
        <to type="redirect" last="true">/events</to>
    </rule>                 
</urlrewrite>

正则表达式^(/event/showEventList)(\.{1})(\bhtm\b|\bhtml\b)(\?{0,1})([a-zA-Z0-9-_=&amp;]{0,}+)(#{0,1})([a-zA-Z0-9-_=&amp;]{0,}+)$有7组,分别是:

  1. (/event/showEventList):匹配 /event/showEventList
  2. (\.{1}):匹配单个点 (.)
  3. (\bhtm\b|\bhtml\b): 只匹配 htm 或 html
  4. (\?{0,1}):匹配可能出现零个或一个的问号 (?)
  5. ([a-zA-Z0-9-_=&amp;]{0,}+):匹配可以出现零次或多次的查询字符串
  6. (#{0,1}):匹配可以出现零个或一个的主题标签 (#)
  7. ([a-zA-Z0-9-_=&amp;]{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>