2013-04-09 2 views
1

jsf 응용 프로그램 작업 다른 사람이 썼다 나는 아주 기본적인 것을 놓치고 있어야합니다.FacesMessage의 출현은 마크 업 순서에 따라 달라집니다.

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> 행 다음으로 이동하면 메시지가 표시됩니다. 왜 그런가요? 이게 효과가 있니?

답변

2

이 특정 예에서 getter 메소드로 비즈니스 작업을 수행하는 것은 렌더링 응답 단계에서 HTML 출력을 생성하는 동안에 만 호출됩니다. 메시지 구성 요소의 HTML 표현이 이미 미리 생성 된 경우 faces 메시지를 추가하는 것은 너무 늦습니다. 이미 작성된 바이트를 응답에서 가져올 수 없습니다.

사실, you should never do business logic in getters. 특정 기능 요구 사항을 명확하게 명시하지 않았기 때문에 올바른 솔루션을 제안하기는 어렵지만,이 특정 예제에서 솔루션 중 하나는 사전 렌더링 뷰 수신기 메서드에서 대신 작업을 수행하는 것입니다.

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

업데이트

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

위의 유일한 JSF2 Facelets에 적용됩니다. 기존의 JSP와 사용되지 않는 JSP에는 비슷한 방법이 없습니다. 가장 좋은 방법은 빈 문자열을 반환하고 JSP 위에 참조하는 getter입니다.

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

감사와

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

. 나는 정말로 의도 된 것이 무엇인지 확인해야 할 것이다. 나는 아직도 코드를 이해하지 못하지만 조금 더 나을 것입니다. –

+0

JSF는 렌더링 응답 중에 HTML 코드를 생성합니다. JSF는이를 위해 컴포넌트 트리 계층을 가로 지른다. 먼저, JSF는 ''을 만나고, 메시지를 수집하고 목록에 HTML을 생성합니다 (이 시점에서 메시지가 없습니다!). 그런 다음 JSF는''를 만나고, 값에 대한 getter를 호출하고 그 값으로 HTML을 생성합니다 (그 시점에서 메시지가 추가되었습니다!). 그러나 getter에 추가 된 faces 메시지는 미리 ''이 생성되어 표시 될 수 없습니다. 사전 렌더링 리스너 메소드는 * JSF가 HTML을 만들기 전에 호출됩니다. – BalusC

+0

다시 한번 감사드립니다. 나는 생각했다. 이제 실제로 일어날 일은 다음과 같습니다. 페이지로드시 일부 작업이 수행되어야합니다. 작업 결과가 표시되고 양식에 따라 채워집니다. 로드 단계는 내가 보여준 게터에서 모두 코딩됩니다. 실제 코드에서는 실제로 아무 것도 출력하지 않습니다. 그 모든 것이 콩의 생성자에 들어가야한다고 생각합니다. 맞습니까? –