[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