33

、、、、など@EJBの依存関係をに注入するにはどうすればよいですか?私の特定のケースでは、SpringマネージドBeanを次の方法で注入する必要があります。@PersistenceContext@Inject@AutoWired@FacesValidator@AutoWired

@FacesValidator("emailExistValidator")
public class EmailExistValidator implements Validator {

    @Autowired
    private UserDao userDao;

    // ...
}

ただし、注入されずに残りnull、結果としてjava.lang.NullPointerException。のようで@EJB@PersistenceContextまた@Inject動作しません。

DBにアクセスできるように、バリデーターにサービスの依存関係を挿入するにはどうすればよいですか?

4

2 に答える 2

68

JSF 2.3+

すでにJSF2.3以降を使用していて、たとえば@EJB@PersistenceContextまたは を介してCDIでサポートされているアーティファクトを挿入する場合は、注釈に@Inject追加managed=trueするだけでCDIで管理できます。@FacesValidator

@FacesValidator(value="emailExistValidator", managed=true)

JSF 2.2-

JSF 2.3以降をまだ使用していない場合は、基本的にマネージドBeanにする必要があります。代わりにSpring @Component、CDI、@NamedまたはJSFを使用して、マネージドBeanにし、依存性注入の対象にします。@ManagedBean@FacesValidator

たとえば、CDIを使用したい場合@Named

@Named
@ApplicationScoped
public class EmailExistValidator implements Validator {
    // ...
}

#{name}また、ハードコードされた文字列のバリデーターIDとしてではなく、ELでマネージドBeanとして参照する必要があります。したがって、そう

<h:inputText ... validator="#{emailExistValidator.validate}" />

それ以外の

<h:inputText ... validator="emailExistValidator" />

また

<f:validator binding="#{emailExistValidator}" />

それ以外の

<f:validator validatorId="emailExistValidator" />

EJBの場合、JNDIから手動で取得することによる回避策があります。 @FacesConverterおよび@FacesValidatorでの@EJBの取得も参照してください。

JSFユーティリティライブラリOmniFacesを使用する場合、バージョン1.6以降、追加の構成やアノテーションなしでクラス@Injectで使用@EJBするための透過的なサポートが追加されます。CDIショーケースの例@FacesValidatorも参照してください。@FacesValidator

参照:


于 2011-09-27T16:21:11.507 に答える
2

Java EE8やJSF2.3を使用している場合は、JSFバリデーターに挿入できるようになりました。

Payara Server5.192#badassfishでMojarra2.3.9.payara-p2を使用してテストしました。

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://xmlns.jcp.org/jsf/html">
    <h:body>
        Hello from Facelets
        <h:form>
            <h:messages/>
            <h:inputText value="#{someBean.txtField}" validator="someValidator"/>
        </h:form>
    </h:body>
</html>
import javax.inject.Named;
import javax.enterprise.context.Dependent;

@Named(value = "someBean")
@Dependent
public class SomeBean {

  private String txtField;

  public String getTxtField() {
    return txtField;
  }

  public void setTxtField(String txtField) {
    this.txtField = txtField;
  }
}
import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.validator.FacesValidator;
import javax.faces.validator.Validator;
import javax.faces.validator.ValidatorException;
import javax.inject.Inject;

@FacesValidator(value = "someValidator", managed = true)
public class CustomValidator implements Validator<String> {

  @Inject
  NewClass newClass;

  @Override
  public void validate(FacesContext context, UIComponent component, String value)
      throws ValidatorException {

    System.out.println("validator running");
    System.out.println("injected bean: " + newClass);

    if (value != null && value.equals("badvalue")) {
      throw new ValidatorException(new FacesMessage(newClass.getMessage()));
    }
  }
}
public class NewClass {

  public String getMessage() {
    return "secret message";
  }
}
import javax.faces.annotation.FacesConfig;

// WITHOUT THIS INJECTION WILL NOT WORK!
@FacesConfig(version = FacesConfig.Version.JSF_2_3)
public class ConfigurationBean {
}

次のようにレンダリングする必要があります:

ここに画像の説明を入力してください

の必要性に気付く前に、私は壁に頭を約1時間叩きましたConfigurationBean。ドキュメントから:

FacesConfig.Version.JSF_2_3 この値は、セクション5.6.3「CDIfor ELResolution」およびセクション5.9「CDIIntegration」で指定されているように、CDIをEL解像度に使用し、JSFCDIインジェクションを有効にする必要があることを示します。

そして、このGitHubの問題から、https ://github.com/eclipse-ee4j/glassfish/issues/22094 :

デフォルトでは、JSF 2.3は、以前のリリースのJSFとの互換モードで実行されます。ただし、CDI管理対象Beanがアノテーション@javax.faces.annotation.FacesConfigでアプリケーションに含まれている場合を除きます。JSF 2.3モードに切り替えるには、次のような構成Beanが必要です。(ConfigurationBeanを表示

..。

JSFを「現在のバージョン」に切り替える必要があるという事実は非常に物議を醸しました。EG全体がこれに反対票を投じましたが、最終的には、JCPがJavaEEおよびスペックリードに適用する下位互換性要件を回避できませんでした。

于 2019-12-27T19:32:37.050 に答える