Following my first experiments with Jersey I’ve continue my investigation of Jersey and Guice integration. As mentioned in the previous post my research was mainly centered around Paul Sandoz’s post, the Jersey mailing list (nb. unfortunately I could find much), and as the last resort the source code.
For Jersey 1.3 and Guice integration the news are quite good. There is a jersey-guice module that provides pretty much everything that is needed. And there is also a sample project providing the necessary details for setting this integration up, so I’ll not detail it here. Basically all you have to do is:
But you will also want to be aware of the following three things:
@Inject if you also need to pass in any of the JAX-RS @*ParamViewable JSPsWhile point 1 above may be a non-issue to most/some, the other two deserve a bit of explanation/details.
When using the Guice integration provided in Jersey 1.3, Guice is responsible to both create and inject components, resources, and providers. Unfortunately due to they way bindings are defined in Guice, there was no easy way to make it aware of all @*Param values and so even if it is recommended to use constructor based injection, you’ll not be able to to both use @Inject and @*Param in a constructor. Most probably the scenarios where you’ll see is issue are those elements that have a per-request lifecycle. The good news is that there are simple workarounds for it:
@*Param as fields and the constructor as @Inject@Inject dependencies as either fields or methods, and use the constructor parameters to make Jersey pass in *@ParamsThe last point is covered in more detail and this email thread. According to the conclusions in there, you’ll probably need a Guice trunk build to get around this issue.
In case you are stuck with Java 5 for the time being, you’ll have to go back and use Jesey 1.2. Unfortunately this comes with a couple of other bad news:
Unfortunately I’m in this second situation. My machines are still running Java 5 and an upgrade is not foreseeable. There might be a good part in this though: if I’ll find the time I’ll probably try to backport Jersey 1.3 Guice support to 1.2. But there are still some problems with this (license, distribution, etc.) and I’ll need to consult myself with Jersey people.
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.
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.
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
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:
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:
ServiceException, ErrorInfo which can carry details of different server side errors,ExceptionMappers: `WebApplicationExceptionHandler: deals with WebApplicationException creating an ErrorInfoServiceExceptionHandler: deals with ServiceException creating an ErrorInfoThrowableHandler: deals with all Throwable, creating an ErrorInfoThe 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:
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.