[cdi-dev] Which version of HttpServletRequest is injected?

arjan tijms arjan.tijms at gmail.com
Tue Sep 13 03:46:12 EDT 2016


p.s.

On Thu, Sep 8, 2016 at 2:40 PM, Martin Kouba <mkouba at redhat.com> wrote:

> Stuart has a good point about backward compatibility. Servlet impl would
> have to detect CDI version and skip registration if not 2.0+. I think
> SERVLET_SPEC-116 should be reopened and the discussion restarted.
>

Would you like to re-open that discussion on the Servlet list? Would be
good to have someone from the CDI EG explaining the case I think.

Kind regards,
Arjan Tijms



>
>
>> Kind regards,
>> Arjan Tijms
>>
>>
>>
>>
>>
>>
>>     But it's more complicated then it sounds. For example,
>>     HttpServletRequest attibutes might be used as backing storage of the
>>     request context. So that it cannot simply change...
>>
>>     Anyway, I think this problem deserves some attention from both the
>>     CDI and the Servlet EG.
>>
>>     Martin
>>
>>     Dne 8.9.2016 v 13:31 arjan tijms napsal(a):
>>
>>         Hi,
>>
>>         On Thu, Sep 8, 2016 at 1:09 PM, Romain Manni-Bucau
>>         <rmannibucau at gmail.com <mailto:rmannibucau at gmail.com>
>>         <mailto:rmannibucau at gmail.com <mailto: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().getRequestDispatcher(...);
>>         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
>>         <https://twitter.com/rmannibucau>> |  Blog
>>             <https://blog-rmannibucau.rhcloud.com
>>         <https://blog-rmannibucau.rhcloud.com>> | Old Wordpress Blog
>>             <http://rmannibucau.wordpress.com
>>         <http://rmannibucau.wordpress.com>> | Github
>>             <https://github.com/rmannibucau
>>         <https://github.com/rmannibucau>> | LinkedIn
>>             <https://www.linkedin.com/in/rmannibucau
>>         <https://www.linkedin.com/in/rmannibucau>> | Tomitriber
>>             <http://www.tomitribe.com> | JavaEE Factory
>>             <https://javaeefactory-rmannibucau.rhcloud.com
>>         <https://javaeefactory-rmannibucau.rhcloud.com>>
>>
>>             2016-09-08 13:03 GMT+02:00 arjan tijms
>>         <arjan.tijms at gmail.com <mailto:arjan.tijms at gmail.com>
>>             <mailto:arjan.tijms at gmail.com <mailto:arjan.tijms at gmail.com>
>> >>:
>>
>>                 Hi,
>>
>>                 On Thu, Sep 8, 2016 at 12:40 PM, Martin Kouba
>>         <mkouba at redhat.com <mailto:mkouba at redhat.com>
>>                 <mailto:mkouba at redhat.com <mailto: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
>>         <mailto:cdi-dev at lists.jboss.org> <mailto:cdi-dev at lists.jboss.org
>>         <mailto:cdi-dev at lists.jboss.org>>
>>                         https://lists.jboss.org/mailman/listinfo/cdi-dev
>>         <https://lists.jboss.org/mailman/listinfo/cdi-dev>
>>
>>         <https://lists.jboss.org/mailman/listinfo/cdi-dev
>>         <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
>>         <http://www.apache.org/licenses/LICENSE-2.0.html>
>>                         <http://www.apache.org/licenses/LICENSE-2.0.html
>>         <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 <mailto:cdi-dev at lists.jboss.org>
>>         <mailto:cdi-dev at lists.jboss.org <mailto:cdi-dev at lists.jboss.org>>
>>                 https://lists.jboss.org/mailman/listinfo/cdi-dev
>>         <https://lists.jboss.org/mailman/listinfo/cdi-dev>
>>                 <https://lists.jboss.org/mailman/listinfo/cdi-dev
>>         <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
>>         <http://www.apache.org/licenses/LICENSE-2.0.html>
>>                 <http://www.apache.org/licenses/LICENSE-2.0.html
>>         <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
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.jboss.org/pipermail/cdi-dev/attachments/20160913/0569e725/attachment-0001.html 


More information about the cdi-dev mailing list