Converting ZonedDateTime type to Gson

后端 未结 4 1939
梦谈多话
梦谈多话 2021-01-18 10:33

I have rest service that return arraylist of object,and I have implemented jersy restful client to execute it,but I have problem in converting ZonedDateTime type to json so

4条回答
  •  甜味超标
    2021-01-18 10:44

    There are at least two ways to achieve this:

    1) Gson with JsonDeserializer

    Little changes within your code:

    Type listType =  new TypeToken>() {}.getType();
    List scorefactors = new GsonBuilder()
                .registerTypeAdapter(ZonedDateTime.class, GsonHelper.ZDT_DESERIALIZER)
                .create()
                .fromJson(output, listType);
    

    Helper Class

    class GsonHelper {
    
        public static final JsonDeserializer ZDT_DESERIALIZER = new JsonDeserializer() {
            @Override
            public ZonedDateTime deserialize(final JsonElement json, final Type typeOfT, final JsonDeserializationContext context) throws JsonParseException {
                JsonPrimitive jsonPrimitive = json.getAsJsonPrimitive();
                try {
    
                    // if provided as String - '2011-12-03T10:15:30+01:00[Europe/Paris]'
                    if(jsonPrimitive.isString()){
                        return ZonedDateTime.parse(jsonPrimitive.getAsString(), DateTimeFormatter.ISO_ZONED_DATE_TIME);
                    }
    
                    // if provided as Long
                    if(jsonPrimitive.isNumber()){
                        return ZonedDateTime.ofInstant(Instant.ofEpochMilli(jsonPrimitive.getAsLong()), ZoneId.systemDefault());
                    }
    
                } catch(RuntimeException e){
                    throw new JsonParseException("Unable to parse ZonedDateTime", e);
                }
                throw new JsonParseException("Unable to parse ZonedDateTime");
            }
        };
    
    }
    

    2) Use MessageBodyReader & XMLAdapter

    Changes for your Client implementation:

    ClientConfig config = new DefaultClientConfig();
    config.getFeatures().put(JSONConfiguration.FEATURE_POJO_MAPPING, Boolean.TRUE);
    Client client = Client.create(config);
    
    List result = client.resource("http://localhost:8080/adap/api/getScoreFactor"")
                    .accept("application/json")
                    .get(ClientResponse.class)
                    .getEntity(new GenericType>(){});
    
    System.out.println(result);
    

    You might need to import jersey-json for this

    
        com.sun.jersey
        jersey-bundle
        1.19.1
    
    
        com.sun.jersey
        jersey-json
        1.19.1
    
    

    Btw, why do you use 1.*?

    Your Scorefactor

    @XmlRootElement
    @XmlAccessorType(XmlAccessType.FIELD)
    public class Scorefactor implements Serializable {
    
        @Column(name = "lastmodifieddate")
        @XmlElement(name = "lastmodifieddate")
        @XmlJavaTypeAdapter(ZonedDateTimeToStringXmlAdapter.class)
        private ZonedDateTime lastmodifieddate;
    
        //...
    

    ZonedDateTime from / to String (recommended)

    public class ZonedDateTimeToStringXmlAdapter extends XmlAdapter {
    
        @Override
        public ZonedDateTime unmarshal(final String v) throws DateTimeParseException {
            return ZonedDateTime.parse(v);
        }
    
        @Override
        public String marshal(final ZonedDateTime v) throws Exception {
            return v.toString();
        }
    
    }
    

    ZonedDateTime from / to Long

    public class ZonedDateTimeToLongXmlAdapter extends XmlAdapter {
    
        @Override
        public ZonedDateTime unmarshal(final Long v) throws DateTimeParseException {
            return ZonedDateTime.ofInstant(Instant.ofEpochMilli(v.longValue()), ZoneId.systemDefault()); 
        }
    
        @Override
        public Long marshal(final ZonedDateTime v) throws Exception {
            return Long.valueOf(v.toInstant().toEpochMilli());
        }
    
    }
    

    You could also build your own MessageBodyReader/MessageBodyWriter or use other implementations like Moxy.

    I would like to recommend to use Jersey 2.*.

    Hope this was helpful somehow. Have a nice day.

提交回复
热议问题