【问题标题】:Modify "Black Box" Servlet Response Output修改“黑盒”Servlet 响应输出
【发布时间】:2012-10-24 10:37:51
【问题描述】:

问题:

我有一个生成报告的 servlet,更具体地说是报告的表体。它是一个黑盒子,我们无权访问源代码。

尽管如此,它的工作令人满意,并且不打算很快重写或替换 servlet。

我们需要修改它的响应文本以更新它生成的一些链接到其他报告,我正在考虑使用过滤器来查找锚文本并使用正则表达式替换它。

研究:

我遇到了this question,它有一个正则表达式过滤器。这应该是我需要的,但也许不是。

我并没有尝试解析严格意义上的parsing 术语的 HTML,并且我没有使用该语言的完整规范。我所拥有的是组成表格主体的 HTML 标记子集,并且没有嵌套表格,因此 servlet 生成的 HTML 子集不是递归的。

我只需要找到/替换锚点目标并向标签添加一个属性。

所以问题是:

我需要修改 servlet 的输出以更改所有此类链接:

<a href="http://mypage.com/servlets/reports/?a=report&id=MyReport&filters=abcdefg">

进入如下链接:

<a href="http://myOtherPage.com/webReports/report.xhtml?id=MyReport&filters=abcdefg" target="_parent">

我应该使用@ Jeremy Stein编写的正则表达式过滤器还是有更好的解决方案?

【问题讨论】:

  • 我当然不会使用正则表达式来解析 HTML,但也许这样的东西适用于 URL 本身。对于幽默和可怕的警告,您应该阅读以下内容:stackoverflow.com/a/1732454/650425
  • @maple_shaft 在这个问题上我的团队在我的肩膀上发出了很多笑声。至于 servlet 输出,我们进行了测试,它编写了有效的 XML。如果我需要将其转换为数据结构,我会使用 XML 解析器对其进行解析。我只需要在响应中发送它之前修改它的部分。
  • 当您说:“此类链接...” 是指指向特定主机或域的所有链接吗?或者只是那些具有特定 URL 的人?或者只有那些 path=servlets/reports/ 您需要更明确地说明您希望修改哪些锚链接。另外,锚还有其他属性吗?
  • 谢谢 ridge,我还是进入了正则表达式路径。我没有解析 HTML,只是在输出上进行查找替换。跑得快,能胜任。
  • 对到达这里的人的警告:避免使用懒点。*?如果可以的话,就像瘟疫一样。regular-expressions.info/catastrophic.html

标签: java regex httpresponse servlet-filters


【解决方案1】:

假设目标 A 标记中唯一不同的部分是 href 属性的查询组件,那么这个经过测试的正则表达式解决方案应该做得很好:

// TEST.java 20121024_0800
import java.util.regex.*;
public class TEST {
    public static String fixReportAnchorElements(String text) {
        Pattern re_report_anchor = Pattern.compile(
            "<a href=\"http://mypage\\.com/servlets/reports/\\?a=report&id=([^\"]+)\">",
            Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE);
        Matcher m = re_report_anchor.matcher(text);
        return m.replaceAll(
            "<a href=\"http://myOtherPage.com/webReports/report.xhtml?id=$1\" target=\"_parent\">"
            );
    }
    public static void main(String[] args) {
        String input =
            "test <a href=\"http://mypage.com/servlets/reports/?a=report&id=MyReport&filters=abcdefg\"> test";
        String output = fixReportAnchorElements(input);
        System.out.println(output);
    }
}

【讨论】:

  • 是的,这就是我的想法。我使用了 Jeremy Stein 的课程(请参阅相关链接),并进行了一些更改。我只是想知道正则表达式过滤器是否是编辑 servlet 输出的方法。我将我的模式和 replaceString 添加到您的答案中,+1 并接受了它。
【解决方案2】:

我使用了Jeremy Stein (click to go to question) 类,做了一些改动:

a) 确保过滤器链或 servlet 中的任何人都不会在包装器对象上调用 getOutputStream(),否则它会抛出 invalidStateException(检查主题上的 this answer by BalusC)。

b) 我想在页面上做一个单独的更改,所以我没有在 web.xml 上放置任何 filterConfig。

b.2) 我也没有在 web.xml 上放任何东西。在类本身上使用了javax.servlet.annotation.WebFilter

c) 我直接在类上设置 Pattern 并替换字符串:

Pattern searchPattern = Pattern.compile("<a (.*?) href=\".*?id=(.*?)[&amp;|&]filtros=(.*?)\" (.*?)>(.*?)</a>");
String replaceString = "<a $1 href=\"/webReports/report.xhtml?idRel=$2&filtros=$3\" target=\"_parent\" $4>$5</a>";

注意.*? 尽可能少地匹配,以避免匹配超过想要的。

为了测试匹配和正则表达式,我在研究主题时使用了this applet I found

希望这对遇到同样问题的人有所帮助。

【讨论】:

    猜你喜欢
    • 2020-05-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-25
    • 2010-12-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多