CDI инжекция в JSP

В рамките на JSP е възможно да се използват CDI управлявани beans чрез EL изрази като ${myBean.myAttribute}. Тук няма проблем.

Бих искал да използвам „обикновено инжектиране“ (т.е. без използване на EL изрази) с @Inject в JSP файлове, например: ‹%! @Inject MyBean myBean; %> след това по-късно ‹%= myBean.getMyAttribute() %>. Дори ако този пример може да бъде постигнат с помощта на EL изрази, някои други случаи на употреба не могат.

Изглежда, че това не се поддържа напълно от сървърите на приложения:
- JBoss 6.0.0, JBoss 6.1.0, Resin 4.0.22: Добре, работи добре.
- JBoss 7.0.1, GlassFish 3. x (бяха тествани няколко версии): НЕ УДАВА, myBean остава нула.

Трябва да работи добре в JSP, тъй като:
(1) работи добре в сървлети според различните засегнати спецификации и
(2) JSP се превежда в сървлет по време на изпълнение.

Знаете ли момчета дали това, което се опитвам да направя, се поддържа или не? Може би някаква вътрешна информация/информация за внедряване?


person Florian Beaufumé    schedule 12.09.2011    source източник
comment
Не знам дали се поддържа (или трябва да се поддържа), но знам, че правенето на това в JSP е просто лоша идея. JSP са предназначени да генерират маркиране. Те не трябва да съдържат Java скриптлети от години. Направете каквото искате в обикновен сървлет и изпратете към JSP. Използвайте само етикетите EL и JSP в JSP.   -  person JB Nizet    schedule 12.09.2011
comment
Използването на сървлети и/или MVC рамки може да помогне в някои ситуации в зависимост от изискванията на приложението. Но понякога добавянето на сървлет само за предаване на референция на сервизен компонент към JSP е излишно и може да се счита за анти-шаблон. Това, от което наистина се интересувам тук, е разбирането на поведението на CDI за JSP, дори ако има алтернативни решения. :)   -  person Florian Beaufumé    schedule 13.09.2011


Отговори (3)


Интересен въпрос, ако не го бяхте тествали, щях да заложа малко пари на факта, че не работи ;-)

CDI се основава на управлявани компоненти (JSR 316). Съответното определение е доста облекчено (нарочно):

От спецификацията:

Управляван Bean може да бъде деклариран чрез анотиране на неговия клас с анотацията javax.annotation.ManagedBean. Управляваният Bean не трябва да бъде: финален клас, абстрактен клас, нестатичен вътрешен клас. Управляваният Bean може да не може да бъде сериализиран, за разлика от обикновен JavaBean компонент.

В основния компонентен модел, Managed Beans трябва да предостави конструктор без аргументи, но спецификация, която се основава на Managed Beans, като CDI (JSR-299), може да облекчи това изискване и да позволи на Managed Beans да предостави на конструкторите по-сложни сигнатури,

Това, което вероятно се случва, е, че контейнерът сканира класовата пътека и се случва да намери компилираните JSP сървлети. Мина известно време, откакто видях такъв за последен път, но си спомням, че кодът се генерира и всичко (включително скриптлетите) попада в doGet() или doPost()...!? Така че, въпреки че те формално не дисквалифицират по отношение на определението, аз се съмнявам, че JSP скриптът е нещо, което искате да считате за управляван bean. Чувствам се ужасно грешно, честно ;-)

Следя пощенските списъци на CDI / Weld / Seam от доста време и не си спомням JSP да е споменаван някога. Същото е и с търсенето в Google на тази връзка.

Като следствие не трябва да разчитате на CDI, работещ със скриптове. IMHO това поведение има повече страничен ефект, отколкото нещо умишлено и може да бъде премахнато в бъдещи издания без предупреждение (или дори без да бъде забелязано :-)

И така, +1 за предложението на JB Nizet: Използвайте сервлети с CDI, но не и JSP.

АКТУАЛИЗАЦИЯ: Опитах се да помогна, а не да създавам объркване ;-) Мисълта ми е: IMHO ми се струва наистина грешно да се използва CDI в JSP, но не намерих нищо в съответните спецификации, което да доказва това . Всичко, което мога да кажа е, че JSP никога не се споменават никъде - което донякъде подкрепя интуицията ми (и отговаря на наблюдението, че някои реализации го вземат предвид, други не).

person jan groth    schedule 12.09.2011
comment
Не разбрах вашето твърдение, че CDI се основава на управлявани бобове. Всъщност CDI прави JSF управляваните beans не необходими и не изисква анотацията @ManagedBean в своите управлявани beans - един клас просто се нуждаете от конструктор по подразбиране, за да бъде bean. Също така препратката на Weld гласи, че сървлетите са компоненти така че бих се обзаложил, че генерираните от JSP сървлети ще поддържат инжектиране (без да се взема предвид дали е добро или лошо). - person brandizzi; 13.09.2011
comment
Не, не, вие смесвате JSF javax.faces.bean.ManagedBean с CDI javax.annotation.ManagedBean - неприятна неяснота. Тази глава от документацията на Weld е добро начало за (пре)оценка на CDI, моля, проверете и цитирания JSR 316... Да, сървлетите са зърна, това е без съмнение. Но честно казано не знам дали генерираните сървлети се вписват в тази схема - както писах преди. - person jan groth; 13.09.2011
comment
Не всички елементи на JSP скриптове завършват в doGet/doPost, JSP декларации (т.е. ‹%! ... %› неща) дефинират атрибути или методи на класа. Това е правилният вариант за @Inject атрибути. Освен това уточнение, Ян, не разбирам логическия ти извод и защо казваш, че те формално не отговарят на изискванията. - person Florian Beaufumé; 13.09.2011

Не мисля, че има преносим @Inject, наличен извън кутията за JSP, но би трябвало да е възможно да се приложи (на ниво контейнер) по същия начин, по който работи със сървлети.

И въпреки че съм съгласен, че това не е най-добрият начин за използване на CDI, технически не виждам причина против него. Например, AFAIK @Inject в сървлети прозрачно използва ThreadLocal проксита, защо не използвате тази функция в JSP?

person Tair    schedule 16.09.2011

Опитайте тази :-

<%!
    @Inject
    private UserService userService;
%>

При мен работи :)

Забележка: Използвайте скоба <%! %> вместо <% %>.

person Victory    schedule 20.12.2018