1

他の誰かが書いたjsfアプリケーションで作業していると、非常に基本的なものが欠けているに違いありません。私はそれをこれに落としましたが、これは機能していません:

page.jsp:

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>

<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h"%>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f"%>
<!doctype html>
<html>
<body>
    <f:view>
        <h:messages id="error" globalOnly="true"/>
        <h:outputText value="#{testBean.msg}"/>
    </f:view>
</body>
</html>

testBean.java:

import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;

public class testBean {

    public String getMsg() {
        FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "getMsg"), null));
        return "getMsg";
    }
}

このコードは、 で生成されたエラー メッセージを表示しませんtestBean#getMsg<h:messages>行の後に toを移動すると<h:outputText>、メッセージが表示されます。何故ですか?これは機能するはずですか?

4

1 に答える 1

2

この特定の例では、レンダリング応答フェーズで HTML 出力を生成するときにのみ呼び出される getter メソッドでビジネス ジョブを実行しています。メッセージ コンポーネントの HTML 表現が事前に生成されている場合、この特定の構成で faces メッセージを追加するには遅すぎます。既に書き込まれたバイトを応答から取り戻すことはできません。

実際、ゲッターでビジネス ロジックを行うべきではありません。具体的な機能要件がどこにも明確に述べられていないため、適切な解決策を提案するのは困難ですが、この特定の例では、解決策の 1 つは、レンダリング前のビュー リスナー メソッドでジョブを実行することです。

<f:view>
    <f:event type="preRenderView" listener="#{testBean.init}" />
    <h:messages id="error" globalOnly="true"/>
    <h:outputText value="#{testBean.msg}"/>
</f:view>

private String msg;

public void init() { 
    msg = "getMsg";
    FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "getMsg"), null));
}

public String getMsg() { // Keep getter untouched! Don't do business logic in there!
    return msg;
}

上記の更新は、JSF2 Facelets にのみ適用されます。レガシーおよび非推奨の JSP では、同様の方法はありません。最善の策は、getter が空の文字列を返し、それを JSP の先頭で参照することです。

<f:view>
    <h:outputText value="#{testBean.initHack}" />
    <h:messages id="error" globalOnly="true"/>
    <h:outputText value="#{testBean.msg}"/>
</f:view>

private String msg;

public String getInitHack() {
    msg = "getMsg";
    FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "getMsg"), null));
    return "";
}

public String getMsg() { // Keep getter untouched! Don't do business logic in there!
    return msg;
}
于 2013-04-09T13:36:47.413 に答える