0

我正在使用一个 JSON Web API,它将数据中的所有 &、"、'、< 和 > 字符转换为 &、" 等。看起来它正在使用 PHP 的 htmlspecialchars()。

我有一些处理这个问题的 PHP 代码,比如:

function unescape_special_chars(&$value, $key) {
    $value = html_entity_decode($value, ENT_QUOTES, 'UTF-8');
}
...

$response = json_decode($response->getBody(), true);
// the data has been run through htmlspecialchars(), we must undo this
array_walk_recursive($response, 'unescape_special_chars');

这很好,我不知道也不关心返回的 JSON 对象的结构是什么,但是上面的内容会遍历并修复它。

我需要将此代码重写为 Java,并且我正在使用 Play!框架。我对 Play 很陌生,对 Java 很生疏。到目前为止,这是我在 Play 应用程序中的 util 类中的内容:

protected Promise<JsonNode> consumeApi() throws Exception {
    Promise<Response> resultsP = WS.url(REST_URL).post("");
    Promise<JsonNode> jsonNodeP = resultsP.map(new Function<Response, JsonNode>() {
        public JsonNode apply(Response response) throws Throwable {
            // Here I need to "array_walk_recursive" in Java/Jackson
            return response.asJson();
        }
    });
    return jsonNodeP;
}

我怎样才能在 Java 和/或 Jackson 中做类似的事情?我有一种感觉,我应该能够遍历 JsonNode 提供的树模型,但我可以在正确的方向上使用一些建议或指针。谢谢。

4

1 回答 1

0

我能够“array_walk_recursive”JsonNode 树并使用自定义的用户提供的回调来修复它,类似于我上面的 PHP 解决方案,具有以下内容:

public Promise<JsonNode> consumeApi() throws Exception {
    return WS.url(REST_URL)
            .post("")
            .map(new Function<Response, JsonNode>() {
                public JsonNode apply(Response response) throws Throwable {
                    // BEGIN JACKSON RELEVANT CODE
                    return JsonUtils.walkJsonNode(response.asJson(), new JsonUtils.TextFixer() {
                        public String fix(String string) {
                            return StringEscapeUtils.unescapeHtml4(string);
                        }
                    });
                    // END JACKSON RELEVANT CODE
                }
            });
}

StringEscapeUtils是从org.apache.commons.lang3JsonUtils好像:

public class JsonUtils {
    public interface TextFixer {
        public String fix(String string);
    }

    public static JsonNode walkJsonNode(JsonNode node, TextFixer fixer) {
        if (node.isTextual()) {
            String fixedValue = fixer.fix(node.getTextValue());
            return new TextNode(fixedValue);

        } else {
            if (node.isArray()) {
                ArrayNode array = (ArrayNode)node;
                for (int i = 0; i < array.size(); i++) {
                    JsonNode value = array.get(i);
                    JsonNode fixedValue = walkJsonNode(value, fixer);
                    array.set(i, fixedValue);
                }

            } else if (node.isObject()) {
                ObjectNode object = (ObjectNode)node;
                Iterator<String> ite = object.getFieldNames();
                while (ite.hasNext()) {
                    String fieldName = ite.next();
                    JsonNode value = object.get(fieldName);
                    JsonNode fixedValue = walkJsonNode(value, fixer);
                    object.put(fieldName, fixedValue);
                }
            }

            return node;
        }
    }
}

请注意,这是针对 Jackson 1.9.10 的,它是当前与最新 Play (2.1) 一起提供的;Jackson 2.x 有一些不同之处。如果有人有任何改进建议,请发表评论。希望这堵代码墙对未来与杰克逊合作的谷歌员工有所帮助。

于 2013-03-26T18:34:00.290 回答