2017-07-11 1 views
0

Comment puis-je obtenir MOXy pour unmarshal JSON en LocalDate et LocalDateTime?Unmarshalling LocalDate/LocalDateTime avec MOXy

J'ai une méthode @GET qui produit une instance échantillon avec trois champs de types LocalDate, LocalDateTime et Date, respectivement.

Frapper ce point d'extrémité, je reçois:

{ 
    "localDate": "2017-07-11", 
    "localDateTime": "2017-07-11T10:11:10.817", 
    "date": "2017-07-11T10:11:10.817+02:00" 
} 

Je puis après les données ci-dessus à ma méthode @POST, qui renvoie simplement les données à nouveau:

{ 
    "date": "2017-07-11T10:11:10.817+02:00" 
} 

Comme vous pouvez le voir, les deux localDate et localDateTime sont perdus dans le processus, car MOXy n'initialise pas ces deux champs.

Ce qui donne? MOXy semble soutenir la sérialisation de ces types, mais pas la désérialisation?

import javax.ws.rs.Consumes; 
import javax.ws.rs.GET; 
import javax.ws.rs.POST; 
import javax.ws.rs.Path; 
import javax.ws.rs.core.MediaType; 
import javax.ws.rs.core.Response; 
import java.time.LocalDate; 
import java.time.LocalDateTime; 
import java.util.Date; 

@Path("/test/date") 
public class DateTest { 
    public static class Data { 
     public LocalDate localDate; 
     public LocalDateTime localDateTime; 
     public Date date; 
    } 

    @GET 
    @Path("roundtrip") 
    public Response roundtrip() { 
     Data sample = getSample(); 
     return roundtrip(sample); 
    } 

    @POST 
    @Path("roundtrip") 
    @Consumes(MediaType.APPLICATION_JSON) 
    public Response roundtrip(Data t) { 
     return Response.status(Response.Status.OK).entity(t).build(); 
    } 

    protected Data getSample() { 
     final Data data = new Data(); 
     data.localDate = LocalDate.now(); 
     data.localDateTime = LocalDateTime.now(); 
     data.date = new Date(); 
     return data; 
    } 
} 

Version Moxy: jersey-media-moxy-2.25.1

+1

Est-ce vraiment "serialisation" (dans le sens le plus commun) ou est-ce simplement en appelant toString() ?. Il y a une différence. Jusqu'à ce que MOXy/JAXB prenne réellement en charge l'heure Java8, vous devrez probablement utiliser [XMLAdapter] (http://blog.bdoughan.com/2011/05/jaxb-and-joda-time-dates-and-times.html). Ou vous pouvez utiliser Jackson au lieu de MOXy, et [utiliser son support de temps Java8] (https://stackoverflow.com/a/28803634/2587435) –

+0

@peeskillet Je n'ai pas pensé à cette possibilité. J'ai lu [votre message] (https://stackoverflow.com/a/26825079/383124) et j'ai compris que cela signifiait qu'il était supporté. – phant0m

+0

Dans ce post, j'ai effectivement donné deux exemples de ce que j'ai mentionné comme solutions dans mon commentaire précédent (à savoir utiliser un adaptateur ou passer à Jackson) –

Répondre

1

Selon la suggestion de peeskillet I mis en œuvre la classe d'adaptation suivante:

public class LocalDateTimeAdapter extends XmlAdapter<String, LocalDateTime>{ 

    private static final DateTimeFormatter DTF = DateTimeFormatter.ofPattern("yyyyMMddHHmmss"); 

    @Override 
    public String marshal(LocalDateTime localDateTime) throws Exception { 
    return localDateTime.format(DTF); 
    } 

    @Override 
    public LocalDateTime unmarshal(String string) throws Exception { 
    return LocalDateTime.parse(string, DTF); 
    } 

} 

En outre, j'ai créé package-info.java dans le même package où mes classes pour Moxy et adaptateur (dans un sous-paquet) sont trouvés avec le contenu suivant:

@XmlJavaTypeAdapters({ 
    @XmlJavaTypeAdapter(type=LocalDateTime.class, 
     value=LocalDateTimeAdapter.class) 
}) 
package api; 

import java.time.LocalDateTime; 

import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; 
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapters; 

import api.adapter.LocalDateTimeAdapter; 

Ainsi, le marshalling et unmarshalling fonctionne sans problèmes. Et avec DTF, vous pouvez spécifier le format qui doit être appliqué.