8

@ManagedProperty が CDI(?) で機能しないため、@Named で @ManagedProperty アノテーションを使用できない場合、どのように URL のパラメーターを facelets クライアントに渡しますか? 私のコードでは、javax.mail.getMessageNumber() を「戻る」ボタンと「進む」ボタンを介して details.xhtml に渡したいと考えています。

@Inject を使用する必要があることは理解していますが、何がどのように注入されるのでしょうか?

glassfish ログから、id は常に 0 です。これは非常に奇妙です。「進む」をクリックしても、何度クリックしてもidが1を超えることはありません。もちろん、それは問題の単なる兆候です。もちろん、望ましい出力は、次のメッセージに進むことです。

おそらく、メッセージ、または少なくとも int をセッションに入れますか?

クライアントは次のようになります。

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<ui:composition xmlns:ui="http://java.sun.com/jsf/facelets"
                template="./template.xhtml"
                xmlns:h="http://java.sun.com/jsf/html"
                xmlns:c="http://java.sun.com/jsp/jstl/core"
                xmlns:f="http://java.sun.com/jsf/core">
    <ui:define name="top">
        <h:form>
            <h:form>
                <h:outputLink id="link1" value="detail.xhtml">
                    <f:param name="id" value="#{detail.back()}" />
                    <h:outputText value="back" />
                </h:outputLink>
            </h:form>
        </h:form>
        <h:form>
            <h:outputLink id="link1" value="detail.xhtml">
                <f:param name="id" value="#{detail.forward()}" />
                <h:outputText value="forward" />
            </h:outputLink>
        </h:form>
    </ui:define>
    <ui:define name="content">
        <h:outputText value="#{detail.content}"></h:outputText>
    </ui:define>
</ui:composition>

そして豆はそのまま:

package net.bounceme.dur.nntp;

import java.util.logging.Level;
import java.util.logging.Logger;
import javax.enterprise.context.RequestScoped;
import javax.faces.bean.ManagedProperty;
import javax.inject.Named;
import javax.mail.Message;

@Named
@RequestScoped
public class Detail {

    private static final Logger logger = Logger.getLogger(Detail.class.getName());
    private static final Level level = Level.INFO;
    @ManagedProperty(value = "#{param.id}")
    private Integer id = 0;
    private Message message = null;
    private SingletonNNTP nntp = SingletonNNTP.INSTANCE;

    public Detail() {
        message = nntp.getMessage(id);
    }

    public int forward() {
        logger.log(level, "Detail.forward.." + id);
        id = id + 1;
        logger.log(level, "..Detail.forward " + id);
        return id;
    }

    public int back() {
        logger.log(level, "Detail.back.." + id);
        id = id - 1;
        logger.log(level, "..Detail.back " + id);
        return id;
    }

    public Message getMessage() {
        return message;
    }

    public String getContent() throws Exception {
        return message.getContent().toString();
    }
}
4

3 に答える 3

14

これは、JSF 2.3 で導入された でのみ機能しjavax.faces.annotation.ManagedPropertyます。

@Inject @ManagedProperty("#{param.id}")
private String id;

非推奨になっjavax.faces.bean.ManagedPropertyたアノテーションは、JSF@ManagedBeanクラスでのみ機能します。つまり、JSF によって管理されるインスタンスです。CDI によって管理されているインスタンスでは機能しません@NamedMessageさらに、別の間違いを犯しました:コンストラクターで管理プロパティに基づいて準備しようとしています。それが本当@ManagedBeanの だったら、それもうまくいきませんでした。コンストラクターが呼び出される前にセッター メソッドを呼び出すことができないため、構築中に管理プロパティを使用することはできません。@PostConstructこれにはメソッドを使用する必要がありました。

JSF 2.3 にアップグレードできない場合は、カスタム CDI アノテーションを作成する必要があります。具体例はこちらのブログに掲載されています。関連性の抜粋を次に示します。

カスタム@HttpParam注釈:

@Qualifier
@Retention(RUNTIME)
@Target({TYPE, METHOD, FIELD, PARAMETER})
public @interface HttpParam {
    @NonBinding
    public String value() default "";
}

アノテーション値プロデューサー:

public class HttpParamProducer {

    @Inject
    FacesContext facesContext;

    @Produces
    @HttpParam
    String getHttpParameter(InjectionPoint ip) {
        String name = ip.getAnnotated().getAnnotation(HttpParam.class).value();
        if ("".equals(name)) name = ip.getMember().getName();
        return facesContext.getExternalContext()
                .getRequestParameterMap()
                .get(name);
    }
}

使用例:

@Inject @HttpParam
private String id;

JSF ユーティリティ ライブラリOmniFacesには、@Paramまさにこの目的のための があり、JSF 変換と検証のサポートが組み込まれています。


Detailまたは、マネージド Beanの外部コンテキストからリクエスト パラメータを手動で取得することもできます。マネージド Bean の初期化を行うための推奨される@PostConstruct方法は、コンストラクターではなくメソッドを使用することです。コンストラクターは、マネージド Bean の作成とはまったく異なる目的で使用できるためです

@PostConstruct
public void init() {
    String id = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("id");
    // ...
}

IMO もこの特定のケースにより適している別の方法は、カスタム コンバーターによって<f:viewParam>ID を直接変換できるようにすることです。Message

<f:metadata>
    <f:viewParam name="id" value="#{detail.message}" converter="messageConverter" />
</f:metadata>

だけで

@Named
public class Detail {

    private Message message;

    // Getter+setter
}

そして

@FacesConverter("messageConverter")
public class MessageConverter implements Converter {

    // Convert string id to Message object in getAsObject().
    // Convert Message object to string id in getAsString().

}

こちらもご覧ください

于 2012-04-07T23:35:52.480 に答える
1

まず、エイリアンの部分について説明します。Glassfish は JBoss Weld を CDI 実装として使用します。Oracle は独自の実装を開発していません。

そして、エラーメッセージの意味について: FacesContext は単に経由で注入できません@Inject。そのためのかなり古い機能要求があり、Seam または Solder がプロデューサーを提供すると思います。ただし、そのためだけにどちらのライブラリも統合する必要はありません。を介して、通常のマネージド Bean で行うように、faces コンテキストにアクセスしますFacesContext.getCurrentInstance()

于 2012-04-08T19:58:08.417 に答える
0

私は単純なことを行う複雑な方法を求めていました。CDI では、上記で BalusC によって説明されているように、パラメーターを渡すために @ManagedProperty を使用することはできません。代わりに、次のように xhtml ファイルをセットアップするだけです。

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<ui:composition xmlns:ui="http://java.sun.com/jsf/facelets"
                template="./template.xhtml"
                xmlns:h="http://java.sun.com/jsf/html"
                xmlns:c="http://java.sun.com/jsp/jstl/core"
                xmlns:f="http://java.sun.com/jsf/core">
    <ui:define name="top">
        <h:form>
            <h:commandButton action="#{messages.back()}" value="..back" />
        </h:form>
        <h:form>
            <h:commandButton action="#{messages.forward()}" value="forward.." />
        </h:form>
    </ui:define>
    <ui:define name="content">
        <h:dataTable value="#{messages.model}" var="m">
            <h:column>
                <f:facet name="id">
                    <h:outputText value="id" />
                </f:facet>
                <h:outputLink id="hmmm" value="detail.xhtml">
                    <f:param name="id" value="#{m.getMessageNumber()}" />
                    <h:outputText value="#{m.getMessageNumber()}" />
                </h:outputLink>
            </h:column>
            <h:column>
                <f:facet name="subject">
                    <h:outputText value="subject" />
                </f:facet>
                <h:outputText value="#{m.subject}"></h:outputText>
            </h:column>
            <h:column>
                <f:facet name="content">
                    <h:outputText value="content" />
                </f:facet>
                <h:outputText value="#{m.sentDate}"></h:outputText>
            </h:column>
            <h:column>
                <f:facet name="date">
                    <h:outputText value="date" />
                </f:facet>
                <h:outputLink value="#{messages.getUrl(m)}">#{messages.getUrl(m)}</h:outputLink>
            </h:column>
        </h:dataTable>
    </ui:define>
</ui:composition>

に:

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<ui:composition xmlns:ui="http://java.sun.com/jsf/facelets"
                template="./template.xhtml"
                xmlns:h="http://java.sun.com/jsf/html"
                xmlns:c="http://java.sun.com/jsp/jstl/core"
                xmlns:f="http://java.sun.com/jsf/core">
    <ui:define name="top">
        <h:form>
            <h:outputLink id="back" value="detail.xhtml">
                <f:metadata>
                    <f:viewParam name="id" value="#{detail.id}"  />
                </f:metadata>
                <f:param name="id" value="#{detail.back()}" />
                <h:outputText value="back" />
            </h:outputLink>
        </h:form>
        <h:form>
            <h:outputLink id="forward" value="detail.xhtml">
                <f:metadata>
                    <f:viewParam name="id" value="#{detail.id}"  />
                </f:metadata>
                <f:param name="id" value="#{detail.forward()}" />
                <h:outputText value="forward" />
            </h:outputLink>
        </h:form>
    </ui:define>
    <ui:define name="content">
        <h:outputText value="#{detail.content}"></h:outputText>
    </ui:define>
</ui:composition>

この単純な例では、コンバーターは必要なく、デフォルトで問題なく動作することを明確にするために、これを含めているのは誰にでもあります。

元の質問も少し混乱しています。これに関する他の質問を見ると、他の人はこのような単純な例から利益を得ることができると思います. 非常に多くの例が過度に複雑であるか、EJB などを含んでいます。

于 2012-04-10T11:14:28.120 に答える