[cdi-dev] Which version of HttpServletRequest is injected?
arjan tijms
arjan.tijms at gmail.com
Thu Sep 8 10:17:56 EDT 2016
Hi,
On Thu, Sep 8, 2016 at 2:40 PM, Martin Kouba <mkouba at redhat.com> wrote:
> 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.
>
Indeed, that is a good point, but that's basically part of the challenge of
moving those build-in beans. If I'm not mistaken Antoine once mentioned in
one of the other related issues something along the line that CDI 2.0 could
provide something for that. So the "is 2.0+" check could be made easier or
more straightforward.
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/20160908/ac4caff4/attachment-0001.html
More information about the cdi-dev
mailing list