11

JSFViewScopedBeanをManagedPropertyとしてjavax.faces.validator.Validatorを実装するRequestScopedBeanに注入しようとしています。ただし、常にViewScopedBeanの新しいコピーが注入されます。

ViewScoped Bean

@ViewScoped
@ManagedBean
public class Bean {

     private Integer count = 1;     

     private String field2;      

     public String action(){
          ++count;
          return null;
     }

     public String anotherAction(){
          return null;
     }

     //getter and setter

}

バリデーター

@RequestScoped
@ManagedBean
public class SomeValidator implements Validator {

     public void validate(FacesContext context, UIComponent comp, Object value)
        throws ValidatorException {

           //logging bean.getCount() is always one here. Even after calling ajax action a few times

     }
     @ManagedProperty(value = "#{bean}")
     private Bean bean;
}

xhtmlページ

<!DOCTYPE html>
 <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">
<h:head>

</h:head>

<h:body>
   <h:form>

    <h:panelGroup layout="block" id="panel1">


        <h:commandButton type="submit" value="Action" action="#{bean.action}">
            <f:ajax render="panel1"></f:ajax>
        </h:commandButton>

        <h:outputText value="#{bean.count}"></h:outputText>

    </h:panelGroup>

    <h:panelGroup layout="block" id="panel2">

        <h:inputText type="text" value="#{bean.field1}">
            <f:validator binding="#{someValidator}" />
        </h:inputText>

    </h:panelGroup>

    <h:commandButton type="submit" value="Another Action" action="#{bean.anotherAction}">
        <f:ajax execute="panel2" render="panel2"></f:ajax>
    </h:commandButton>

 </h:form>

</h:body>

</html>

コードで述べたように、ajaxアクションを数回呼び出した後でも、bean.getCount()をログに記録すると常に1つ表示されます。

ただし、ViewScopedをSessionScopedに変更した場合も、同じシナリオが機能します。また、RequestScoped BeanのValidator実装を削除し、PostConstructでロガーを使用すると、期待どおりにajaxリクエストごとにカウントが増加します。

私は何か間違ったことをしていますか?またはこれはどのように機能する必要がありますか?前もって感謝します

4

1 に答える 1

14

これは、のbinding属性が<f:validator>ビューのビルド時に評価されるためです。現時点では、ビュースコープはまだ使用できません(理にかなっていますが、まだビルド中です...)。そのため、新しいビュースコープのBeanが作成され、リクエストスコープのBeanと同じ効果があります。今後のJSF2.2では、この鶏卵の問題が解決される予定です。

それまでは、メソッド内にビュースコープのBeanが必要であると絶対に確信している場合( EJB、マルチフィールドバリデーターvalidate()などの他の方法を探したい)、プログラムで内部を評価するのが唯一の方法です。によって注入されるのではなく、メソッド自体。<f:attribute>#{bean}validate()@ManagedProperty

これに使用できますApplication#evaluateExpressionGet()

Bean bean = context.getApplication().evaluateExpressionGet(context, "#{bean}", Bean.class);

参照:

于 2012-11-27T13:26:22.127 に答える