As I've read here and tried myself, it is not possible to inject the HttpServletResponse of the current #RequestScoped.
So it seems that you have to implement a custom CDI Procuder or #Produces method to be able to inject the HttpserlvetResponse. I have two questions:
Where would one implement this producer? Maybe with a web filter that sets the response in a #RequestScoped bean?
Is injecting the response even a good idea in the first place since there is no way to inject the response by default?
Never mind. I just found the Servlet module from Apache DeltaSpike which allows for injectable servlet objects such as the HttpServletResponse. So there is no need for a custom CDI Producer or #Produces method.
Related
I'm building a rest API in Spring. Is there a way to tap into the routing to do a lookup?
Is there a table somewhere?
Given a full route /someobject/a with an ACCEPT header of "whatever", is there a way I can tell what controller and method it will get routed to, Or do I need to build that map myself?
I asked a similar question in a different way and was suggested to use Spring AOP which I tried with #Before, but it doesn't work in some of the cases I need. Specifically, if there are validation annotations on the method parameters and the validation fails, it doesn't make it to the join point. Doesn't make it to the #AfterThrowing either.
For those trying to figure this out in the future, yes it is indeed possible. The routing is exposed as a bean:
#Autowired
private RequestMappingHandlerMapping requestMappingHandlerMapping;
You need the HttpServletRequest object which you can get from here if you don't have it already:
HttpServletRequest request = ((ServletRequestAttributes)RequestContextHolder.currentRequestAttributes()).getRequest();
Then you just call:
HandlerMethod handlerMethod = (HandlerMethod)requestMappingHandlerMapping.getHandler(request).getHandler();
My specific need was to get the PreAuthorize attribute, but you can do anything with the HandlerMethod object:
PreAuthorize preauthorize = handlerMethod.getMethodAnnotation(PreAuthorize.class);
I'm learning Jersey and trying to build a rest api. But I'm having a hard time understanding the difference between various bindings - bind() , AbstractBinder(), bindFactory() and also the scopes - RequestScoped , Singleton and PerLookup. What are the differences between them and when to use which one?
e.g. Say I have some request specific data passed into the request header. I want to use this data multiple times (say in resource classes, DAOs etc) during the request processing. What I figured is that I'll use a request filter and extract the data using the ContainerRequestContext and store it to some class. But i'm not able to figure out how to bind this class so that I can access it later. Which binding to use in this case?
bind() and bindFactory() are methods in the AbstractBinder class that you use to bind your services in the registry. The AbstractBinder is what you register with Jersey so that it knows to configure all your bindings. You use bind() to bind the service itself. You use bindFactory() to bind the service using a Factory (or Supplier in 2.26+) to create the service.
RequestScoped means that the service is scoped to the request, meaning that it will be the same instance for the lifetime of the request. You would use this scope when the service is dependent on information tied to a request, like request headers.
Singleton scope means that there will only be one instance of the service for the lifetime of the application. You would use this scope when the service can safely be used at anytime without being tied to any request.
PerLookup means that a new instance of the service will be created every time it is looked up, either directly through the ServiceLocator (or InjectionManager in 2.26+) or via an #Inject (or other injection) annotation. Even though this is the default scope, the RequestScope and Singleton scope would be more appropriate for most of the use cases in the context of a Jersey application.
For your use case where you want to get information from the request context and use it in the service, you would use a RequestScoped service and use a bindFactory() with a Factory (or Supplier in 2.26+) and inject the request context into the Factory and use the context to create your service. You can see more explanation in How to inject an object into jersey request context?. If you are using Jersey 2.26+, you'll also want to read Jersey 2.26: register #Inject in ResourceConfig bindFactory cannot convert Factory to Supplier
I'm trying to clear my concept about Interceptors in Java EE. I have read Java EE specification but I'm little confused about it. Please provide me some useful link or tutorial which could clear my concept. How, When, Why do we use interceptors?
Interceptors are used to implement cross-cutting concerns, such as logging, auditing, and security, from the business logic.
In Java EE 5, Interceptors were allowed only on EJBs. In Java EE 6, Interceptors became a new specification of its own, abstracted at a higher level so that it can be more generically applied to a broader set of specifications in the platform.
They intercept invocations and life-cycle events on an associated target class. Basically, an interceptor is a class whose methods are invoked when business methods on a target class are invoked, life-cycle events such as methods that create/destroy the bean occur, or an EJB timeout method occurs. The CDI specification defines a type-safe mechanism for associating interceptors to beans using interceptor bindings.
Look for a working code sample at:
https://github.com/arun-gupta/javaee7-samples/tree/master/cdi/interceptors
Java EE 7 also introduced a new #Transactional annotation in Java Transaction API. This allows you to have container-managed transactions outside an EJB. This annotation is defined as an interceptor binding and implemented by the Java EE runtime. A working sample of #Transactional is at:
https://github.com/arun-gupta/javaee7-samples/tree/master/jta/transaction-scope
Interceptors are used to add AOP capability to managed beans.
We can attach Interceptor to our class using #Interceptor annotation.
Whenever a method in our class is called, the attached Interceptor will intercept that method invocation and execute its interceptor method.
This can be achieved using #AroundInvoke annotation ( see example below ).
We can intercept life cycle events of a class ( object creation,destroy etc) using #AroundConstruct annotation.
Main difference between Interceptor and Servlet Filters is We can use Interceptor outside WebContext, but Filters are specific to Web applications.
Common uses of interceptors are logging, auditing, and profiling.
For more detailed introduction, you can read this article.
https://abhirockzz.wordpress.com/2015/01/03/java-ee-interceptors/
I like this definition: Interceptors are components that intercept calls to EJB methods. They can be used for auditing and logging as and when EJBs are accessed.
In another situation, they can be used in a situation where we need to check whether a client has the authority or clearance to execute a transaction on a particular object in the database. Well, this is where Interceptors come in handy; they can check whether the client/user has that authority by checking whether he/she can invoke that method on that database object or EJB.
However, I would still have a look at the following article and the following tutorial to get an idea of how they are used in a Java EE setting/environment.
You can use Interceptor for the places where you want to perform some tasks before sending a request to the Controller class and before sending a request to a responce.
Ex:- Think you want to validate the auth token before sending a request to the Controller class in this case, you can use Intercepters.
Sample code:
#Component
public class AuthInterceptor implements HandlerInterceptor {
public boolean preHandle(HttpServletRequest request, HttpServletResponse
response, Object handler) throws Exception {
//Here you can write code to validate the auth token.
}
}
I am currently developing a REST webservice using Jersey and Guice as a DI-container.
For handling the requests I am relying on a GuiceServletContextListener which is configured similar to the following:
bind(UserResource.class);
//Some other root-level resources for REST
serve("/rest/*").with(GuiceContainer.class);
As I have to deal with hierarchical data (One user should have their own items and it should be possible to access items of other users in the form of /rest/user/[Username]/item). For this, I am using Jersey's support for subresources.
For example, my UserResource contains the following method (ItemResource.Factory is a factory interface whose implementation is automatically provided by Guice's FactoryModuleBuilder):
#Inject
private ItemResource.Factory _itemResourceFactory;
#Path("/{username}/item")
public ItemResource getItems(#PathParam("username") String username) {
User user = //...
return this._itemResourceFactory.create(user);
}
ItemResource (the subresource) then again is implemented as a normal Jersey class based on the User passed in in the constructor.
However, my subresources need access to #Context fields (like UriInfo or HttpServletRequest), too. According to the Jersey documentation, #Context fields are not injected for subresources as their lifecycle is unknown (and the documentation seems to be true).
This is very unfortuante for me: I really need access to those values.
As a workaround, I am currently passing those values as additional constructor parameters to my subresources which I perceive as everything but comfortable.
Is there any possibility to tell Jersey to inject them anyway?
Nevertheless, even better would be if Guice itself was able to inject the #Context fields.
Simply swapping the #Context for #Inject, however, doesn't work as Guice has no registrations for types like UriInfo or HttpServletRequest.
Can I somehow create those mappings?
The problem is, that I don't know how to access the request specific values inside a Guice Provider implementation.
Are there maybe any helper methods to get access to the current instances of those Jersey objects so I can write the necessary providers?
Or are those implementations maybe already available somewhere out there?
I am not sure I understood your problem. Can you post the code related to "passing those values as additional constructor parameters"?
You can inject the Context like this:
#Path("/{username}/item")
public ItemResource getItems(#Context HttpServletRequest request, #PathParam("username") String username) {
Maybe you could inject fields programmatically? Guice provides this through the Injector class:
Injector injector = Guice.createInjector(...);
injector.injectMembers(someObjectToInject);
See http://code.google.com/p/google-guice/wiki/Injections for more information on this topic.
I'm looking for a way to autowire HttpServletResponse. It doesn't work with spring out of the box, but I've found this description. This works but is sort of annoying, in that spring obviously has a mechanism to make objects request scoped (i.e. HttpServletRequest) and this seems to be a hack bolted on top.
Is there a way to hook into the same mechanism that spring uses for HttpServletRequest? And, any idea why spring team decided to only make HttpServletRequest autowire capable (and excluded HttpServletResponse)?
Perhaps there is some workaround, but it's not that obvious, because it's not the way it's meant to be. Spring MVC is meant to have singleton #Controller beans that provide #RequestMapping methods which take the request and response as arguments.
If you need the response in another place (the service layer) - don't do it. The response should not go beyond the web (controller) layer.
To inject the response, you need:
- to store the response in a ThreadLocal
- to make a factory bean that returns the current response
About the example code you showed - I'm not sure if you are not going to need the factory bean to return a proxy (implementing HttpServletResponse), which in turn to return the current response. And it gets rather complicated.
But ultimately - you should not do that. If you need to intercept multiple controller invocations, use an mvc-interceptor. If you really need to use an aspect, you can get the response if it is passed as argument to the intercepted method.
Can you simply include the request in the method handle?
#RequestMapping(method=Method.GET, value="myUrl")
public String doGet(HttpServletResponse response){//spring will put the response in for you
...
}