Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CXF JAXRS - How do I pass Date as QueryParam

I have a service defined as follows.

public String getData(@QueryParam("date") Date date)

I'm trying to pass a java.util.Date to it from my client (which is jaxrs:client of CXF, not a generic HTTP client or browser).

My service receives the date as Thu Mar 01 22:33:10 IST 2012 in the HTTP URL. Since CXF won't be able to create a Date object using this String, my client receives a 404 error. I tried using a ParameterHandler on the service side, but I still can't parse it successfully because I'm not expecting the date in any specific format.

As per this post, passing a Date is supposed to work out of the box, but I can't seem to get the basic case working. Am I required to do anything in order to successfully pass a Date object from my client to service? Appreciate any help.

Thanks

like image 331
domino Avatar asked Mar 01 '12 17:03

domino


People also ask

What is Jaxrs Cxf?

JAX-RS: Java API for RESTful Web Services is a Java programming language API that provides support in creating web services according to the Representational State Transfer (REST) architectural style. CXF supports JAX-RS 2.1 (JSR-370), 2.0 (JSR-339) and 1.1 (JSR-311).


1 Answers

The problem is that JAX-RS dictates that parameter unbundling be done in one of two ways:

  1. The parameter bean has a public constructor that accepts a String
  2. The parameter bean has a static valueOf(String) method.

In your case, the Date is being unbundled via its Date(String) constructor, which cannot handle the input format your client is sending. You have a couple options available to remedy this:


Option 1

Get your client to change the format of the date before they send it. This is the ideal, but probably the hardest to accomplish!


Option 2

Handle the crazy date format. The options for this are:

Change your method signature to accept a string. Attempt to construct a Date object out of that and if that fails, use your own custom SimpleDateFormat class to parse it.

static final DateFormat CRAZY_FORMAT = new SimpleDateFormat("");  public String getData(@QueryParam("date") String dateString) {     final Date date;     try {         date = new Date(dateString); // yes, I know this is a deprecated method     } catch(Exception e) {         date = CRAZY_FORMAT.parse(dateString);     } } 

Define your own parameter class that does the logic mentioned above. Give it a string constructor or static valueOf(String) method that invokes the logic. And an additional method to get the Date when all is said and done.

public class DateParameter implements Serializable {     public static DateParameter valueOf(String dateString) {         try {             date = new Date(dateString); // yes, I know this is a deprecated method         } catch(Exception e) {             date = CRAZY_FORMAT.parse(dateString);         }     }      private Date date;     // Constructor, Getters, Setters }  public String getData(@QueryParam("date") DateParameter dateParam) {     final Date date = dateParam.getDate(); } 

Or finally, you can register a parameter handler for dates. Where its logic is simply the same as mentioned for the other options above. Note that you need to be using at least CXF 2.5.3 in order to have your parameter handler evaluated before it tries the default unbundling logic.

public class DateHandler implements ParameterHandler<Date> {     public Map fromString(String s) {         final Date date;         try {             date = new Date(dateString); // yes, I know this is a deprecated method         } catch(Exception e) {             date = CRAZY_FORMAT.parse(dateString);         }     } } 
like image 168
Perception Avatar answered Sep 22 '22 07:09

Perception