Implement CDI in JSP

In JSP, you can use managed CDI components using EL expressions such as $ {myBean.myAttribute}. There is no problem.

I would like to use a “regular injection” (i.e. without using EL expressions) with @Inject in JSP files, for example: <%! @Inject MyBean myBean; %> then later <% = myBean.getMyAttribute ()%>. Even though this example can be obtained using EL expressions, some other use cases cannot.

This seems to be not fully supported by application servers:
- JBoss 6.0.0, JBoss 6.1.0, Resin 4.0.22: OK, it works just fine.
- JBoss 7.0.1, GlassFish 3.x (several versions have been tested): FAILURE, myBean remains zero.

This should work well in JSP since:
(1) it works fine in servlets according to various specifications and
(2) The JSP is translated into the servlet at runtime.

Guys, do you know whether or not what I'm trying to do is supported? Maybe there is some information about the internal implementation?

+6
source share
3 answers

An interesting question, if you had not tested it, I would have put money on the fact that it does not work; -)

CDI runs on managed beans (JSR 316). The corresponding definition is rather relaxed (on purpose):

From the specification:

A managed Bean can be declared by annotating its class using the javax.annotation.ManagedBean annotation. A managed Bean does not have to be: a final class, abstract class, non-static inner class. A managed Bean cannot be serializable, unlike a regular JavaBean.

In the model of the base component of Managed Beans, a constructor must provide an argument without arguments, but a specification that builds on Managed Beans, such as CDI (JSR-299), can ease this requirement and allow Managed Beans to provide constructors with more complex signatures.

What is likely to happen is that the container scans the classpath and detects compiled JSP servlets. Some time ago I saw one, but I remember that the code is generated and everything (including scriptlets) gets into doGet() or doPost() ...!? Thus, even if they formally do not disqualify in terms of definition, I doubt that the JSP script is all that you want to consider a managed bean. Honestly, this is terribly wrong -)

I regularly read the CDI / Weld / Seam mailing lists, and I don’t remember that the JSP was ever mentioned. The same thing with googling is a mix.

As a result, you should not rely on CDI working with scriptlets. IMHO, this behavior has a side effect rather than something internal, and it can be discarded in future releases without notice (or without even noticing :-)

So +1 for JB Nizet's suggestion: use servlets with CDI but not JSP.

UPDATE : I tried to help, not to create confusion ;-) I want to say: IMHO it is really wrong to use CDI in JSP incorrectly, but I did not find anything in the corresponding specifications that proves this. All I can say is that the JSPs are never mentioned anywhere - which type supports my gut feeling (and corresponds to the observation that some implementations consider and others don't).

+2
source

I don’t think there is a portable @Inject available out of the box for JSP, but it can be implemented (at the container level) the same way it works with servlets.

And although I agree that this is not the best way to use CDI, technically I see no reason against it. For example, AFAIK @Inject in servlets transparently uses ThreadLocal proxies, why not use this function in JSP?

+1
source

Try this :-

 <%! @Inject private UserService userService; %> 

This works for me :)

Note. Use the bracket <%! %> <%! %> <%! %> <%! %> instead of <% %> .

0
source

Source: https://habr.com/ru/post/897130/


All Articles