Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

This is what I'm thinking about doing on a JEE Glassfish server using Jersey.

@GET
@Path("/{name}/{date}")
public String getMessages(@PathParam("name") String name, @PathParam("date") Date date)

I like the idea of being able to tell people consuming this RESTful webservice that "The date here is anything that works with the Date class in Java". That's pretty simple from the standpoint that they can just look at the Date spec, and they'll already have a working model that they can test with.

The problem that I'm worried about is that when I do this, JAX-RS is not very nice when Date() doesn't like what it gets in the constructor. Since Date() throws an error if it can't parse what it's given (like if you pass it the string "today" instead of a real date), the JEE server returns a 404 error.

Is this a good practice? Is there a better way to do this that I'm not thinking of?

share|improve this question
add comment

3 Answers

up vote 5 down vote accepted

Sounds like a bad idea. For one thing, the Date constructor that you'd be relying on has been deprecated since Java 1.1 in favor of DateFormat.parseDate(), precisely because it's unclear how strings should be parsed into dates, as the rules are different for different localities.

My recommendation would be to stick with a specific format, preferably the internationally understood yyyy-MM-dd, and use a DateFormat to parse the date from a string inside your service, which makes it clear how to consume the web service, and allows you to follow whatever the standard convention for returning error messages is for your web services when something goes wrong.

share|improve this answer
add comment

I'm using a custom class DateParam:

@GET
@Path("/{name}/{date}")
public String getMessages(@PathParam("name") String name, @PathParam("date") DateParam date)
  Date date = date.getDate();

The class is defined as:

public class DateParam {
  private final Date date;

  public DateParam(String dateStr) throws WebApplicationException {
    if (isEmpty(dateStr)) {
      this.date = null;
      return;
    }
    final DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
    try {
      this.date = dateFormat.parse(dateStr);
    } catch (ParseException e) {
      throw new WebApplicationException(Response.status(Status.BAD_REQUEST)
        .entity("Couldn't parse date string: " + e.getMessage())
        .build());
    }
  }

  public Date getDate() {
    return date;
  }
}

If the parameter is empty then you would get a null date. You can extend DateParam by a public static final field for undefined date values. This would make testing for undefined date params clearer.

One drawback here is that for each DateParam, a new instance of SimpleDateFormat is created. However, since SimpleDateFormat is not thread-safe, we cannot reuse it easily.

share|improve this answer
add comment

Who will use your service? Will they bother to lookup the specification of the Date class and figure out what kind of strings it will parse? I wouldn't, even if being a Java programmer I would know where to look ;-)

I think you should first tell your users what your URIs will look like, e.g.

.../your-resource-name/yyyy-MM-dd

and then look for a way to have Jersey help you in parsing whatever date format you chose. That could mean using a Date parameter type and maybe specifying a regular expression in your @Path annotation, like

@Path(/{name}/{date: [0-9][0-9][0-9][0-9]-[0-1][0-9]-[0-3][0-9]/)

or using some other class capable of parsing a date in your format. How to handle URIs that don't match the spec you give to your users is yet another thing you should decide how to handle independently of any of the above (return a default resource? return a 404 error?).

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.