web-dev-qa-db-ja.com

アノテーションを使用して、ジャクソンの逆シリアル化プロセスでACCEPT_SINGLE_VALUE_AS_ARRAYを実施する方法

JacksonACCEPT_SINGLE_VALUE_AS_ARRAYを使用するために、クラスのListプロパティに注釈を使用する方法はありますか?私はSpringを使用しており、以下の例外が発生します

ネストされた例外はcom.fasterxml.jackson.databind.JsonMappingExceptionです:VALUE_STRINGトークンからJava.util.ArrayListのインスタンスをデシリアライズできません

次のようなクラスがあると仮定します。

public class MyClass {

    private List < String > value;
}

そして、私のJSON構造は以下のとおりです:

ケース1:

[{"operator": "in", "value": ["Active"], "property": "status"}]

ケース2:

[{"operator": "like", "value": "aba", "property": "desc"}]

フレームワークにこれらの2つのケースを逆シリアル化するときに同じように処理することを通知するには、どのアノテーションを使用すればよいですか。

PDATE:より明確にするために、この投稿の回答に更新を移動しました。

19
Vahid

私は明確にするために自分の質問に答えているだけです。答えの1つは、注釈を使用できるように上位バージョンにアップグレードすることでした。プロジェクトの依存関係の制限により、私はそれを行うことができません。

その結果、Michal Foksaの回答に基づいて、カスタムデシリアライザーを作成することで問題を解決しました。以下の通り:

私の財産:

@JsonDeserialize(using = CustomStringDeserializer.class)
private List<String> value;

そして私のデシリアライザ:

public class CustomStringDeserializer extends JsonDeserializer<List<String>>{

    @Override
    public List<String> deserialize(JsonParser p, DeserializationContext ctxt)
            throws IOException, JsonProcessingException {
        ObjectMapper mapper = new ObjectMapper();
        mapper.enable(DeserializationFeature. ACCEPT_SINGLE_VALUE_AS_ARRAY);
        return mapper.readValue(p, List.class);
    }

}
7
Vahid

@ JsonFormat アノテーションを使用できます。

public class MyClass {

    @JsonFormat(with = JsonFormat.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
    private List<String> value;

}

これを使用するには、Jacksonバージョンmin 2.7.0が必要です。他の利用可能な JsonFormat機能 を使用することもできます。

バージョン2.6.xの場合

@Autowired private ObjectMapper mapper;
//...

mapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);
  • このコードをInitializer Classに追加します。
  • または、Bean ConfigurationJacksonを直接設定することもできます

これらは問題を解決しますが、すべてのdeserializationプロセスに対してアクティブ化されます。

34
Ömer Erden

カスタムJsonDeserializerを作成して、両方のケースを処理し、デシリアライザで値クラスプロパティに注釈を付けます。

デシリアライザー:

public class StringListDeserializer extends JsonDeserializer<List<String>>{

    @Override
    public List<String> deserialize(JsonParser parser, DeserializationContext ctxt)
            throws IOException, JsonProcessingException {

        List<String> ret = new ArrayList<>();

        ObjectCodec codec = parser.getCodec();
        TreeNode node = codec.readTree(parser);

        if (node.isArray()){
            for (JsonNode n : (ArrayNode)node){
                ret.add(n.asText());
            }
        } else if (node.isValueNode()){
            ret.add( ((JsonNode)node).asText() );
        }
        return ret;
    }
}

私のクラス:

public class MyClass {
    .
    @JsonDeserialize(using = StringListDeserializer.class)
    private List<String> value;
    .
}

それが役に立てば幸い。

ところで、そのような場合にアノテーションだけで対処する方法があれば、それも知りたいです。

6
Michal Foksa

このプロジェクトがSpringプロジェクトである場合は、このプロパティをapplication.properties

spring.jackson.deserialization.UNWRAP_SINGLE_VALUE_ARRAYS=true

0
javaPlease42