[cdi-dev] Which version of HttpServletRequest is injected?
Romain Manni-Bucau
rmannibucau at gmail.com
Thu Sep 8 08:14:00 EDT 2016
Well supposes @Current means something for the component getting the
injection, I can see where you go starting from AuthModule but more your
browse the chain less it makes sense IMO -> maybe something to work on auth
side more than CDI?
That said CDI has a notion for conversions which is to define a provided
filter. Maybe that's the easiest here: a user could define one or multiple
filters ("CDI Filter" or whatever name) which would set CDI position in the
filter chain, defining it N times would update "current" request and the
produces one so we keep current default and enable the user to control it
himself finely when needed.
Romain Manni-Bucau
@rmannibucau <https://twitter.com/rmannibucau> | Blog
<https://blog-rmannibucau.rhcloud.com> | Old Wordpress Blog
<http://rmannibucau.wordpress.com> | Github <https://github.com/rmannibucau> |
LinkedIn <https://www.linkedin.com/in/rmannibucau> | Tomitriber
<http://www.tomitribe.com> | JavaEE Factory
<https://javaeefactory-rmannibucau.rhcloud.com>
2016-09-08 14:10 GMT+02:00 arjan tijms <arjan.tijms at gmail.com>:
> Hi,
>
> I see what you mean.
>
> There's perhaps 2 solutions.
>
> 1. Specify @Inject HttpServletRequest to inject the current one (the top
> one from the stack)
> 2. Let @Inject HttpServletRequest as it's now (you get an arbitrary one,
> which is hopefully at least always the same for a given server), and
> introduce a qualifier @Current orso.
>
> I don't think you'd ever need @Inject @Web(FilterX.class) Request, which
> would mean searching back through the stack. If users would want that, they
> have to make their own producer.
>
> What we could do now is:
>
> AuthModule
> |
> |
> Filter1 (calls) ---> BeanX.foo() #1
> |
> |
> Filter2
> |
> |
> Servlet1 (calls) ---> BeanX.foo() #2
> |
> |
> (forward) ---> Servlet2 (calls) ---> BeanX.foo() #3
>
>
>
> If BeanX is injected with @Inject HttpServletRequest or @Inject @Current HttpServletRequest,
> then:
>
>
> In #1, BeanX.foo() sees the HttpServletRequest as it was passed in to
> Filter1
>
> In #2, BeanX.foo() sees the HttpServletRequest as it was passed in to
> Servlet1
>
> In #3, BeanX.foo() sees the HttpServletRequest as it was passed in to
> Servlet2
>
>
>
> Since the request processing is strictly sequential here, a given thread
> always has the concept of the request that was passed it to the
> module/filter/servlet that's highest up the call stack. That one would IMHO
> be the most logical one that you want to work with.
>
> Kind regards,
> Arjan Tijms
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
> On Thu, Sep 8, 2016 at 1:53 PM, Romain Manni-Bucau <rmannibucau at gmail.com>
> wrote:
>
>> AFAIK the server propagates by designt he request/response pair so even
>> if there is a way to know which one it is at each moment you still have the
>> issue you don't know what @Inject Request; means. @Inject
>> @Web(FilterX.class) Request; is possible but not sure the real meaning and
>> IMO it breaks the loose coupling of CDI so not sure it does worth to
>> spec-ed it.
>>
>>
>> Romain Manni-Bucau
>> @rmannibucau <https://twitter.com/rmannibucau> | Blog
>> <https://blog-rmannibucau.rhcloud.com> | Old Wordpress Blog
>> <http://rmannibucau.wordpress.com> | Github
>> <https://github.com/rmannibucau> | LinkedIn
>> <https://www.linkedin.com/in/rmannibucau> | Tomitriber
>> <http://www.tomitribe.com> | JavaEE Factory
>> <https://javaeefactory-rmannibucau.rhcloud.com>
>>
>> 2016-09-08 13:31 GMT+02:00 arjan tijms <arjan.tijms at gmail.com>:
>>
>>> Hi,
>>>
>>> On Thu, Sep 8, 2016 at 1:09 PM, Romain Manni-Bucau <
>>> rmannibucau at gmail.com> wrote:
>>>
>>>> Hit that issue as well several times.
>>>>
>>>> It is more vicious than it looks like IMO cause CDI will *never* get
>>>> *the* right request for everybody, it is as simple as that. Any part of the
>>>> app can rely on the wrapper level N (of course N being different for each
>>>> mentionned parts of the app).
>>>>
>>>
>>> What I was thinking, but maybe I'm wrong, is that the application never
>>> "just" wraps the request and uses it for itself. It always passes it to the
>>> container, which then passes it on to the next Filter, Servlet, or
>>> whatever. So at that point the container code has the opportunity to store
>>> the request as being the "current" one.
>>>
>>> E.g. if you do:
>>>
>>> RequestDispatcher dispatcher = servletContext().getRequestDis
>>> patcher(...);
>>> dispatcher.forward(wrap(request), response);
>>>
>>> Then the RequestDispatcher, which is a container class, receives the
>>> wrapped request and can make it available.
>>>
>>> The other way around, eventually every AuthModule, Filter or Servlet has
>>> to be called by the container at some point. E.g. the "protected void
>>> service(HttpServletRequest req, HttpServletResponse resp)" is called by the
>>> container.
>>>
>>> So just before the container invokes the HttpServlet#service method, the
>>> container can store the request, and CDI (via an SPI) can pick it up from
>>> there.
>>>
>>> That way in every context you can always have the *current* request (the
>>> request that's passed in to the last Servlet or Filter call on the stack).
>>>
>>> Kind regards,
>>> Arjan Tijms
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>> Best CDI can do is to provide the request it has (already the case and
>>>> cost pretty much nothing) and enable the user to produces very easily its
>>>> own request from its filter (or equivalent) for its usage IMO - which is
>>>> IMO already doable but maybe there is another shortcut we can introduce I
>>>> didnt think about. If you look one step further any web framework built on
>>>> top of CDI does it and therefore runs in a well known context.
>>>>
>>>>
>>>> Romain Manni-Bucau
>>>> @rmannibucau <https://twitter.com/rmannibucau> | Blog
>>>> <https://blog-rmannibucau.rhcloud.com> | Old Wordpress Blog
>>>> <http://rmannibucau.wordpress.com> | Github
>>>> <https://github.com/rmannibucau> | LinkedIn
>>>> <https://www.linkedin.com/in/rmannibucau> | Tomitriber
>>>> <http://www.tomitribe.com> | JavaEE Factory
>>>> <https://javaeefactory-rmannibucau.rhcloud.com>
>>>>
>>>> 2016-09-08 13:03 GMT+02:00 arjan tijms <arjan.tijms at gmail.com>:
>>>>
>>>>> Hi,
>>>>>
>>>>> On Thu, Sep 8, 2016 at 12:40 PM, Martin Kouba <mkouba at redhat.com>
>>>>> wrote:
>>>>>
>>>>>> that's a good question. In Weld, the request object is captured
>>>>>> during request context activation, i.e. during
>>>>>> ServletRequestListener.requestInitialized() notification and before
>>>>>> any filter or servlet is invoked. So wrappers are ignored and the
>>>>>> original/first request is used.
>>>>>>
>>>>>
>>>>> Indeed, although do note that some servers (Liberty and WebLogic I
>>>>> think) send the ServletRequestListener.requestInitialized()
>>>>> notification rather late, and do that after the application already has
>>>>> seen the request and has had a chance to wrap it. This by itself is a
>>>>> separate problem. So on these servers, Weld would receive an early request
>>>>> but not necessarily the earliest.
>>>>>
>>>>>
>>>>>> But TBH I don't think we can fix this easily as I'm not aware of any
>>>>>> portable way to listen for "wrapping actions".
>>>>>>
>>>>>
>>>>> This would have to happen with Server specific code I guess, just as
>>>>> Weld now requires an SPI to obtain the current principal for injection.
>>>>>
>>>>> You could say that the Servlet container could store the request
>>>>> "somewhere" on a stack structure, just before it invokes the
>>>>> ServerAuthModule, Filter, Servlet and anything else I may have forgotten,
>>>>> and then when control flows back to each Servlet, Filter, etc unwind that
>>>>> stack.
>>>>>
>>>>> At the very least the spec for now should perhaps clarify this?
>>>>>
>>>>> Kind regards,
>>>>> Arjan Tijms
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>>
>>>>>> Martin
>>>>>>
>>>>>> Dne 8.9.2016 v 11:02 arjan tijms napsal(a):
>>>>>>
>>>>>>> Hi,
>>>>>>>
>>>>>>> The CDI spec defines a built-in bean for the type
>>>>>>> HttpServletRequest. In
>>>>>>> 3.8 it says:
>>>>>>>
>>>>>>> "A servlet container must provide the following built-in beans, all
>>>>>>> of
>>>>>>> which have qualifier @Default:
>>>>>>>
>>>>>>> a bean with bean type javax.servlet.http.HttpServletRequest,
>>>>>>> allowing
>>>>>>> injection of a reference to the HttpServletRequest"
>>>>>>>
>>>>>>> An HttpServletRequest however can be wrapped multiple times and by
>>>>>>> multiple artefacts. I.e. by a ServerAuthModule, Filter and a
>>>>>>> RequestDispatcher.
>>>>>>>
>>>>>>> The question now is; which version of the HttpServletRequest is
>>>>>>> supposed
>>>>>>> to be injected?
>>>>>>>
>>>>>>> * The first one in the chain?
>>>>>>> * The last one in the chain?
>>>>>>> * The current one at a given point in the chain?
>>>>>>>
>>>>>>> A little bit of experimenting seems to indicate it's now often "one
>>>>>>> of
>>>>>>> the first ones", e.g. the one that happened to be current when e.g. a
>>>>>>> ServletRequestListener that initialises a specific CDI
>>>>>>> implementation is
>>>>>>> called.
>>>>>>>
>>>>>>> I think this is a little confusing, as working with an injected
>>>>>>> request
>>>>>>> can now totally ignore the request wrapping that has been done and
>>>>>>> break
>>>>>>> an application badly.
>>>>>>>
>>>>>>> Thoughts?
>>>>>>>
>>>>>>> Kind regards,
>>>>>>> Arjan Tijms
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> _______________________________________________
>>>>>>> cdi-dev mailing list
>>>>>>> cdi-dev at lists.jboss.org
>>>>>>> https://lists.jboss.org/mailman/listinfo/cdi-dev
>>>>>>>
>>>>>>> Note that for all code provided on this list, the provider licenses
>>>>>>> the code under the Apache License, Version 2 (
>>>>>>> http://www.apache.org/licenses/LICENSE-2.0.html). For all other
>>>>>>> ideas provided on this list, the provider waives all patent and other
>>>>>>> intellectual property rights inherent in such information.
>>>>>>>
>>>>>>>
>>>>>> --
>>>>>> Martin Kouba
>>>>>> Software Engineer
>>>>>> Red Hat, Czech Republic
>>>>>>
>>>>>
>>>>>
>>>>> _______________________________________________
>>>>> cdi-dev mailing list
>>>>> cdi-dev at lists.jboss.org
>>>>> https://lists.jboss.org/mailman/listinfo/cdi-dev
>>>>>
>>>>> Note that for all code provided on this list, the provider licenses
>>>>> the code under the Apache License, Version 2 (
>>>>> http://www.apache.org/licenses/LICENSE-2.0.html). For all other ideas
>>>>> provided on this list, the provider waives all patent and other
>>>>> intellectual property rights inherent in such information.
>>>>>
>>>>
>>>>
>>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.jboss.org/pipermail/cdi-dev/attachments/20160908/9bd09288/attachment-0001.html
More information about the cdi-dev
mailing list