私はスプリングブートでいくつかのモデルを変換することに取り組んでいますREST APIアプリを使用するJava 8のJava.time.LocalDateTime
の代わりにjodaのDateTime
。API呼び出しから返されるタイムスタンプがISO_8601
形式に準拠するようにします。動機は、Java 8の時間( 詳細はこちら )。
難しいことは、LocalDateTime
を含むオブジェクトをJSONにシリアル化することです。
たとえば、次のエンティティがあります。
// ... misc imports
import Java.time.LocalDateTime;
import Java.time.ZoneOffset;
@Data
@Entity
@Table(name = "users")
public class User {
@Id @Column
private String id;
@Column
private String name;
@Column
private String email;
@Column
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss", timezone = "UTC")
private Java.time.LocalDateTime createdAt;
public User(String name, String email) {
this.id = Utils.generateUUID();
this.createdAt = LocalDateTime.now(ZoneOffset.UTC);
}
}
タイムスタンプジャクソン機能として日付をオフにするようにapplication.properties
を設定しました:
spring.jackson.serialization.WRITE_DATES_AS_TIMESTAMPS = false
私のMavenデプス:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>1.3.6.RELEASE</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<version>2.8.1</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.0.1.Final</version>
</dependency>
最後に、コントローラーを介してJSON表現を取得しようとします。
@RequestMapping("/users")
@RestController
public class UserController {
private UserService userService;
@Autowired
public UserController(UserService userService) {
this.userService = userService;
}
@RequestMapping(
value = "/{id}",
method = RequestMethod.GET,
produces = MediaType.APPLICATION_JSON_UTF8_VALUE
)
public User getUser(@PathVariable("id") String id) {
return userService.findById(id);
}
}
このエンドポイントを実際に呼び出すと、次の例外が発生します。
Java.lang.NoSuchMethodError:
com.fasterxml.jackson.datatype.jsr310.ser.JSR310FormattedSerializerBase.findFormatOverrides(Lcom/fasterxml/jackson/databind/SerializerProvider;Lcom/fasterxml/jackson/databind/BeanProperty;Ljava/lang/Class;)Lcom/fasterxml/jackson/annotation/JsonFormat$Value;
または、構成クラスでアプリのObjectMapper
も構成しました。
@Configuration
public class ServiceConfiguration {
@Bean
public ObjectMapper getJacksonObjectMapper() {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.registerModule(new JavaTimeModule());
objectMapper.configure(
com.fasterxml.jackson.databind.SerializationFeature.WRITE_DATES_AS_TIMESTAMPS,
false
);
return objectMapper;
}
}
どんなリードも大歓迎です。
Spring BootのJacksonバージョンとpom.xml
にあったバージョンとのバージョンの不一致であることが判明しました。 MilošとAndyが提案したように、正しいバージョンを設定してspring.jackson.serialization.write_dates_as_timestamps=true
でアプリを実行すると、ObjectMapper
を構成したり、LocalDateTime
に注釈を追加したりすることなく、問題が解決しましたモデルフィールド。
...
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>1.3.6.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>1.3.6.RELEASE</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
</dependency>
</dependencies>
NoSuchMethodError
は、Jacksonのバージョンを混合しているためです。 Spring Boot 1.3.6はJackson 2.6.7を使用しており、jackson-datatype-jsr310
の2.8.1を使用しています。
Spring Bootはjackson-datatype-jsr310
を含むJacksonの依存関係管理を提供するため、pomからバージョンを削除する必要があります。別のバージョンのJacksonを使用する場合は、jackson.version
プロパティをオーバーライドする必要があります。
<properties>
<jackson.version>2.8.1</jackson.version>
</properties>
これにより、ジャクソンのすべての依存関係が同じバージョンになり、バージョンの不一致による問題が回避されます。
必要に応じて、ObjectMapper
を構成するJavaコードを削除することもできます。Java Timeモジュールは、クラスパスでタイムスタンプとして日付を書き込むことは、application.properties
で設定できます:
spring.jackson.serialization.write-dates-as-timestamps=false
ObjectMapper
Beanは、Springで取得するために@Primary
としてマークする必要があります。または、JavaTimeModule
Beanを作成するだけで、Springがそれをピックアップし、デフォルトのオブジェクトマッパーに追加します。
おそらくすでに見ていますが、 公式ドキュメントをご覧ください 。
ジャクソンのバージョンを混在させるため、エラーが発生します。 Spring Bootのバージョン1.3.6.RELEASE
を使用しています。 Spring Bootバージョン2.x.x.RELEASE
に移行する場合は、com.fasterxml.jackson.datatype
依存関係をspring-boot-starter-json
依存関係に置き換えることができます。このようにして、Spring Bootに正しいジャクソンバージョンを処理させることができます。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-json</artifactId>
</dependency>