在sessionCreated()之前调用的JSF 2.0 encodeAll()

时间:2012-04-10 15:49:27

标签: jsf jsf-2 custom-component

我在JSF 2.0中创建了一个自定义组件。其目的是在输入文本框中显示会话属性值。我希望在HttpSessionListener sessionCreated方法中创建会话属性。问题是encodeAll方法在sessionCreated方法之前被调用。如何在sessionCreated之前调用encodeAll

的web.xml

<context-param>
    <param-name>javax.faces.FACELETS_LIBRARIES</param-name>
    <param-value>/WEB-INF/components.taglib.xml</param-value>
</context-param>
<listener>
    <listener-class>mycomp.jsf.listener.MyListener</listener-class>
</listener>

components.taglib.xml

<facelet-taglib xmlns="http://java.sun.com/xml/ns/javaee"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-facelettaglibrary_2_0.xsd"
            version="2.0">
<namespace>http://mycomp/jsf/components</namespace>
<tag>
    <tag-name>mycomp</tag-name>
    <component>
        <component-type>MyComp</component-type>
    </component>
</tag>
</facelet-taglib>

MyListener.java

public class MyListener implements HttpSessionListener {
@Override
public void sessionCreated(HttpSessionEvent event) {
    HttpSession session = event.getSession();
    session.setAttribute("sessionid", session.getId());
}
@Override
public void sessionDestroyed(HttpSessionEvent se) {
} 
}

MyComp.java

@FacesComponent(value = "MyComp")
public class MyComp extends UIComponentBase {
public MyComp() {
    setRendererType(null);
}
protected Class getComponentClass() {
    return this.getClass();
}
@Override
public void decode(FacesContext context) {
//some logic
}
@Override
public void encodeAll(FacesContext context) throws IOException {
    String clientId = getClientId(context) + ":token";
    HttpSession session = (HttpSession) context.getExternalContext().getSession(false);
    String sessionId = (String) session.getAttribute("sessionid");
    if (sessionId == null || "".equals(sessionId)) {
        throw new RuntimeException("sessionid is missing!");
    }
    ResponseWriter writer = context.getResponseWriter();
    writer.startElement("input", this);
    writer.writeAttribute("type", "text", "type");
    writer.writeAttribute("name", clientId, "name");
    writer.writeAttribute("value", sessionId, "value");
    writer.endElement("input");
}
@Override
public String getFamily() {
    return null;
}
}

的index.xhtml

<html xmlns="http://www.w3.org/1999/xhtml"
  xmlns:h="http://java.sun.com/jsf/html"
  xmlns:t="http://mycomp/jsf/components">
<h:head>
</h:head>
<h:body>
    <h:form>
        <t:mycomp />
    </h:form>
</h:body>
</html>

1 个答案:

答案 0 :(得分:0)

getSession(false)替换为getSession(true)

HttpSession session = (HttpSession) context.getExternalContext().getSession(true);

布尔值表示在尚未创建会话时是否应创建会话。使用getSession(false)时,如果在此时尚未创建null,那么当您调用任何方法时,NullPointerException就会产生ExternalContext#getSessionMap()。另请参阅javadoc


对于具体问题,

无关,更清洁的是使用javax.servlet代替。在JSF代码中导入“原始”HttpSession session = (HttpSession) context.getExternalContext().getSession(true); String sessionId = (String) session.getAttribute("sessionid"); if (sessionId == null || "".equals(sessionId)) { throw new RuntimeException("sessionid is missing!"); } 通常表示JSF代码中有气味。即有些东西不必要地过于复杂。然后,您应该使用纯JSF API寻找更简单的方法。

替换

String sessionId = (String) context.getExternalContext().getSessionMap().get("sessionid");
if (sessionId == null || "".equals(sessionId)) {
    throw new RuntimeException("sessionid is missing!");
}

通过

{{1}}