9

JSON文字列を入力として受け取るBeanオブジェクトを更新するREST WSがあります。

ABean entity = svc.findEntity(...);
objectMapper.readerForUpdating(entity).readValue(json);
[...]
svc.save(entity);

ABean は、他のオブジェクトも含む複合型です

class ABean {
    public BBean b;
    public CBean c;

    public String d;
}

svc.save(...)は、Bean と埋め込みオブジェクトを保存します

セキュリティ上の理由から、JSON 文字列で更新できるプロパティの一部を除外したいのですが、これを動的に行いたいので、すべての WS (またはユーザー ロール) について更新を禁止するプロパティを決定できます (したがって、Jackson Views を単純に使用することはできません)

要約すると、JSON デシリアライゼーション中にプロパティを動的に除外する方法はありますか?

4

4 に答える 4

1

@JsonIgnoreType を使用して、シリアライズから Java クラス/インターフェース/列挙を無視できます。さらに、プロパティのリストを無視するために @JsonIgnoreProperties を使用し、特定のプロパティに対して @JsonIgnore を使用できます。

于 2012-09-06T18:38:56.280 に答える
1

あなたの説明から、アノテーションを単純に使用して、@JsonIgnore特定のクラスごとにフィールドがシリアル化されるのを防ぐことはできないと思います。

Jakson mix-ins の使用を見てください。 mix-ins を使用すると、クラス定義を (必要な注釈を付けて) データ バインディングに置き換えることができます。シリアル化中に、特定の mix-in クラス定義を選択して、シリアル化される実際のクラスの代わりにすることができます。すべてのケースを処理する一連のミックスインを定義してから、特定の Bean をシリアル化するときに適切なものを選択します。

于 2012-09-06T18:03:46.007 に答える
0

私が思いついた最も強力で迅速かつ簡単な解決策は、デシリアライゼーションから取得した JsonNode ツリーをフィルタリングし、フィルタリングした結果を readerForUpdating に渡すことです。そんな感じ:

public class JacksonHelper {
    public JsonNode filterBeanTree(JsonNode o, List<String> includedProperties,
            List<String> excludedProperties, int maxDepth) {
        JsonNode tree = o.deepCopy();
        this.filterBeanTreeRecursive(tree, includedProperties, excludedProperties, maxDepth, null);
        return tree;
    }

    private void filterBeanTreeRecursive(JsonNode tree, List<String> includedProperties,
            List<String> excludedProperties, int maxDepth, String key) {
        Iterator<Entry<String, JsonNode>> fieldsIter = tree.fields();
        while (fieldsIter.hasNext()) {
            Entry<String, JsonNode> field = fieldsIter.next();
            String fullName = key == null ? field.getKey() : key + "." + field.getKey();

            boolean depthOk = field.getValue().isContainerNode() && maxDepth >= 0;
            boolean isIncluded = includedProperties != null
                    && !includedProperties.contains(fullName);
            boolean isExcluded = excludedProperties != null
                    && excludedProperties.contains(fullName);
            if ((!depthOk && !isIncluded) || isExcluded) {
                fieldsIter.remove();
                continue;
            }

            this.filterBeanTreeRecursive(field.getValue(), includedProperties, excludedProperties,
                    maxDepth - 1, fullName);
        }
    }
} 
于 2012-09-25T18:49:33.217 に答える