Jackson ObjectMapperを使用してオブジェクトからマップを取得しようとしています:
ObjectMapper oMapper = ObjectMapperWithDate.getObjectMapper();
Map<String, Object> map = oMapper.convertValue(obj, Map.class);
日付フィールドに問題があります。マップでは、それらがLongオブジェクトになっているためです。
ObjectMapperが日付を文字列に変更するように、デシリアライザを追加しました
public class ObjectMapperWithDate {
@Bean
public static ObjectMapper getObjectMapper() {
ObjectMapper mapper = new ObjectMapper();
mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
mapper.registerModule(
new SimpleModule("foo")
.addDeserializer(Date.class, new DateDeserializer())
.addSerializer(Date.class, new DateSerializer())
);
return mapper;
}
public static class DateSerializer extends StdScalarSerializer<Date> {
public DateSerializer() {
super(Date.class);
}
@Override
public void serialize(Date value, JsonGenerator gen, SerializerProvider provider)
throws IOException {
DateFormat formatter = new SimpleDateFormat("dd-MM-yyyy", Locale.ENGLISH);
String output = formatter.format(value);
gen.writeString(output);
}
}
public static class DateDeserializer extends StdScalarDeserializer<Date> {
public DateDeserializer() {
super(Date.class);
}
@Override
public Date deserialize(JsonParser p, DeserializationContext ctxt)
throws IOException {
try {
DateFormat formatter = new SimpleDateFormat("dd-MM-yyyy", Locale.ENGLISH);
return formatter.parse(p.getValueAsString());
} catch (Exception e) {
return null;
}
}
}
}
もちろん、マッパーの呼び出しは少し異なります。
ObjectMapper oMapper = ObjectMapperWithDate.getObjectMapper();
Map<String, Object> map = oMapper.convertValue(obj, Map.class);
これで、Dateオブジェクトがマップ内のStringオブジェクトになります。日付が適切に表現されている。しかし、私はそれらを日付タイプのままにする必要があります。興味深いのは、デシリアライザにブレークポイントを設定しても、到達しないことです。だから、デシリアライザに到達することは決してないだろう。シリアル化後のマッパーがSerializationFeature.WRITE_DATES_AS_TIMESTAMPSに応じてDateをStringまたはLongにし、デシリアライズ時にDateを認識しないためだと思います。
マッピング後に日付プロパティを日付プロパティのままにするにはどうすればよいですか?認められる必要があります。
ところで、BigDecimalプロパティはDoubleプロパティに変換されます。それは同様の問題のようですが、これらの2つのタイプは私の今後の作業にそれほど違いはありません。
マップの値のタイプをとして定義したためObject
、JacksonはタイプのカスタムデDate
シリアライザーを選択せず、デフォルトのデシリアライザーを使用してすべてのタイプを基本的なタイプ(long、String、LinkedHashMapなど)に変換します。
Date
オブジェクトにフィールドしかない場合は、convertValue
メソッドの2番目の引数を変更するだけです。
Map<String, Date> map = oMapper.convertValue(obj, new TypeReference<Map<String, Date>>() {});
しかし、明らかにそれはあなたのケースではないので、異なるタイプのフィールドを持つオブジェクトに対してそれを行う最も簡単な方法は、デシリアライザのタイプをに変更し、Object
その中のすべてのデータを手動で解析することです:
public static class DateDeserializer extends StdScalarDeserializer<Object> {
public DateDeserializer() {
super(Object.class);
}
@Override
public Object deserialize(JsonParser p, DeserializationContext ctxt)
throws IOException {
String valueAsString = p.getValueAsString();
try {
DateFormat formatter = new SimpleDateFormat("dd-MM-yyyy", Locale.ENGLISH);
return formatter.parse(valueAsString);
} catch (Exception e) {
//you could add extra logic to parse other types
return valueAsString;
}
}
}
また、の第一引数に置き換えることを忘れないでください.addDeserializer
としObject.class
それを行うためのよりエキゾチックな方法については、この記事を確認してください:http : //robertmarkbramprogrammer.blogspot.com/2018/05/de-serialise-json-string-to-map-with.html
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加