9

Sorry for what it seems to be a redundant question but i do have many options, and despite my effort reading dozen of threads, i'm not able to understand what to do.

I do have a java application which job is to :

  1. get datas from a SOAP WS (XML),
  2. do some logic ( incoming deliverydate will become datebl )
  3. Finally send it to a REST WS (JSON Format), which will update an Oracle Table

Plan is thus as follows :
SOAP WS ---- deliverydate ----> JAVA APP (logic) ---- datebl ----> REST WS

Jar used in JAVA APP are jackson-core-asl-1.9.13.jar and jackson-mapper-asl-1.9.13.jar among others.

Issues i have is when dealing with dates.

Readings : ( Tried to be inspired but jackson version seems not to be the same ) :

JSON Serializing date in a custom format (Can not construct instance of java.util.Date from String value)

Jackson 2.3.2: Issue with deserializing a Date despite of setting the date format to ObjectMapper

Edit 01/04/15

http://jackson-users.ning.com/forum/topics/cannot-deserialize-a-date

The facts now

Point 1 : When recovering data from SOAP WS, deliverydate is a String which exact value is :

2014-07-31 07:00:00.0

Point 2: Just before using the setter, i thought it could be a good idea to format this String to a date.

SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                                    Date dateebl = dateFormat.parse(deliverydate);
                                    msi.setDatebl(dateebl);

datebl declaration in POJO

private java.util.Date    datebl;

At this stage, datebl value has transformed to

Thu Jul 31 07:00:00 CEST 2014

(despite choosing the specific format yyyy-MM-dd HH:mm:ss)

Point 3 and ERROR i have : The error i have is thrown by the rest server:

Can not construct instance of java.util.Date from String value 'Thu Jul 31 07:00:00 CEST 2014': not a valid representation (error: Can not parse date "Thu Jul 31 07:00:00 CEST 2014": 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: org.glassfish.jersey.message.internal.EntityInputStream@5709779; line: 1, column: 74] (through reference chain: com.rest.entities.MvtSwapsIn["datebl"])

What i tried to do : To resolve this, as i'm using a version prior to 2.x, i thought that my best option was to use a custom serializer, so :

  • In pojo, annotation was added just before the getter

    @JsonSerialize(using = CustomJsonDateSerializer.class)
        public java.util.Date getDatebl() {
            return datebl;
        }
    
  • Serializer was created as follows

    public class CustomJsonDateSerializer extends JsonSerializer<Date> {
    
    @Override
    public void serialize(Date value, JsonGenerator jgen,
            SerializerProvider provider) throws IOException,
            JsonProcessingException {
        SimpleDateFormat dateFormat = new SimpleDateFormat(Properties.General.FORMAT_HEURE_JSON_SERIALIZE_2);
        String dateString = dateFormat.format(value);
        jgen.writeString(dateString);       
    }
    

    }

In example,tried with FORMAT_HEURE_JSON_SERIALIZE_2, but tried many others without success.

public static final String  FORMAT_HEURE_JSON               = new String("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
public static final String  FORMAT_HEURE_JSON_SERIALIZE     = new String("EEE yyyy-MM-dd'T'HH:mm:ss.SSSZ");
public static final String  FORMAT_HEURE_JSON_SERIALIZE_2   = new String("EEE, dd MMM yyyy HH:mm:ss zzz");
public static final String  FORMAT_HEURE_JSON_SERIALIZE_3   = new String("yyyy-MM-dd HH:mm:ss");

At this point, i'm lost.

I don't know where and how to update my code.

  1. Should i still use SimpleDateFormat after getting date from SOAP ws ?
  2. Given the fact i'm using jackson 1.9, is my @JsonSerialize annotation good ? ( as well as the serializer ?)
  3. Do i have to modify something on the rest server ?

Please can someone help me organize my thoughts ?

Kind regards,

Pierre

3
  • 1
    "At this stage, datebl value has transformed to [... string representation ...]" - No, it's been transformed into a Date. A Date object is just a number of milliseconds since the Unix epoch. It doesn't have any concept of a string representation as part of its state. You're looking at the result of calling Date.toString, which is just using some default formatting. Commented Mar 31, 2015 at 22:31
  • Tanc, You've missed some useful information. "In example,tried with FORMAT_HEURE_JSON_SERIALIZE_2, but tried many others without success." What does "without success" mean? What is the exact error you are getting at this point? Commented Mar 31, 2015 at 23:18
  • Thanks Jon for clarifying this point. Tim, sorry for being so unclear. I meant that whatever date formatting i'm using, yyyy-MM-dd'T'HH:mm:ss.SSSZ,EEE yyyy-MM-dd'T'HH:mm:ss.SSSZ, EEE, dd MMM yyyy HH:mm:ss zzz or yyyy-MM-dd HH:mm:ss, still have the same rest server side error . "Can not construct instance of java.util.Date from String value" I even tried not to use @JsonSerialize(using = CustomJsonDateSerializer.class) and it is still doing the same error. Thanks for your help. Commented Apr 1, 2015 at 6:15

3 Answers 3

14

Open your POJO, annotate the date field declaration like so

@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "<your_date_pattern>")

Where your_date_pattern can be something like

yyyy-MM-dd HH:mm:ss

Done

Sign up to request clarification or add additional context in comments.

1 Comment

+1, <your_date_pattern> can also be any date formate,Example: dd-MM-yyyy, JsonFormat will convert to DB acceptable format like "yyyy-MM-dd"
1

I guess you are using Jersey as a JAX-RS implementation. Have you left some details out from the stacktrace? Reading the stacktrace it seems the Jersey receives a String instead of a Date: Can not construct instance of java.util.Date from String value 'Thu Jul 31 07:00:00 CEST 2014'. If your class com.rest.entities.MvtSwapsIn["datebl"]) declares a date, this behaviour is a bit strange.

Anyway, for Jackson to work, one suggestion is to register a Jackson ObjectMapper to the REST config with a ContextResolver (this applies to both Jackson 1.x and 2.x). Try putting a breakpoint in both the constructor and getContext()-method to see if they are invoked at runtime:

public class ObjectMapperConfigContextResolver implements     ContextResolver<ObjectMapper> {

ObjectMapper mapper;

public ObjectMapperConfigContextResolver() {
    mapper.setDateFormat(new SimpleDateFormat("<your pattern>"));
}

@Override
public ObjectMapper getContext(Class<?> type) {
    return mapper;
}

}

The @Provider annotation should make JAX-RS pick up your configured ObjectMapper. If no you can do it manually:

@ApplicationPath("/")
public class RestApplication extends Application {
    @Override
    public Set<Class<?>> getClasses() {
        Set<Class<?>> classes = new HashSet<>();
        classes.add(ObjectMapperConfigContextResolver.class);
        return classes;
    }
}

It would be helpful if you provided some information from your pom.xml (if you are using Maven).

Comments

0

Thanks a lot Jim, Jon.

Thomas. Even if i found a workaround, i will check what you wrote carefully.

Nevertheless,i finally managed to solve this. As i was not able to understand if problem was on Serialization(JavaApp) i've decided to have a look on the other side Deserialization(REST WS).

Quick reminder : SOAP WS ----> JAVA APP ----> REST WS

Date received from SOAP WS was exactly received as String, its value was

2014-07-31 07:00:00.0

Within JAVA App, i did

            DateFormat originalFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss.S");
            DateFormat targetFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            Date date = originalFormat.parse(deliverydate);
            String formattedDate = targetFormat.format(date); 

            msi.setDatebl(date);

At this point, i had still the same error until i saw that JSON sent to REST WS was

{"id":87434958,"datebl":"Thu Jul 31 07:00:00 CEST 2014","price":15.45,"model":"AAA"}

*Some parts of JSON Object were cutted.

Within REST WS, i've added the following to the pojo (Probably one of them is necessary) and created a custom deserializer as follows :

@JsonDeserialize(using = CustomJsonDateDeserializer.class)
private java.util.Date    datebl;

@JsonDeserialize(using = CustomJsonDateDeserializer.class)
public void setDatebl(java.util.Date datebl) {
    this.datebl = datebl;
}



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

import org.codehaus.jackson.JsonParser;
import org.codehaus.jackson.JsonProcessingException;
import org.codehaus.jackson.map.DeserializationContext;
import org.codehaus.jackson.map.JsonDeserializer;



public class CustomJsonDateDeserializer extends JsonDeserializer<Date>
{
    @Override
    public Date deserialize(JsonParser jsonparser,
            DeserializationContext deserializationcontext) throws IOException, JsonProcessingException {

        DateFormat formatter = new SimpleDateFormat("EEE MMM dd HH:mm:ss z yyyy", Locale.US);
        String dateStr = jsonparser.getText();
        try {
            return (Date)formatter.parse(dateStr);
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }

    }
}

At this point, update has been done properly. Date was found in database in a proper format.

Readings : How to convert "Mon Jun 18 00:00:00 IST 2012" to 18/06/2012?

2 Comments

Jackson has the setDateFormat method as a convenience method as it provides built-in serializers for dates so you don't have to write them :)
public ObjectMapper setDateFormat(DateFormat dateFormat) { _deserializationConfig = _deserializationConfig.with(dateFormat); _serializationConfig = _serializationConfig.with(dateFormat); return this; }

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.