JSON Jackson ObjectMapper ReadValue - Error in converting date

23,158

Solution 1

I was able to get this done using custom deserializer and mixins. Code Below -

import java.io.IOException;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

import javax.xml.datatype.DatatypeConfigurationException;
import javax.xml.datatype.DatatypeConstants;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;

import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;

public class TestJSONDeserialize {

    public static void main(String[] args){

        ObjectMapper mapper = new ObjectMapper();
        mapper.addMixIn(Data.class, NewMixin.class);

        String jsonString = "{\"date\":\"2014-02-10\",\"time\":\"16:15:00\"}";
        Data data = null;
        try {
            data = mapper.readValue(jsonString, Data.class);
        } catch (JsonParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (JsonMappingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        if(data != null){
            System.out.println(" Data " + data.getDate());
            System.out.println(" Data " + data.getTime());
        }   
    }


}



import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.GregorianCalendar;

import javax.xml.datatype.DatatypeConfigurationException;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;

public class CustomDateDeserializer extends JsonDeserializer<XMLGregorianCalendar> {

    private static SimpleDateFormat formatter = 
      new SimpleDateFormat("yyyy-MM-dd");


    @Override
    public XMLGregorianCalendar deserialize(JsonParser jsonparser, DeserializationContext arg1) throws IOException, JsonProcessingException {
        // TODO Auto-generated method stub
        String date = jsonparser.getText();
        try {

            GregorianCalendar c = new GregorianCalendar();
            c.setTime(formatter.parse(date));
            XMLGregorianCalendar date2 = null;
            try {
                date2 = DatatypeFactory.newInstance().newXMLGregorianCalendar(c);
            } catch (DatatypeConfigurationException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

            return date2;
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }
    }
}




import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.GregorianCalendar;

import javax.xml.datatype.DatatypeConfigurationException;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;

public class CustomTimeDeserializer extends JsonDeserializer<XMLGregorianCalendar> {

    private static SimpleDateFormat formatter = 
      new SimpleDateFormat("hh:mm:ss");


    @Override
    public XMLGregorianCalendar deserialize(JsonParser jsonparser, DeserializationContext arg1) throws IOException, JsonProcessingException {
        // TODO Auto-generated method stub
        String date = jsonparser.getText();
        try {

            GregorianCalendar c = new GregorianCalendar();
            c.setTime(formatter.parse(date));
            XMLGregorianCalendar date2 = null;
            try {
                date2 = DatatypeFactory.newInstance().newXMLGregorianCalendar(c);
            } catch (DatatypeConfigurationException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

            return date2;
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }
    }
}



import javax.xml.datatype.XMLGregorianCalendar;

import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;

abstract class NewMixin {

    @JsonDeserialize(using = CustomDateDeserializer.class)
    public abstract void setDate(XMLGregorianCalendar date);

    @JsonDeserialize(using = CustomTimeDeserializer.class)
    public abstract void setTime(XMLGregorianCalendar time);
}

Solution 2

See here. Stick a date formatter on your field:

@JsonFormat(shape=JsonFormat.Shape.STRING, pattern="HH:mm:ss", timezone="CET")
private Date startTime;

Solution 3

Already answered in this old post, but hope this will be helpful for someone in future.

Specifying DateFormat in ObjectMapper solved my issue.

objectMapper.setDateFormat(new SimpleDateFormat(MY_FORMAT));
Share:
23,158
Punter Vicky
Author by

Punter Vicky

Updated on April 27, 2020

Comments

  • Punter Vicky
    Punter Vicky about 4 years

    I am seeing the error listed below when trying to convert the json string to an object. I don't have the source code for Data class & it is part of a jar file. Is there a way I could use mixins to get this fixed?

    CODE

    ObjectMapper mapper = new ObjectMapper();
    mapper.readValue(request, Data.class);
    

    ERROR

    org.codehaus.jackson.map.JsonMappingException: Can not construct instance of javax.xml.datatype.XMLGregorianCalendar from String value '10:00:00': not a valid representation (error: Can not parse date "10:00:00": not compatible with any of standard forms ("yyyy-MM-dd'T'HH:mm:ss.SSSZ", "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", "EEE, dd MMM yyyy HH:mm:ss zzz", "yyyy-MM-dd"))

    JSON REQUEST

     "timeSlot":{  
           "date":"2015-10-21",
           "endTime":"10:00:00",
           "startTime":"08:00:00",   
     }
    

    EDIT

    This issue is similar to this , however this is occuring while deserializing. The other solution helped in appropriately serializing the request.

    I have pasted the sample code which is not working below -

    import java.io.IOException;
    import java.text.DateFormat;
    import java.text.ParseException;
    import java.text.SimpleDateFormat;
    import java.util.Calendar;
    import java.util.Date;
    import java.util.GregorianCalendar;
    
    import javax.xml.datatype.DatatypeConfigurationException;
    import javax.xml.datatype.DatatypeConstants;
    import javax.xml.datatype.DatatypeFactory;
    import javax.xml.datatype.XMLGregorianCalendar;
    
    import com.fasterxml.jackson.core.JsonParseException;
    import com.fasterxml.jackson.core.JsonProcessingException;
    import com.fasterxml.jackson.databind.JsonMappingException;
    import com.fasterxml.jackson.databind.ObjectMapper;
    import com.fasterxml.jackson.databind.SerializationFeature;
    
    public class TestJSONDeserialize {
    
        public static void main(String[] args){
    
            ObjectMapper mapper = new ObjectMapper();
            mapper.addMixIn(Data.class, MyMixin.class);
    
            String jsonString = "{\"date\":\"2014-02-10\",\"time\":\"16:15:00\"}";
            try {
                mapper.readValue(jsonString, Data.class);
            } catch (JsonParseException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (JsonMappingException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
    
        }
    
    
    }
    

    Data class (I cannot make changes to this file)

    import javax.xml.datatype.XMLGregorianCalendar;
    
    public class Data {
    
        private XMLGregorianCalendar date;
        private XMLGregorianCalendar time;
    
        public XMLGregorianCalendar getDate() {
            return date;
        }
        public void setDate(XMLGregorianCalendar date) {
            this.date = date;
        }
        public XMLGregorianCalendar getTime() {
            return time;
        }
        public void setTime(XMLGregorianCalendar time) {
            this.time = time;
        }
    
    
    
    }
    

    I see the below error when I run this :

    com.fasterxml.jackson.databind.exc.InvalidFormatException: Can not construct instance of javax.xml.datatype.XMLGregorianCalendar from String value '16:15:00': not a valid representation (error: Failed to parse Date value '16:15:00': Can not parse date "16:15:00": not compatible with any of standard forms ("yyyy-MM-dd'T'HH:mm:ss.SSSZ", "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", "EEE, dd MMM yyyy HH:mm:ss zzz", "yyyy-MM-dd")) at [Source: {"date":"2014-02-10","time":"16:15:00"}; line: 1, column: 21] (through reference chain: com.comcast.json.test.Data["time"])

  • Punter Vicky
    Punter Vicky over 8 years
    Thank You. I don't have the java file with me but I am using a class that is part of a jar which was provided by different team. I wouldn't be able to modify the class containing this field. I also cannot set a generic date time format for the whole class because date is yyyy-MM-dd and time is hh:mm:ss