Проблемы с использованием аннотаций CDI v / s JSF - PullRequest
0 голосов
/ 21 мая 2018

Я совершенно новичок в JSF и в процессе обучения, и у меня возникают проблемы, чтобы понять, использовать ли аннотации CDI или аннотацию JSF.Во многих местах (например, this ) я обнаружил, что мы всегда должны использовать аннотации CDI, но это действительно не работает, и мое демонстрационное приложение работает только тогда, когда я использую аннотации JSF.

Ниже приведены примеры, где я сталкиваюсь с проблемой, и мой вопрос - Может кто-нибудь объяснить, если я делаю что-то неправильно, ИЛИ если с JSF я должен использовать аннотации JSF, и если это правда, то я думаю,эти посты (например, this ) неверны. Я вижу, что в этом посте также упоминается, что если это JSF версии 2.0 или выше без CDI, то должна использоваться аннотация JSF, я проверил свой JSFверсия и это JavaServer Faces Reference Implementation 2.1.20 Fri Mar 8 05:55:39 PST 2013, но я не знаю, с CDI или нет.

Пожалуйста, обратитесь к моему фрагменту кода в конце.

@javax.faces.bean.ManagedBean v / s @ javax.inject.Named

Я обнаружил, что для использования управляемого компонента с синтаксисом EL (язык выражений) - #{}, класс управляемого компонента может быть аннотирован @javax.faces.bean.ManagedBean илис @javax.inject.Named.

Теоретически любой способ должен работать, но когда я использую аннотацию CDI, я получаю следующее исключение:

javax.el.PropertyNotFoundException: //C:/E_Drive/Projects/Workspace/HakerRank/testing/WebContent/greeting.xhtml @21,42 value="#{userNumberBean.userNumber}": Target Unreachable, identifier 'userNumberBean' resolved to null
    at com.sun.faces.facelets.el.TagValueExpression.getType(TagValueExpression.java:100)
    at com.sun.faces.renderkit.html_basic.HtmlBasicInputRenderer.getConvertedValue(HtmlBasicInputRenderer.java:95)
    at javax.faces.component.UIInput.getConvertedValue(UIInput.java:1030)
    at javax.faces.component.UIInput.validate(UIInput.java:960)
    at javax.faces.component.UIInput.executeValidate(UIInput.java:1233)
    at javax.faces.component.UIInput.processValidators(UIInput.java:698)

Но когда я использую аннотацию @javax.faces.bean.ManagedBean, тогда все работает.

@javax.enterprise.context.SessionScoped v / s @ javax.faces.bean.SessionScoped

Опять же, теоретически оба должны работать, но если я использую бин CDI, тогда это не бобсессионный компонент, и когда я обновляю свою страницу, я все еще вижу ### UserNumberBean Instantiation ... в журналах (хотя я могу видеть, что мой браузер имеет тот же идентификатор JSESSION - Cookie: JSESSIONID=a7iC7zNgF3ddWg069Hzny6T3UvgIVrfQ0GYJf8_pzT6Y0TzYAW3c!1544639247), который предполагает, что создается новый экземпляр компонента.Однако, если я использую javax.faces.bean.SessionScoped, тогда все работает как положено.


greetings.xhtml:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html lang="en" xmlns="http://www.w3.org/1999/xhtml"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:ui="http://java.sun.com/jsf/facelets">

<h:head>
    <title>Guess Number Facelets Application</title>
</h:head>
<h:body>
    <h:form>
        <h:graphicImage value="#{resource['images:OracleLogo.png']}"
            alt="Duke waving his hand" />
        <h2>Hi, my name is Duke. I am thinking of a number from
            #{userNumberBean.minimum} to #{userNumberBean.maximum}. Can you guess
            it?</h2>
        <p>
            <h:inputText id="userNo" title="Enter a number from 0 to 10:"
                value="#{userNumberBean.userNumber}">
                <f:validateLongRange minimum="#{userNumberBean.minimum}" maximum="#{userNumberBean.maximum}" />
            </h:inputText>
            <h:commandButton id="submit" value="Submit" action="response" />
        </p>
        <h:message showSummary="true" showDetail="false"
            style="color: #d20005;
font-family: 'New Century Schoolbook', serif;
font-style: oblique;
text-decoration: overline"
            id="errors1" for="userNo" />
    </h:form>
</h:body>
</html>

response.xhtml:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html lang="en" xmlns="http://www.w3.org/1999/xhtml"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:ui="http://java.sun.com/jsf/facelets">
<h:head>
    <title>Guess Number Facelets Application</title>
</h:head>
<h:body>
    <h:form>
        <h:graphicImage value="#{resource['images:OracleLogo.png']}"
            alt="Duke waving his hand" />
        <h2>
            <h:outputText id="result" value="#{userNumberBean.response}" />
        </h2>
        <h:commandButton id="back" value="Back" action="greeting" />
    </h:form>
</h:body>
</html>

UserNumberBean:

import java.io.Serializable;
import java.util.Random;

import javax.inject.Named;

@Named
@javax.enterprise.context.SessionScoped
public class UserNumberBean implements Serializable {
    private static final long serialVersionUID = 5443351151396868724L;
    Integer randomInt = null;
    Integer userNumber = null;
    String response = null;
    private int maximum = 10;
    private int minimum = 0;

    {
        System.out.println("### UserNumberBean Instantiation ...");
    }

    static{
        System.out.println("### UserNumberBean Static initialization ...");
    }

    public UserNumberBean() {
        Random randomGR = new Random();
        randomInt = new Integer(randomGR.nextInt(maximum + 1));
        // Print number to server log
        System.out.println("Duke's number: " + randomInt);
    }

    public void setUserNumber(Integer user_number) {
        userNumber = user_number;
    }

    public Integer getUserNumber() {
        return userNumber;
    }

    public String getResponse() {
        System.out.println("### userNumber: " + userNumber + " | randomInt: " + randomInt);
        if ((userNumber == null) || (userNumber.compareTo(randomInt) != 0)) {
            return "Sorry, " + userNumber + " is incorrect.";
        } else {
            return "Yay! You got it!";
        }
    }

    public int getMaximum() {
        return (this.maximum);
    }

    public void setMaximum(int maximum) {
        this.maximum = maximum;
    }

    public int getMinimum() {
        return (this.minimum);
    }

    public void setMinimum(int minimum) {
        this.minimum = minimum;
    }

}

ОБНОВЛЕНИЕ 1: @XtremeBiker - я использую Weblogic 12.1.2.Версия сервлета 3.0, а версия JSP 2.1, поэтому моя версия JEE должна быть> = 6, это означает, что у меня должен быть CDI.Я не знаю, как получить версию CDI.

Ответы [ 2 ]

0 голосов
/ 22 мая 2018

Если кто-то хочет понять всю концепцию и причины этого вопроса, то обратитесь к этому ответу, который был рекомендован @Kukeltje, спасибо, приятель.

Ниже приведен краткий обзор моегопроблема и то, что я узнал из этого:

  • Основная причина моей проблемы заключалась в том, что, хотя я использовал аннотацию javax.inject.Named, но она не вступила в силу, потому что я не былсоздание контейнера CDI.
  • Исправление кода должен был включить файл beans.xml в каталог WEB-INF.Прочитайте это о том, как настроить приложение CDI.Итак, в основном мне не хватало того, что я не настроил CDI, поэтому аннотации не вступили в силу.
    • С другой стороны, поскольку у меня был контейнер JEE 6, поэтому я явно нуждался в файле beans.xml, в контейнере JEE 7, если какой-либо класс имеет аннотации CDI, тогда сервер автоматически распознает приложение как приложение CDI, подробнее здесь .
  • Еще одна важная вещь, которую я узнал, - это то, что аннотации CDI предпочтительнее аннотаций JSF (хорошо, что я обнаружил и столкнулся с этой проблемой, иначе я мог бы закончитьиспользуя аннотации JSF).
0 голосов
/ 21 мая 2018

Управляемый компонент - это компонент, управляемый JSF.Это старая техника, введенная JSF, когда CDI не было доступно.В течение этого времени в JSF было определено несколько областей.

@javax.faces.bean.ManagedBean

@javax.faces.bean.SessionScoped

начиная с Jva EE 6CDI является частью версии EE.Компоненты CDI не являются специфичными для JSF и могут использоваться во всей экосистеме JEE.CDI определяет несколько областей.

@javax.inject.Named

@javax.enterprise.context.SessionScoped

Выше я сгруппировал аннотации JSF и CDI вместе.Не возможно их смешать.Если вы смешаете эти аннотации, ваше приложение не будет работать должным образом.

Больше не используйте старомодные теги JSF - они помечены как устаревшие.Начиная с JSF 2.3 (JEE 8) старые аннотации удаляются / будут удалены.

...