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

Community
  • 1
  • 1
Tanc
  • 667
  • 3
  • 6
  • 25
  • 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. – Jon Skeet Mar 31 '15 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? – Tim Mar 31 '15 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. – Tanc Apr 01 '15 at 06:15

3 Answers3

13

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

shashwat
  • 7,851
  • 9
  • 57
  • 90
Christopher Kikoti
  • 2,487
  • 1
  • 24
  • 29
  • +1, can also be any date formate,Example: dd-MM-yyyy, JsonFormat will convert to DB acceptable format like "yyyy-MM-dd" – Allahbakash.G Sep 18 '18 at 14:00
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).

thomas77
  • 1,100
  • 13
  • 27
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?

Community
  • 1
  • 1
Tanc
  • 667
  • 3
  • 6
  • 25
  • 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 :) – thomas77 Apr 01 '15 at 10:48
  • public ObjectMapper setDateFormat(DateFormat dateFormat) { _deserializationConfig = _deserializationConfig.with(dateFormat); _serializationConfig = _serializationConfig.with(dateFormat); return this; } – thomas77 Apr 01 '15 at 10:48