FacesMessage的出现取决于标记序列

时间:2013-04-09 13:09:23

标签: jsp jsf

在别人写的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>移到<h:outputText>行之后,则会显示该消息。这是为什么?这应该有效吗?

1 个答案:

答案 0 :(得分:2)

您正在使用getter方法执行业务工作,此方法仅在呈现响应阶段期间生成HTML输出期间调用此特定示例。如果事先已经生成了消息组件的HTML表示,则在此特定构造中添加faces消息为时已晚。您无法从响应中收回已写入的字节。

事实上,you should never do business logic in getters。您没有在任何地方明确说明具体的功能要求,因此很难提出正确的解决方案,但在此特定示例中,其中一个解决方案是在预渲染视图侦听器方法中执行作业。

<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;
}