3
votes

Jackson @JsonFormat convertissant la date avec un fuseau horaire incorrect

J'ai une valeur provenant de la charge utile JSON comme:

Wed Mar 27 08:00:00 CDT 2019

Entity.java

@JsonProperty("callStartTime")
@Column(name = "call_start_dt", nullable = false)
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", lenient = OptBoolean.FALSE)
private Date callStartTime;

Quand je l'ai imprimé sur la console, il dit:

"callStartTime" : "2019-03-27 13:00:00"

Je voulais être le même que dans la charge utile json. Comment puis-je résoudre ce problème?

Je prends simplement la date de json et je l'écris dans mysql db dans une colonne datetime.


1 commentaires

4 Réponses :


1
votes

Essayez ceci

@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX")
private Date callStartTime;


4 commentaires

Cela lance une exception. l'exception est com.fasterxml.jackson.databind.exc.InvalidFormatException: impossible de désérialiser la valeur de type java.util.Date` from String "2019-03-27T13: 00: 00Z": format attendu "yyyy -MM-jj'T'HH: mm: ss.SSSXXX "`


Ah Vous n'avez pas de millisecondes dans votre date utilisez aaaa-MM-jj'T'HH: mm: ss.XXX


Si vous utilisez la version Java> = 1.8, utilisez ZonedDateTime au lieu de Date @JsonFormat (shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH: mm: ss.XXX") private ZonedDateTime callStartTime;


Pourtant, il jette une exception. même que mentionné ci-dessus



1
votes

java.util.Date ne capture pas les données de fuseau horaire. Il ne connaît que le nombre de millis depuis l'époque.

Vous pouvez essayer d'utiliser l'un des modules de jackson-modules-java8 et désérialiser en une instance de ZonedDateTime à la place, qui tient compte du fuseau horaire.

MODIFIER: essayez ceci comme base pour le faire fonctionner:

public class SoTest {
    public static void main(String[] args) throws Exception {
        ObjectMapper om = new ObjectMapper().registerModule(new ParameterNamesModule())
                                            .registerModule(new JavaTimeModule());

        String s = "{\"callStartTime\" : \"2019-03-27T13:00:00Z\" }";

        MyType mt = om.readValue(s, MyType.class);

        System.out.println(mt.getCallStartTime());
    }
}

class MyType {
    @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ssX", lenient = OptBoolean.FALSE)
    private ZonedDateTime callStartTime;

    public ZonedDateTime getCallStartTime() {
        return callStartTime;
    }

    public void setCallStartTime(ZonedDateTime date) {
        this.callStartTime = date;
    }

}


7 commentaires

J'ai une exception. Impossible de désérialiser la valeur de type java.time.ZonedDateTime à partir de la chaîne "2019-03-27T13: 00: 00Z": Le texte '2019-03-27T13: 00: 00Z' n'a pas pu être analysé, texte non analysé trouvé à l'index 19 ; l'exception imbriquée est com.fasterxml.jackson.databind.exc.InvalidFormatException: impossible de désérialiser la valeur de type java.time.ZonedDateTime de la chaîne "2019-03-27T13: 00: 00Z": Texte '2019-03-27T13: 00: 00Z 'n'a pas pu être analysé, texte non analysé trouvé à l'index 19


Ajout des 3 dépendances mentionnées dans jackson-modules-8


Je n'utilise pas ObjectMapper. Comment l'enregistrer? Je prends juste la date de json et je l'écris dans mysql db dans une colonne datetime.


Votre utilisation de @JsonProperty ( plus rapidexml. github.io/jackson-annotations/javadoc/2.8/com/... ) suggère que quelque part quelque part utilise Jackson pour faire l'analyse JSON, ce qui signifie à son tour que ObjectMapper est utilisé.


OK, j'ai compris. Mais toujours cette exception. Comment résoudre ce problème?


Essayez d'utiliser "@JsonFormat (pattern =" aaaa-MM-jj'T'HH: mm: ssZ ", indulgent = OptBoolean.FALSE)" - notez le Z, pour capturer le fuseau horaire (Zulu dans l'exemple que vous avez donné ci-dessus)


OK - a ajouté un petit test de fonctionnement. Il semble que X était nécessaire, et non Z, pour votre format par docs.oracle.com/javase/8/docs/api/java/time/format/...



2
votes

Solution simple: Je l'ai résolu en changeant le type de données en String , ce qui complète mon objectif de capturer la valeur telle qu'elle provient de la charge utile JSON. L'utilisation de Date et d'autres types de données convertissait la valeur dans un fuseau horaire différent.

@JsonProperty("callStartTime")
@Column(name = "call_start_dt", nullable = false)
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", lenient = OptBoolean.FALSE)
private **String** callStartTime;


0 commentaires

0
votes

Il existe deux solutions possibles pour cela:

1. Définissez le bean ObjectMapper et définissez le format de la date.

@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", lenient = OptBoolean.FALSE)
private Date createTime;

2. Définissez le format de date pour le champ particulier en utilisant @JsonFormat

@Bean
public ObjectMapper objectMapper()
{
   ObjectMapper objectMapper = new ObjectMapper();

   DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
   objectMapper.setDateFormat(df);
       return objectMapper;
}


0 commentaires