0

データ内のすべての&、 "、'、<、>文字を&amp;、&quot;などに変換する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

JsonNode ツリーを「array_walk_recursive」して、上記の 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.lang3です。JsonUtils次のようになります。

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;
        }
    }
}

これは、最新の Play (2.1) で現在出荷されている Jackson 1.9.10 用であることに注意してください。Jackson 2.x にはいくつかの違いがあります。誰かが改善のための提案があれば、コメントを残してください。願わくば、このコードの壁が、Jackson と共同作業する将来の Google 社員の助けになることを願っています。

于 2013-03-26T18:34:00.290 に答える