J'ai créé une application Web Spring qui propose l'API REST. J'utilise Spring Boot 2.x, Spring Data REST, Spring HATEOAS, Spring JPA, Hibernate 5.3, Mysql.
J'utilise également jackson-datatype-jsr310.
Je travaille avec les dates UTC dans toute l'application et je stocke les dates UTC dans Mysql.
Dans mon bean, les dates sont définies comme suit:
@EnableHypermediaSupport(type = {EnableHypermediaSupport.HypermediaType.HAL})
Tout fonctionne mais lorsque l'API est consommée, les dates sont renvoyées dans ce format:
@Autowired(required = true) public void configureJackson(ObjectMapper jackson2ObjectMapper) { jackson2ObjectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); jackson2ObjectMapper.configure(SerializationFeature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS, false); }
Je souhaite tronquer chaque date / heure de mon application en millisecondes, la date doit donc be:
"validUntil": "2019-11-05T22: 59: 59.999Z"
Dans ma @Configuration, j'utilise un JacksonModule personnalisé:
@Bean public Module customJacksonModule() { SimpleModule customJacksonModule = new SimpleModule(); customJacksonModule.addSerializer(ConstraintViolationException.class, constraintViolationExceptionSerializer()); customJacksonModule.addSerializer(ValidationException.class, validationExceptionSerializer()); customJacksonModule.addSerializer(cloud.optix.server.exceptions.ValidationException.class, customValidationExceptionSerializer()); return customJacksonModule; }
J'ai essayé plusieurs approches mais personne n'a fonctionné jusqu'à présent:
1. Application.properties
J'ai mis spring.jackson.serialization.write-date-timestamps-as-nanoseconds = false
dans mon application.propreties
J'ai essayé de modifier les paramètres de objectMapper.
"validUntil" : "2019-11-05T22:59:59.999999Z"
3. Suppression de @EnableHypermediaSupport
@NotNull @Column(nullable = false) private Instant validUntil;
Toutes ces actions n'ont pas changé la façon dont la date est renvoyée au client. J'aimerais avoir des conseils pour comprendre / déboguer pourquoi la date n'est pas renvoyée dans le bon format.
Comme note supplémentaire, j'ai trouvé cela dans com.fasterxml.jackson.datatype.jsr310.ser .InstantSerializerBase
dans la méthode serialize () Je n'ai ni propriété useNanoseconds
, ni formateur
par défaut.
Cependant, la propriété spring.jackson.serialization.write-dates-as-timestamps
dans application.properties a un effet sur le format de la date.
3 Réponses :
Avez-vous simplement essayé d'annoter votre champ validUntil avec @JsonFormat
comme ci-dessous.
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSZ") @NotNull @Column(nullable = false) private Instant validUntil;
Cela fonctionne mais je devrais ajouter cette annotation sur tous les champs de mon application. J'aimerais faire quelque chose pour l'ensemble de l'application au niveau de la configuration
Vous pouvez configurer votre ObjectMapper pour utiliser un format de date spécifique dans l'application:
jackson2ObjectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSz"));
J'ai essayé mais cela ne change pas le format dans mon cas.
Cela ne fonctionne pas pour type java.time .
Vous devez remplacer InstantSerializer
est utilisé par Jackson.
@Configuration public class JacksonConfig { @Bean public Jackson2ObjectMapperBuilderCustomizer jsonCustomizer() { return builder -> builder.serializers(new CustomInstantSerializer()); } private static class CustomInstantSerializer extends InstantSerializer { private static final DateTimeFormatter UTC_DATE_FORMAT = DateTimeFormatter .ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'").withZone(ZoneOffset.UTC); private CustomInstantSerializer() { super(InstantSerializer.INSTANCE, null, UTC_DATE_FORMAT); } } }
Vous pouvez mettre la classe JacksonConfig
dans la configuration
package du projet, par exemple.
De plus, si cela ne fonctionne pas, vérifiez que SpringBoot peut vraiment le trouver. Définissez un point d'arrêt dans le constructeur par défaut de InstantSerializer
ou ajoutez-y une journalisation temporelle.