Jsoup转换&到&当我需要这些信息时

时间:2015-07-13 08:50:48

标签: java jsoup

在少数情况下,我传递了具有用户执行某些操作的页面网址的JSON。该页面网址将包含我需要的那些查询字符串部分,以便用户在我的应用程序需要时重定向到同一页面。我的JSON就像

{
"userId":"123456789",
"pageUrl":"http://exampl.com/designs.jsp?templateId=f348aaf2-45e4-4836-9be4-9a7e63105932&kind=123",
"action":"favourite"
}

但是,当我通过Jsoup.clean(json, Whitelist.basic())运行此json时,我发现&已替换为&。我可以将Jsoup配置为不单独逃避此角色吗?

2 个答案:

答案 0 :(得分:1)

转义发生在org.jsoup.nodes.Entities。 这是有问题的代码

static void escape(StringBuilder accum, String string,
        Document.OutputSettings out, boolean inAttribute,
        boolean normaliseWhite, boolean stripLeadingWhite) {
    boolean lastWasWhite = false;
    boolean reachedNonWhite = false;
    EscapeMode escapeMode = out.escapeMode();
    CharsetEncoder encoder = out.encoder();
    CoreCharset coreCharset = CoreCharset.access$300(encoder.charset().name());
    Map map = escapeMode.getMap();
    int length = string.length();
    int codePoint;
    for (int offset = 0; offset < length; offset += Character.charCount(codePoint)) {
        codePoint = string.codePointAt(offset);

        if (normaliseWhite) {
            if (StringUtil.isWhitespace(codePoint)) {
                if ((stripLeadingWhite) && (!(reachedNonWhite)))
                    continue;
                if (lastWasWhite)
                    continue;
                accum.append(' ');
                lastWasWhite = true;
                continue;
            }
            lastWasWhite = false;
            reachedNonWhite = true;
        }

        if (codePoint < 65536) {
            char c = (char) codePoint;

            switch (c) {
            case '&':
                accum.append("&amp;");
                break;
            case ' ':
                if (escapeMode != EscapeMode.xhtml)
                    accum.append("&nbsp;");
                else
                    accum.append(c);
                break;
            case '<':
                if (!(inAttribute))
                    accum.append("&lt;");
                else
                    accum.append(c);
                break;
            case '>':
                if (!(inAttribute))
                    accum.append("&gt;");
                else
                    accum.append(c);
                break;
            case '"':
                if (inAttribute)
                    accum.append("&quot;");
                else
                    accum.append(c);
                break;
            default:
                if (canEncode(coreCharset, c, encoder))
                    accum.append(c);
                else if (map.containsKey(Character.valueOf(c)))
                    accum.append('&')
                            .append((String) map.get(Character.valueOf(c)))
                            .append(';');
                else
                    accum.append("&#x")
                            .append(Integer.toHexString(codePoint))
                            .append(';');
            }
        } else {
            String c = new String(Character.toChars(codePoint));
            if (encoder.canEncode(c))
                accum.append(c);
            else
                accum.append("&#x").append(Integer.toHexString(codePoint))
                        .append(';');
        }
    }
}

快速做你需要的方法就是使用这样的东西

String str = "http://exampl.com/designs.jsp?templateId=f348aaf2-45e4-4836-9be4-9a7e63105932&kind=123";
str = Jsoup.clean(str, Whitelist.basic());
System.out.println(str);
str = Parser.unescapeEntities(str, true);
System.out.println(str);

另一种方法是扩展上面的类并覆盖导致问题的方法,但由于它仅对包可见(默认可见性),这意味着您必须下载源,更改可见性上面的方法,并覆盖类(因此该方法将是可见的)。

答案 1 :(得分:1)

作为应用Jsoup.clean()后的工作范围,我使用&amp;&替换为regex

String url = Jsoup.clean(url, Whitelist.basic()).replaceAll("&amp;", "&");