Jackson
でACCEPT_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:より明確にするために、この投稿の回答に更新を移動しました。
私は明確にするために自分の質問に答えているだけです。答えの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);
}
}
@ JsonFormat アノテーションを使用できます。
public class MyClass {
@JsonFormat(with = JsonFormat.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
private List<String> value;
}
これを使用するには、Jacksonバージョンmin 2.7.0
が必要です。他の利用可能な JsonFormat機能 を使用することもできます。
@Autowired private ObjectMapper mapper;
//...
mapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);
Initializer Class
に追加します。Bean Configuration
でJackson
を直接設定することもできますこれらは問題を解決しますが、すべてのdeserialization
プロセスに対してアクティブ化されます。
カスタム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;
.
}
それが役に立てば幸い。
ところで、そのような場合にアノテーションだけで対処する方法があれば、それも知りたいです。
このプロジェクトがSpringプロジェクトである場合は、このプロパティをapplication.properties
:
spring.jackson.deserialization.UNWRAP_SINGLE_VALUE_ARRAYS=true