4

I am using Jersey 1.21.1 and am getting strange behavior when unmarshalling dates.

Simplified version of my POJO:

@XmlRootElement
public class Invoice {
    private Date invoiceDate;
    private Date invoiceDate2;
}

My resource method:

@PUT
@Consumes(MediaType.APPLICATION_JSON)
public Response putInvoice(Invoice invoice) { .. }

The JavaScript code that calls this service uses JSON.stringify to produce the following HTTP request payload (this is what was actually sent, according to the Chrome debugger):

{"invoiceDate":"2015-10-27T04:00:00.000Z","invoiceDate2":"2015-10-27T08:00:00.000Z"}

So far so good. But when I stop at a breakpoint inside of putInvoice and examine the Java dates invoice.invoiceDate and invoice.invoiceDate2, they both have the same fastTime:

1445904000000

(which equals October 27, 2015 12:00:00 AM UTC).

I am at a loss why Jersey/MOXy are seemingly unable to parse what looks to me like a standard ISO UTC date. I can only assume I'm doing something wrong or making a bad assumption. Help would be greatly appreciated.

Bampfer
  • 2,120
  • 16
  • 25

1 Answers1

2

The root cause of the problem was that my POJO date field was declared to be java.sql.Date, rather than java.util.Date. The ISO format is indeed parsed correctly when unmarshalling to java.util.Date.

The obvious solution is to use java.util.Date in the POJO. But if for some reason a java.sql.Date is needed, you can write a custom XmlAdaptor to do the parsing and formatting (see answer to this SO question: jaxb unmarshal timestamp)

Additional comments: it's not all that surprising that java.sql.Date doesn't work with Jersey/MOXy out of the box, but I do find the specific failure surprising. Frankly I would have both expected and preferred a class conversion exception, like the one I got when I attempted to write my own XmlAdaptor. That's how I eventually figured out the root cause.

Since MOXy truncated the time, I'm wondering if that's because an exception in the default date-time parsing causes MOXy to fall back to date-only. But if so, how did that fallback successfully assign to java.sql.Date when the original logic couldn't? It's a mystery but not one I plan to spend any time on. (Edit: this explanation probably is wrong-- see comment)

Community
  • 1
  • 1
Bampfer
  • 2,120
  • 16
  • 25
  • Something else I should have noticed before: Jersey + MOXy does the exact same truncation when it marshals java.sql.Date. That is, when I do an HTTP GET on the resource, the date string has no time component or timezone, e.g. '2015-12-15'. So my speculation above that this was inadvertently caused by exception handling seems wrong. It's consistent and therefore feels deliberate, but I am at a loss to explain why java.sql.Date would be treated this way. – Bampfer Jan 05 '16 at 16:01