A couple of weeks ago I started a small sanbox project using the Jersey JAX-RS implementation. My goal was quite simple: trying a couple of things out and plumbing together Jersey, Sitemesh, and Guice. Below are some notes on what I ended up with.
Sitemesh
Integrating Sitemesh was trivial. I only had to include the default Sitemesh configuration options and everything just worked. With the only caveat that the entity to be represented is not available to the Sitemesh decorators. Anyways I’ve decided to leave it as is, as not having access to the entity may actually be a good thing for making your decorators really generic. Just in case you do not agree and you’d like to get access to the entity into decorators leave a comment and I’ll look into it. Or if you already know how to do that, please share it.
Note: I assume this behavior is triggered by the entity being available in the JSP page context and not on the request.
Guice
Documentation about using Guice with Jersey is extremely rare (kindly said) and extremely old. What I’ve ended up with is more like using Guice as the factory pattern then DI: the resource object gets access to the Guice injector from where it canI fetch the needed dependencies. I’m not completely satisfied with this, but I didn’t have enough time to dig deeper.
Note: Ideally you’ll want the resource to be injected with dependencies automatically by Guice, but I’m not really sure if that is possible or not. I guess both Guice and Spring have to do the same thing, so maybe looking at the Spring integration will give me more ideas (hopefully I’ll be able to find more documentation about Spring integration). Paul Sandoz has written about some improvements for Guice integration in Jersey 1.3
Update: here is the follow up post on Guice integration in Jersey 1.3 and Jersey 1.2
Error codes and exception handling
While playing with my little project, I have noticed that there is no recipe for error handling with Jersey. When I say error handling, I’m actually referring to two scenarios:
- handling server side exceptions
- handling server side error codes
My goal was quite simple: have a way to customize the errors returned to the client for both exceptional cases and standard errors,
The only part related to this covered by the spec is defining exception mappers, but that is pretty far from being able to provide a complete solution.
I’ve also searched extensively the mailing list, but I haven’t been able to find a complete solution. What I did find where a couple of interesting ideas and some suggestions that set me on the right direction.
So I’ve ended up writing a couple of classes that would provide an easy way to deal with errors, allow me to customize the “output”, while also maintaining the complete media type support. Basically, my solution defines:
- 1 exception class
ServiceException,
- 1 data class
ErrorInfo which can carry details of different server side errors,
- 3
ExceptionMappers: `
-
WebApplicationExceptionHandler: deals with WebApplicationException creating an ErrorInfo
-
ServiceExceptionHandler: deals with ServiceException creating an ErrorInfo
-
ThrowableHandler: deals with all Throwable, creating an ErrorInfo
The last part of the solution is providing custom MessageBodyWriters for the ErrorInfo class supporting the formats you want to provide from your service. Right now, ErrorInfo can be serialized to XML, JSON and HTML using specific templates.
Dealing with forms and validation is a very common task when creating services/web apps, so I was a bit confused not to found a “standard” or at least some well established solutions. This made me write a couple of classes to make things simpler:
- populate a JavaBean from the form parameters (while this is not a complete solution it allows mapping form parameters to JavaBean properties, including and excluding some properties)
- validate forms parameters using either JSR-303 annotations or programmatically defined constraints according to JSR-303
A sample:
Form.FormBuilder fb = new Form.FormBuilder(ValidatedBean.class)
.include("creditCard")
.validate("creditCard", Validations.CreditCard)
.exclude("param1", "param2");
Form<ValidatedBean> vform = fb.build(validForm);
assertTrue(vform.valid());
ValidatedBean gBean= vform.getObject();
For now that’s all. If there is any interest in these custom pieces I’ve written, please drop me a note and I’ll do my best to share them on GitHub.