0

dukeguess number example を実行していますが、ライフサイクルが期待どおりに実行されていません。数値をinputText期待する があります。コンバーターとバリデーターもあります。バリデータを送信すると<h:form>、バリデータが呼び出されます。入力が整数であるかどうかをチェックする必要があります。マネージド Bean プロパティの値が更新されていません。以下はコードスニペットです。

<h:inputText id="userNo" label="User Number" value="#{UserNumberBean.userNumber}" 
               converterMessage="#{ErrMsg.userNoConvert}"  validator="#{UserNumberBean.validate}">
      <f:valueChangeListener  type="#{UserNumberBean.valueChange()}"></f:valueChangeListener>
                  <f:validateLongRange minimum="#{UserNumberBean.minimum}" maximum="#{UserNumberBean.maximum}" /> 
  </h:inputText>

ここでは、バリデータメソッドがinputTextコンポーネントに設定されています。を送信する<h:form>と、validateメソッドが呼び出されます。以下はメソッドです

public String validate(javax.faces.context.FacesContext fc, javax.faces.component.UIComponent ui, java.lang.Object o){
        System.out.println("in my own validation method");
        if(userNumber ==8){
            return "validation";
        }
        return "validation";
    }

これuserNumberは、クラスのバッキング Bean プロパティです。

public class UserNumberBean {

     public Integer userNumber = null;

public void setUserNumber(Integer user_number) {
        System.out.println("setting userName" + user_number);
        userNumber = user_number;
    }

    public Integer getUserNumber() {
        return userNumber;
    }
}

ゲッターとセッターがありますが、まだuserNumber値が設定されていません。にNullPointerExceptionアクセスするとバリデーターメソッドに入りuserNumberます。何が問題なのか教えてください。以下はコードスニペットです

<HTML xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
    <HEAD> <title>Hello</title> </HEAD>
    <%@ page contentType="application/xhtml+xml" %>
    <%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
    <%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
    <body bgcolor="white">
    <f:view>
    <h:form id="helloForm" >
      <h2>Hi. My name is Duke.  I'm thinking of a number Man from
      <h:outputText lang="en_US" value="#{UserNumberBean.minimum}"/> to
      <h:outputText value="#{UserNumberBean.maximum}"/>.  Can you guess
      it?</h2>

      <h:graphicImage id="waveImg" url="/wave.med.gif" alt="Duke waving" />
      <h:inputText id="userNo" label="User Number" value="#{UserNumberBean.userNumber}" 
                   converterMessage="#{ErrMsg.userNoConvert}"  validator="#{UserNumberBean.validate}">
          <f:valueChangeListener  type="#{UserNumberBean.valueChange()}"></f:valueChangeListener>
                      <f:validateLongRange minimum="#{UserNumberBean.minimum}" maximum="#{UserNumberBean.maximum}" /> 
      </h:inputText>
      <h:commandButton id="submit" action="success" value="Submit" />
      <p>
      <h:message style="color: red; font-family: 'New Century Schoolbook', serif; font-style: oblique; text-decoration: overline" id="errors1" for="userNo"/>
    </p>
   </h:form>
  </f:view>
 </body>
</HTML> 




import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.validator.LongRangeValidator;
import javax.faces.validator.Validator;
import javax.faces.validator.ValidatorException;
import java.util.Random;


public class UserNumberBean {
    Integer randomInt = null;
     public Integer userNumber = null;
    String response = null;
    private boolean maximumSet = false;
    private boolean minimumSet = false;
    private long maximum = 0;
    private long minimum = 0;

    public UserNumberBean() {

        System.out.println(" in constructor");
        Random randomGR = new Random();
        randomInt = new Integer(randomGR.nextInt(10));
        System.out.println("Duke's number: " + randomInt);
    }

    public void setUserNumber(Integer user_number) {
        System.out.println("setting userName" + user_number);
        userNumber = user_number;
    }

    public Integer getUserNumber() {
        return userNumber;
    }

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

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

    public void setMaximum(long maximum) {
        this.maximum = maximum;
        this.maximumSet = true;
    }

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

    public void setMinimum(long minimum) {
        this.minimum = minimum;
        this.minimumSet = true;
    }


    public String validate(javax.faces.context.FacesContext fc, javax.faces.component.UIComponent ui, java.lang.Object o){
        System.out.println("in my own validation method");
        if(userNumber ==8){
            return "validation";
        }
        return "validation";
    }

    public void valueChange(){
        System.out.println(" in value change");
    }
}

リクエストの適用フェーズとは実際には何ですか? リクエストの適用フェーズでは何が行われますか? モデル値の更新フェーズとの違い

4

1 に答える 1

4

バリデーターは 2 つの点で壊れています。

  1. メソッド署名が間違っています。void を返す必要があります。検証に失敗した場合は、 をスローする必要がありますValidatorException。成功したら、戻ってきて、それ以上何もしないでください。

  2. モデル値 (その時点ではまったく設定されていません) ではなく、3 番目の引数として提供された値を検証する必要があります。

したがって、これは次のようにする必要があります。

public void validate(FacesContext context, UIComponent component, Object value) {
    if (value == null) {
        return; // Ignore it. Let required="true" handle.
    }

    if (value != 8) {
        // Assuming that 8 is the guess number?
        throw new ValidatorException(new FacesMessage("Wrong guess, try again."));
    }
}

モデル値をプリミティブ整数NullPointerExceptionと比較しようとしているために発生します。これにより、オートボクシングがプリミティブにアンボックスしようとしますが、それ自体がプリミティブ形式で表現できない場合は失敗します。userNumber8userNumberuserNumbernull

フェーズに関しては、リクエスト値の適用フェーズは必ず呼び出されますが、それ以外の場合は検証フェーズは呼び出されません。リクエスト値の適用フェーズでモデル値が更新されることを期待しているようです。これは正しくありません。JSF 入力コンポーネントの にリクエスト パラメータを適用しますsubmittedValue

以下も参照してください。

于 2013-07-18T15:26:50.403 に答える