Cross-cutting concerns in JAX-RS
I'm looking for a mechanism within JAX-RS (JSR-311) to allow me to distill out some of my cross-cutting concerns specific to my app. For example, my app has certain context which is looked up or built for each request. I'd like to be able to have this type of logic be performed in a centralized location and then somehow be attached to the context to be utilized by various resources for the remainder of the request. It would be even better if I could perform these types of actions for only some subsets of URLs.
The default injection that JAX-RS provides for path segments, cookie, header, etc. is great but what about custom interpretation of those parts? I really don't want to have to build that each time I need it. I'd rather have a way to specify how it is built and then just have the context component injected as part of my resource method.
开发者_JAVA技巧Do any such hooks exist? Can I manipulate the providers model to do this? BTW, I want to stay implementation independent (Jersey, RESTEasy, etc.) as long as possible.
Thanks in advance for any insight.
You can use ContextResolver
provider to provide any context to the resource or to another provider. Basically you need to implement javax.ws.rs.ext.ContextResolver<T>
for any context you want to get injected. Don't forget to annotate it with @Provider
and register.
In some sort of bizaro twist, standards are working together (JAX-RS & CDI) in a wonderfully composable manner, and IBM wrote a tutorial which which may cover my specific question. Part of a larger tutorial on combining CDI and JAX-RS, this article specifically addresses using CDI (Java Contexts and Dependency Injection) decorators and method interceptors to implement cross-cutting concerns in JAX-RS resources:
- Implement a JAX-RS resource with decorators and method interceptors
- General CDI example and then later applied to JAX-RS
Update: I was just able to get this to work in GlassFish 3.1. The key (which none of the examples I've found showed) is that you have to make sure CDI manages the lifespan of your resource instances (so it can wrap with the interceptors). Instantiating yourself and then returning in the Application.getSingletons() method does not work.
I'm going to go back and see if I can get it to go in Jetty too.
Update 2: Jetty (and by extension probably any other non-J2EE servlet containers like Tomcat) are kind of a pain to get set up with CDI. I think GlassFish is a much easier integration. Here is one blog that outlines some of the steps needed for Jetty:
- Hello World Tutorial using Maven 2, JSF 2, Facelets 2, and Weld
精彩评论