La sérialisation de Date en Java
Je suis de passage autour de certains objets par le biais du service web et certains d'entre eux contiennent java.sql.Date. Parce que la Date n'a pas de constructeur vide, il ne veut pas être sérialisé.
Première partie de la question est simple: quelle est la meilleure façon de passer une date entre le client et le service?
Deuxième partie est un peu plus compliqué: une Fois que j'ai décider de la façon de passer les dates autour, je peux évidemment déclarer date transitoire et de faire une certaine classe wrapper pour passer les dates que Chaîne ou que ce soit, mais comment appliquer la même solution que dans la manière la plus transparente possible pour plusieurs classes qui comprennent la Date?
(J'ai un pressentiment que DynamicProxy truc pourrait être une solution, mais la lecture de la documentation sur les Chaises du site n'était pas très utile, donc si c'est vraiment quelque chose dans cette direction, quelques précisions seraient appréciées)
Edit: j'ai demandé à une fausse question, désolé (un malentendu entre moi et le collègue de ce qui est réellement un problème). Problème se produit en raison de la désérialisation. Donc, une fois que j'ai une date au format xml, il tente de désérialiser lui-même comme GregorianCalendar. D'autres part d'une question demeure: Quelle est la meilleure façon de recevoir quelque chose (long ou d'horodatage GregorianCalendar) et le convertir en sql date, sans faire 10 wrappers pour 10 classes différentes. J'utilise NetBeans pour le code et la génération wsdl.
OriginalL'auteur Slartibartfast | 2008-09-22
Vous devez vous connecter pour publier un commentaire.
Joda-Time
La classe Date est un maladroit API. Une meilleure mise en œuvre est Joda-Time.
ISO 8601
Joda-Time permet également de convertir votre date dans un ISO 8601 standard au format (aaaa-mm-jjthh:MM:SS.SSS). L'utilisation de cette norme lors du déplacement de la date de serveur de son client, a l'avantage d'inclure la date dans un format lisible. Lorsque vous utilisez par exemple JAXB, la représentation XML d'une date est également cette norme ISO. (voir la XMLGregorianCalendar classe)
Merci! Ne le savais pas moi-même. Enfin, une meilleure Date de mise en œuvre.
Bel article sur la nouvelle API: today.java.net/pub/a/today/2008/09/18/...
OriginalL'auteur JeroenWyseur
De la sérialisation du long retourné par Jour.getTime() comme suggéré précédemment fonctionne. Vous devriez noter que si votre serveur se trouve dans un autre fuseau horaire que le client, de la date à laquelle vous allez reconstruire de l'autre côté sera différent. Si vous voulez reconstruire exactement le même objet date, vous devez également envoyer votre time zone (Fuseau horaire.getID()) et de l'utiliser pour reconstruire la date de l'autre côté.
si vous sérialiser des 2pm à Paris, vous allez obtenir 8h si vous désérialiser le même flux sur un ordinateur configuré pour le NYC fuseau horaire. Si vous souhaitez planifier une réunion, c'est ok parce que vous voulez tout le monde à assister à la même heure. Mais si vous avez besoin d'afficher des informations contractuelles (ex: cette option expire 2pm à Paris), alors vous devez envoyer le fuseau horaire pour new york ordinateur à la figure, c'est de 2pm et pas 8h, et btw, à Paris. D'affaires il existe des cas pour les deux situations, l'envoi, le long de la zone de l'heure est toujours à l'abri, sauf si vous avez des strictes contraintes de bande passante.
OriginalL'auteur entzik
Pour répondre à la première partie de votre question, je dirais une chaîne de caractères au format iso 8601 (c'est une norme de codage pour les dates).
Pour la deuxième partie, je ne sais pas pourquoi vous auriez besoin d'une classe proxy? Ou pourquoi vous doit étendre la classe date. par exemple. ne serait pas de votre service web savoir qu'un certain champ est un champ de date et de faire la conversion à partir de la date à la chaîne et au retour elle-même? J'avais besoin d'un peu plus d'informations.
OriginalL'auteur Chris Gow
java.sql.Date étend java.util.Date
Suffit d'utiliser getTime() pour obtenir la valeur de type long. Cela peut être sérialisé et un nouveau java.sql.Date(long) ou java.util.Date(long) construit à partir à l'autre extrémité.
OriginalL'auteur cagcowboy
J'ai regardé dans la mise en œuvre de java.sql.Date et que je vois c'java.sql.La Date est Sérialisable comme une extension de java.util.Date.
OriginalL'auteur boutta
une mise en garde avec java.sql.Date qui peu me récemment est qu'il ne stocke pas les portions du temps (heures, minutes, secondes, etc) il suffit de la date de la partie. si vous voulez le plein d'horodatage, vous devez utiliser java.util.Date ou java.sql.Timestamp
OriginalL'auteur Matt
Je vais développer sur le bonne réponse par JeroenWyseur.
ISO 8601
La ISO 8601 format standard est absolument la meilleure façon de sérialiser une date-valeur du temps pour l'échange de données. Le format est sans ambiguïté, intuitive peuples à travers les cultures, et de plus en plus courants dans le monde. Facile à lire pour les humains et les machines.
Le premier exemple a un décalage de deux heures à l'avance de l'heure UTC. Le deuxième exemple montre l'utilisation commune de
Z
("Zoulou") pour indiquer l'heure UTC, court pour+00:00
.Joda-Time & java.temps
La java.util.Date & .Calendrier des classes livré avec Java sont très ennuyeux, déroutant, et vicié. Les éviter. Au lieu de cela, utilisez:
Par défaut, les deux bibliothèques utiliser le format ISO 8601 pour à la fois d'analyse et de génération de représentations de Chaîne de date-heure de valeurs.
Noter que java.le temps s'étend le format ISO 8601 en ajoutant le nom propre de l'fuseau horaire, comme
2007-12-03T10:15:30+01:00[Europe/Paris]
.De recherche StackOverflow.com pour plusieurs centaines de Questions et de Réponses avec beaucoup de discussion et un exemple de code pour ces deux bibliothèques.
Éviter Le Comte-De-Époque
Certains des autres réponses vous recommandons d'utiliser un nombre, un nombre de époque. Cette approche n'est pas pratique. Il n'est pas évident. Il n'est pas lisible par l'homme, faisant de débogage pénible et frustrant.
Nombre de qui est-il, en secondes fréquemment utilisés dans les Unix, millisecondes utilisé en java.util.Date & Joda-Time, microsecondes couramment utilisé dans les bases de données comme Postgresql, ou nanosecondes utilisé dans java.en temps?
Qui de la quelques dizaines époques, premier moment de 1970 utilisée sous Unix, année 1 utilisé dans .Net & Aller, "janvier 0, 1900" utilisé dans des millions (des milliards?) de Excel & Lotus, feuilles de calcul, ou le 1er janvier 2001 utilisé par Cacao?
Voir ma réponse sur une question similaire, pour plus de discussion.
OriginalL'auteur Basil Bourque
Vous n'avez pas besoin de constructeur par défaut (vide) afin de sérialiser/désérialiser date (java.sql.Date ou java.util.La Date). Lors de la désérialisation constructeur n'est pas appelé mais les attributs de l'objet de définir directement les valeurs de données sérialisées et vous pouvez utiliser l'objet tel qu'il est car il désérialisé.
OriginalL'auteur Andreas Bakurov
Vous pouvez utiliser un encodeur et décodeur de serialise et deserialise vos objets.
Voici un exemple qui serialises la SWT classe Rectangle:
OriginalL'auteur paul
Tout d'abord, si vous êtes en utilisant les services web, cela signifie que vous êtes la sérialisation XML et non réguliers de votre sérialisation Java (mais une autre bibliothèque pour le marshaling et désordonnancement). La question est donc de manquer de certaines informations.
Seconde, si vous avez le contrôle sur votre InputStream & OutputStream essayez étendre ObjectOutputStream et ObjectInputStream et remplacer replaceObject() et resolveObject() et puis vous pouvez mettre en œuvre la sérialisation java.sql.Date.
OriginalL'auteur Shimi Bandiel
java.sql.Date déjà implémente Serializable donc pas besoin de le mettre en œuvre 🙂
En ce qui concerne votre question principale, je suis profondément en amour avec JAXB que je peux mettre presque n'importe quel document XML dans un objet, de sorte qu'il pourrait être utile de votre temps à le regarder.
OriginalL'auteur Ioannis
Hmmm... Peut pas penser à une raison pourquoi tout objet sérialisé instance (sérialisé via le java par défaut mécanisme) devrait désérialiser lui-même comme une instance d'une autre classe que la classe de l'information devrait faire partie intégrante des données sérialisées.
Donc c'est soit un problème de votre (dé-)sérialisation cadre ou le cadre accepte tout "date" comme objet sur la "fin de l'envoi" (Calendrier, java.util.Date etc. - ainsi, java.sql.Date de trop car il s'étend java.util.Date), "sérialise" à une Chaîne dans certaines communes de la date format (de sorte que le type de l'information est perdue) et "désérialise" retour à un Calendrier de l'objet sur l'extrémité de réception.
Donc je pense que le moyen le plus simple pour se rendre à java.sql.La Date est de faire un
où vous avez besoin d'une java.sql.Date mais le GregorianCalendar dos de la "sérialisation".
OriginalL'auteur Argelbargel