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

Martin Kouba mkouba at redhat.com
Thu Sep 8 08:40:06 EDT 2016


Dne 8.9.2016 v 14:28 arjan tijms napsal(a):
> Hi,
>
> On Thu, Sep 8, 2016 at 2:14 PM, Martin Kouba <mkouba at redhat.com
> <mailto:mkouba at redhat.com>> wrote:
>
>     The best solution might be to let the servlet container provide the
>     beans for all the servlet artifacts (HttpServletRequest, HttpSession
>     and ServletContext).
>
>
> +100 for that.
>
> Several issues were already created for that in the past, but to my
> understanding it was misunderstood by some in the Servlet EG and
> subsequently closed. See https://java.net/jira/browse/SERVLET_SPEC-116
>
> Specifically this comment was a little problematic:
>
> GW> More over,
> GW> I'm concerned that by making CDI to servlet mapping a responsibility
> GW> of the servlet container, then we are going to have to do a
> GW> container to CDI adaptation for every CDI implementation out there.
>
> I think this is missing the key insight that CDI extensions are portable
> and that it's "just" providing a 1 class extension that adds 3 orso
> build-in beans.

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.

>
> 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


More information about the cdi-dev mailing list