web-dev-qa-db-fra.com

Impossible de construire une instance de Java.util.Date à partir de la valeur String - Pas une représentation valide

Désolé pour ce qui semble être une question redondante, mais j’ai beaucoup d’options, Et malgré mes efforts en lisant des dizaines de sujets, je ne suis pas en mesure de comprendre quoi faire.

J'ai une application Java dont le travail consiste à:

  1. obtenir les données d'un SOAP WS (XML), 
  2. faire un peu de logique (date de livraison entrante deviendra datebl)
  3. Enfin, envoyez-le à un REST WS (format JSON), qui mettra à jour une table Oracle.

Le plan est donc le suivant:
SOAP WS ---- livraisondate ----> APP Java (logique) ---- datebl ----> REST WS

Les fichiers Jar utilisés dans Java APP sont jackson-core-asl-1.9.13.jar et jackson-mapper-asl-1.9.13.jar, entre autres.

Les problèmes que j'ai, c'est quand il s'agit de dates.

Lectures: (Essayé d'être inspiré mais la version jackson ne semble pas être la même):

Date de sérialisation JSON dans un format personnalisé (impossible de construire une instance de Java.util.Date à partir de la valeur String)

Jackson 2.3.2: Problème de désérialisation d'une date malgré la définition du format de date sur ObjectMapper

Modifier le 01/04/15

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

Les faits maintenant  

Point 1: Lors de la récupération de données depuis SOAP WS, deliverydate est une chaîne dont la valeur exacte est: 

2014-07-31 07: 00: 00.0

Point 2: Juste avant d’utiliser le setter, j’ai pensé que ce serait une bonne idée de formater cette chaîne en une date.

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

déclaration datebl en POJO 

private Java.util.Date    datebl;

A ce stade, la valeur datebl a été transformée en 

Jeu. Juil. 31 07:00:00 CEST 2014

(malgré le choix du format spécifique aaaa-MM-jj HH: mm: ss)

Point 3 et ERROR i have: L'erreur que j'ai est renvoyée par le serveur de repos:

Impossible de construire une instance de Java.util.Date à partir de la valeur de chaîne 'Jeu 31 juil. 07:00:00 CEST 2014': représentation non valide (erreur: impossible Date d'analyse "Jeu juil. 31 07:00:00 CEST 2014 ": non compatible avec l’un des Formulaires standard (" aaaa-MM-jj'HH: mm: ss.SSSZ ", " Aaaa-MM -dd'T'HH: mm: ss.SSS'Z '"," EEE, jj MMM aaaa HH: mm: ss zzz ", " aaaa-MM-jj ")) à [Source: org.glassfish.jersey.message.internal.EntityInputStream@5709779; ligne: 1, colonne: 74] (par la chaîne de référence: com.rest.entities.MvtSwapsIn ["datebl"])

Ce que j'ai essayé de faire: Pour résoudre ce problème, étant donné que j'utilise une version antérieure à la version 2.x, je pensais que ma meilleure option consistait à utiliser un sérialiseur personnalisé.

  • En pojo, l'annotation a été ajoutée juste avant le getter

    @JsonSerialize(using = CustomJsonDateSerializer.class)
        public Java.util.Date getDatebl() {
            return datebl;
        }
    
  • Le sérialiseur a été créé comme suit

    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);       
    }
    

    }

Par exemple, essayé avec FORMAT_HEURE_JSON_SERIALIZE_2, mais beaucoup d’autres essayés sans succès.

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");

À ce stade, je suis perdu. 

Je ne sais pas où et comment mettre à jour mon code. 

  1. Devrais-je toujours utiliser SimpleDateFormat après avoir obtenu la date de SOAP ws?
  2. Étant donné que j'utilise Jackson 1.9, mon annotation @JsonSerialize est-elle bonne? (ainsi que le sérialiseur?)
  3. Dois-je modifier quelque chose sur le serveur de repos?

S'il vous plaît, quelqu'un peut-il m'aider à organiser mes pensées?

Sincères amitiés,

Pierre

7
Tanc

Ouvrez votre POJO, annotez la déclaration du champ de date comme suit

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

Où your_date_pattern peut être quelque chose comme

yyyy-MM-dd HH:mm:ss

Terminé

6
Chris J Kikoti

Je suppose que vous utilisez Jersey comme implémentation JAX-RS. Avez-vous laissé des détails dans la pile? En lisant le stacktrace, il semble que le maillot reçoive une chaîne au lieu d'une date: Can not construct instance of Java.util.Date from String value 'Thu Jul 31 07:00:00 CEST 2014'. Si votre classe com.rest.entities.MvtSwapsIn["datebl"]) déclare une date, ce comportement est un peu étrange. 

Quoi qu'il en soit, pour que Jackson fonctionne, une suggestion consiste à enregistrer un objet ObjectMapper de Jackson dans la configuration REST avec un ContextResolver (cela s'applique à la fois à Jackson 1.x et à 2.x). Essayez de placer un point d'arrêt à la fois dans le constructeur et dans la méthode getContext () pour voir s'ils sont appelés à l'exécution:

public class ObjectMapperConfigContextResolver implements     ContextResolver<ObjectMapper> {

ObjectMapper mapper;

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

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

}

L'annotation @Provider doit permettre à JAX-RS de sélectionner votre ObjectMapper configuré. Si non, vous pouvez le faire manuellement:

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

Il serait utile que vous fournissiez des informations à partir de votre fichier pom.xml (si vous utilisez Maven).

1
thomas77

Merci beaucoup Jim, Jon.

Thomas. Même si j’ai trouvé une solution de contournement, je vérifierai ce que vous avez écrit avec soin.

Néanmoins, j’ai finalement réussi à résoudre ce problème. Comme je n’étais pas en mesure de comprendre si le problème était lié à la sérialisation (JavaApp), j’ai décidé de jeter un coup d’œil à la désérialisation (REST WS).

Rappel rapide: SOAP WS ----> APP Java ----> REST WS

La date de réception de SOAP WS a été exactement reçue sous forme de chaîne, sa valeur était 

2014-07-31 07: 00: 00.0

Dans Java App , je l'ai fait 

            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);

À ce stade, j’avais toujours la même erreur jusqu’à ce que j’ai vu que JSON était envoyé à REST WS était 

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

* Certaines parties de JSON Object ont été coupées.

Dans REST WS , j'ai ajouté ce qui suit au pojo (Probablement l'un d'entre eux est nécessaire) et créé un désérialiseur personnalisé comme suit:

@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);
        }

    }
}

À ce stade, la mise à jour a été effectuée correctement. La date a été trouvée dans la base de données dans un format approprié.

Lectures: Comment convertir "Mon Jun 18 00:00:00 IST 2012" en 18/06/2012?

0
Tanc