Description
Hello,
1/ Description
I try to serialize a LocalDate
(java 8) from my JPA entity into a specific pattern (dd/MM/yyyy).
Everything works fine if I put the annotation @JsonFormat(pattern="dd/MM/yyyy")
on each date of my JPA entity.
That solution is too heavy because I don't want to put this annotation on each date of all my jpa entites, So, I was looking for a better solution by applying some global configuration with spring boot.
I found the properties spring.jackson.date-format
and spring.jackson.locale
but I can't get them to work. I don't know if it's really a bug or I miss something in my project / configuration.
I am using Java8, spring-boot (1.2.6.RELEASE) with spring data jpa 1.9, and I have this in my classpath : 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.6.3'
To be precise that I am only working with spring-data-jpa
and not spring-data-rest
.
2/ Unit testing
I made a unit test and I have that output :
(I use spring.jackson.date-format
property)
Without the property in my yaml file, I've got this :
java.lang.AssertionError: JSON path$[0].dateCreation
Expected: "16/10/2015"
but: was **<[2015,10,16]>**
With the property but without specifying any format (blank), I've got this :
java.lang.AssertionError: JSON path$[0].dateCreation
Expected: "16/10/2015"
but: was **"2015-10-16"**
With the property and If i specify any format (dd/MM/yyyy
or dd-mm-yyyy
, or even a class) , I've got the same:
java.lang.AssertionError: JSON path$[0].dateCreation
Expected: "16/10/2015"
but: was **"2015-10-16"**
I've got the same result with the property : spring.jackson.locale
3/ build.gradle
apply plugin: 'spring-boot'
apply plugin: 'java'
springBoot {
mainClass = "com.seriajack.Application"
}
repositories {
mavenCentral()
}
group = 'test'
version = "1.0"
jar {
baseName = 'seriajack'
version= '1.0'
}
compileJava.options.encoding = 'UTF-8'
sourceCompatibility = 1.8
targetCompatibility = 1.8
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath(group: 'org.springframework.boot', name: 'spring-boot-gradle-plugin', version: '1.2.6.RELEASE')
}
}
dependencies {
compile("com.google.guava:guava:18.0")
compile("org.jolokia:jolokia-core:1.2.2")
compile('com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.6.3')
compile("org.springframework.boot:spring-boot-starter-web")
compile("org.springframework.boot:spring-boot-starter-tomcat")
compile("org.springframework.boot:spring-boot-starter-data-jpa")
compile("org.springframework.data:spring-data-jpa:1.9.0.RELEASE")
compile("com.h2database:h2")
compile("org.flywaydb:flyway-core:3.2.1")
testCompile("org.springframework.boot:spring-boot-starter-test")
testCompile 'junit:junit:4.12'
testCompile 'org.easytesting:fest-assert:1.4'
testCompile 'org.mockito:mockito-all:1.10.19'
testCompile 'com.jayway.jsonpath:json-path:2.0.0'
}
4/ application.yml
spring:
profiles:
active: test
jpa:
show-sql: false
hibernate:
ddl: auto
application:
name: seriajack
boot:
admin:
url: http://localhost:8080
client:
serviceUrl: http://localhost:8080
jackson:
date-format: dd/MM/yyyy
management:
port: 8080
address: 127.0.0.1
#SERVER
server:
port: 8080
session-timeout: 300
tomcat.uri-encoding: UTF-8
---
#PROFILE LOCAL
spring:
profiles: local
datasource:
initialize: false
datasource:
seriajack:
driverClassName: oracle.jdbc.driver.OracleDriver
url:
username:
password:
---
#PROFILE DEV
spring:
profiles: dev
datasource:
initialize: false
datasource:
seriajack:
driverClassName: oracle.jdbc.driver.OracleDriver
url:
username:
password:
---
#PROFILE TEST
spring:
profiles: test
datasource:
initialize: false
platform: h2
datasource:
test:
url: "jdbc:h2:mem:test;USER=SA;MODE=Oracle;DB_CLOSE_ON_EXIT=TRUE;INIT=create schema if not exists SERIAJACK\\;"
driverClassName: org.h2.Driver
5/ application.java
@SpringBootApplication
@EntityScan(basePackageClasses = { Application.class, Jsr310JpaConverters.class})
public class Application {
public static void main(String[] args) throws Exception {
SpringApplication.run(Application.class, args);
}
}
6/ JPA entity
package com.seriajack.textereglementaire;
import java.time.LocalDate;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Lob;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import com.fasterxml.jackson.annotation.JsonFormat;
@Entity
@Table(name = "T_TEXTE_REGLEMENTAIRE", schema = "SERIAJACK")
public class TexteReglementaire {
private long id;
private TexteType type;
private String numero;
private String intitule;
private LocalDate dateCreation;
@Lob
private byte[] fichier;
private String precision;
private LocalDate dateCertification;
private LocalDate dateParution;
private String numeroJONC;
private LocalDate dateAbrogation;
private String reference;
private String lienJuridoc;
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SEQ_TTEXTEREG")
@SequenceGenerator(name = "SEQ_TTEXTEREG", sequenceName = "SERIAJACK.SEQ_TTEXTEREG")
@Column(name = "ID")
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
@Column(name = "TYPE", nullable = false)
@Enumerated(EnumType.STRING)
public TexteType getType() {
return type;
}
public void setType(TexteType type) {
this.type = type;
}
@Column(name = "NUMERO", nullable = false)
public String getNumero() {
return numero;
}
public void setNumero(String numero) {
this.numero = numero;
}
@Column(name = "INTITULE", nullable = false)
public String getIntitule() {
return intitule;
}
public void setIntitule(String intitule) {
this.intitule = intitule;
}
@Column(name = "DATE_CREATION", nullable = false)
public LocalDate getDateCreation() {
return dateCreation;
}
public void setDateCreation(LocalDate dateCreation) {
this.dateCreation = dateCreation;
}
@Column(name = "FICHIER", nullable = false)
public byte[] getFichier() {
return fichier;
}
public void setFichier(byte[] fichier) {
this.fichier = fichier;
}
@Column(name = "PRECISION")
public String getPrecision() {
return precision;
}
public void setPrecision(String precision) {
this.precision = precision;
}
@Column(name = "DATE_CERTIFICATION")
public LocalDate getDateCertification() {
return dateCertification;
}
public void setDateCertification(LocalDate dateCertification) {
this.dateCertification = dateCertification;
}
@Column(name = "DATE_PARUTION")
public LocalDate getDateParution() {
return dateParution;
}
public void setDateParution(LocalDate dateParution) {
this.dateParution = dateParution;
}
@Column(name = "NUMERO_JONC")
public String getNumeroJONC() {
return numeroJONC;
}
public void setNumeroJONC(String numeroJONC) {
this.numeroJONC = numeroJONC;
}
@Column(name = "DATE_ABROGATION")
public LocalDate getDateAbrogation() {
return dateAbrogation;
}
public void setDateAbrogation(LocalDate dateAbrogation) {
this.dateAbrogation = dateAbrogation;
}
@Column(name = "REFERENCE")
public String getReference() {
return reference;
}
public void setReference(String reference) {
this.reference = reference;
}
@Column(name = "LIEN_JURIDOC")
public String getLienJuridoc() {
return lienJuridoc;
}
public void setLienJuridoc(String lienJuridoc) {
this.lienJuridoc = lienJuridoc;
}
}
7/ Controller
@Configuration
@RestController
@RequestMapping(value = "/api/texte", produces = "application/json;charset=UTF-8")
public class TexteReglementaireController {
@Autowired
TexteReglementaireService texteReglementaireService;
@RequestMapping(value = "/list", method = RequestMethod.GET)
public List<TexteReglementaire> findAllTexteReglementaire() {
return texteReglementaireService.findAllTexteReglementaire();
}
}