修复htmlspecialchars() - 使用Play在JSON有效负载内编码数据!和杰克逊

时间:2013-03-22 01:56:43

标签: java json playframework jackson

我正在使用JSON网络API将数据中的所有&,“,”,<和>字符转换为& amp;,& quot;等等。看起来它正在使用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提供的树模型,但我可以使用一些建议或指针正确的方向。感谢。

1 个答案:

答案 0 :(得分: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);杰克逊2.x有一些差异。如果有人有任何改进建议,请发表评论。希望这段代码对未来与杰克逊合作的谷歌有所帮助。