web-dev-qa-db-ja.com

Jackson JSR310モジュールでLocalDateTimeをデシリアライズする

説明したライブラリ Jackson Datatype JSR310ページ を使用していますが、それを動作させるのにまだ苦労しています。

次のBeanを構成しました。

@Bean
@Primary
public ObjectMapper objectMapper() {
    ObjectMapper mapper = new ObjectMapper();
    mapper.registerModule(new JSR310Module());
    return mapper;
}

REST API)を呼び出すと、日付形式の出力はyyyy-MM-dd'T'HH:ss.SSSSSS、たとえば2015-04-11T00:10:38.905847です。これは私のAngularJSコードで適切に処理されます。

REST APIに何かを送信したい場合、日付はyyyy-MM-dd'T'HH:mm:ss.SSS'Z'として投稿されます。例:2015-04-09T08:30:00.000Z

ジャクソンは最後に「Z」について文句を言い続けます。ドキュメントのLocalDateTimeDeserializerを見ると、DateTimeFormatter.ISO_LOCAL_DATE_TIMEに沸騰するISO_LOCAL_DATE'T'ISO_LOCAL_TIMEを使用しており、オーバーライドゾーンがないことに言及しています。

それで、私が作成しているDateFormatObjectMapperを設定する必要があると考えました。

@Bean
@Primary
public ObjectMapper objectMapper() {
    ObjectMapper mapper = new ObjectMapper();
    mapper.registerModule(new JSR310Module());
    mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"));
    return mapper;
}

しかし、これは何もしません。 yyyy-MM-ddのような単純なものに変更しましたが、シリアル化された日付は以前の形式のままであり、逆シリアル化も影響を受けません。

これを機能させるためにここで何が間違っていますか? JavaScriptコードの日付形式は、ISO 8601形式を知っている限りです...

15
Mekswoll

独自のシリアライザーを作成する必要はありません。デフォルトのものを使用すれば十分ですが、別の形式でインスタンスを作成します(time_zone one)そのため、超過部分は切り取られます。

new LocalDateTimeDeserializer(DateTimeFormatter.ISO_DATE_TIME)

私の場合、設定レベルで達成するためにこのようなcontextResolverを持っています:

@Service 
@Provider
public class ObjectMapperContextResolver implements ContextResolver<ObjectMapper> {  
    private final ObjectMapper mapper;

    public ObjectMapperContextResolver() {
        mapper = new ObjectMapper();
        JavaTimeModule javaTimeModule=new JavaTimeModule();
        // Hack time module to allow 'Z' at the end of string (i.e. javascript json's) 
        javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ISO_DATE_TIME));
        mapper.registerModule(javaTimeModule);
        mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
    }

    @Override
    public ObjectMapper getContext(Class<?> type) {
        return mapper;
    }  
}
23
user1299153

現時点では、LocalDateTimeDeserializerはオブジェクトマッパーに設定された日付形式を尊重していないようです。

動作させるには、LocalDateTimeDeserializerをオーバーライドするか、最後に 'Z'文字を処理するZoneDateTimeを使用するように切り替えることができます。

次に例を示します。

public class Java8DateFormat {
    public static void main(String[] args) throws IOException {
        final ObjectMapper mapper = new ObjectMapper();
        mapper.registerModule(new JSR310Module());
        // mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"));

        final String date = mapper.writeValueAsString(new Date());
        System.out.println(date);
        System.out.println(mapper.readValue(date, ZonedDateTime.class));
    }
}

出力:

"2015-04-11T18:24:47.815Z"
2015-04-11T18:24:47.815Z[GMT]
5
Alexey Gavrilov

Hibernate 4、Spring 4-REST WS、Client-Spring Boot 1.5.2。私の場合、Entityで使用しましたZonedDateTime class to map Timestampデータベース内。HibernateおよびSpring Boot RESTは正常に動作します。ライブラリはpomファイルにのみ追加する必要があります。

    <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-annotations -->
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-annotations</artifactId>
        <version>${jackson.version}</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.datatype/jackson-datatype-jsr310 -->
    <dependency>
        <groupId>com.fasterxml.jackson.datatype</groupId>
        <artifactId>jackson-datatype-jsr310</artifactId>
        <version>${jackson.version}</version>
    </dependency>

そのため、そのコンバーターはLocalDateTimeのSpringにも実装されていると思います。jackson.versionは最新のものです。

1
hariprasad