Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jaxb unmarshal timestamp

I cannot get JAXB to unmarshal a timestamp in a Resteasy JAX-RS server application.

My class looks like this:

@XmlAccessorType(XmlAccessType.NONE) @XmlRootElement(name = "foo") public final class Foo {     // Other fields omitted      @XmlElement(name = "timestamp", required = true)     protected Date timestamp;      public Foo() {}      public Date getTimestamp() {         return timestamp;     }      public String getTimestampAsString() {         return (timestamp != null) ? new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(timestamp) : null;     }      public void setTimestamp(final Date timestamp) {         this.timestamp = timestamp;     }      public void setTimestamp(final String timestampAsString) {         try {             this.timestamp = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(timestampAsString);         } catch (ParseException ex) {             this.timestamp = null;         }     } } 

Any ideas?

Thanks.

like image 958
Ralph Avatar asked Mar 25 '10 21:03

Ralph


People also ask

What is JAXB Unmarshal?

The JAXB Unmarshaller interface is responsible for governing the process of deserializing the XML data to Java Objects. The unmarshalling to objects can be done to variety of input sources.

What is JAXB in Java?

JAXB simplifies access to an XML document from a Java program by presenting the XML document to the program in a Java format. The first step in this process is to bind the schema for the XML document into a set of Java classes that represents the schema.


2 Answers

JAXB can handle the java.util.Date class. However it expects the format:

"yyyy-MM-dd'T'HH:mm:ss" instead of "yyyy-MM-dd HH:mm:ss"

If you want to use that date format I would suggest using an XmlAdapter, it would look something like the following:

import java.text.SimpleDateFormat; import java.util.Date;  import javax.xml.bind.annotation.adapters.XmlAdapter;  public class DateAdapter extends XmlAdapter<String, Date> {      private SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");      @Override     public String marshal(Date v) throws Exception {         return dateFormat.format(v);     }      @Override     public Date unmarshal(String v) throws Exception {         return dateFormat.parse(v);     }  } 

You would then specify this adapter on your timestamp property:

import java.util.Date;  import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;  @XmlAccessorType(XmlAccessType.NONE)  @XmlRootElement(name = "foo")  public final class Foo {      // Other fields omitted       @XmlElement(name = "timestamp", required = true)      @XmlJavaTypeAdapter(DateAdapter.class)     protected Date timestamp;       public Foo() {}       public Date getTimestamp() {          return timestamp;      }       public void setTimestamp(final Date timestamp) {          this.timestamp = timestamp;      }   } 
like image 79
bdoughan Avatar answered Sep 22 '22 17:09

bdoughan


JAXB cannot marshal Date objects directly, because they don't have enough information to be unambiguous. JAXB introduced the XmlGregorianCalendar class for this purpose, but it's very unpleasant to use directly.

I Suggest changing your timestamp field to be a XmlGregorianCalendar, and change your various methods to update this field while retaining the public interface you already have, where possible.

If you want to keep the Date field, then you'll need to implement your own XmlAdapter class to tell JAXB to how turn your Date to and from XML.

like image 43
skaffman Avatar answered Sep 21 '22 17:09

skaffman