Внедрение CDI в JSP

В JSP можно использовать управляемые компоненты CDI, используя выражения 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 (было протестировано несколько версий): FAILS, 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 основан на управляемых bean-компонентах (JSR 316). Соответствующее определение довольно расслаблено (намеренно):

Из спецификации:

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

В базовой модели компонентов управляемые компоненты должны предоставлять конструктор без аргументов, но спецификация, основанная на управляемых компонентах, например CDI (JSR-299), может ослабить это требование и позволить управляемым компонентам предоставлять конструкторам более сложные сигнатуры.

Вероятно, происходит то, что контейнер просматривает путь к классам и находит скомпилированные сервлеты JSP. Прошло некоторое время с тех пор, как я последний раз видел один, но я помню, что код сгенерирован и все (включая скриптлеты) попадают в doGet() или _2 _...!? Итак, даже несмотря на то, что они формально не дисквалифицируют с точки зрения определения, я сомневаюсь, что скрипт JSP - это что-то, что вы хотите рассматривать как управляемый компонент. Честно говоря, это ужасно неправильно ;-)

Я слежу за списками рассылки CDI / Weld / Seam уже довольно давно и не припомню, чтобы когда-либо упоминался JSP. То же самое и с поиском в Google этой связи.

Как следствие, вам не следует полагаться на CDI при работе со скриплетами. ИМХО, это поведение имеет больше побочных эффектов, чем что-то внутреннее, и может быть исключено в будущих выпусках без уведомления (или даже без заметного :-)

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

ОБНОВЛЕНИЕ: я пытался помочь, а не создавать путаницу ;-) Моя точка зрения: ИМХО, мне кажется, действительно неправильно использовать CDI в JSP, но я не нашел ничего в соответствующих спецификациях, подтверждающих это. . Все, что я могу сказать, это то, что JSP нигде никогда не упоминаются - это поддерживает мое чутье (и соответствует наблюдению, что некоторые реализации учитывают это, а другие нет).

person jan groth    schedule 12.09.2011
comment
Я не понял вашего утверждения, что CDI строится на управляемых bean-компонентах. Фактически, CDI делает ненужными управляемые компоненты JSF и не требует аннотации @ManagedBean в своих управляемых компонентах - один класс просто нужен конструктор по умолчанию, который будет bean-компонентом. Кроме того, в справочнике Weld говорится, что сервлеты являются bean-компонентами, поэтому я готов поспорить, что сервлеты, сгенерированные JSP, будут поддерживать инъекцию (не принимая во внимание, хорошо это или плохо). - person brandizzi; 13.09.2011
comment
Нет-нет, вы смешиваете JSF javax.faces.bean.ManagedBean с CDI javax.annotation.ManagedBean - досадная двусмысленность. Эта глава документации по сварке является хорошее начало для (пере) оценки CDI, пожалуйста, также проверьте процитированный JSR 316 ... Да, сервлет - это bean-компоненты, это вне всяких сомнений. Но я, честно говоря, не знаю, вписываются ли сгенерированные сервлеты в эту схему - как я писал ранее. - 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