如何设置JSF PhaseListener的参数来拦截和采取相应的行动?

时间:2014-11-17 11:18:30

标签: jsf parameters phaselistener

我正在尝试为执行操作方法并重定向到另一个页面后拦截PhaseListener的参数进行拦截 - 这是最好的方法吗?

  • 显式redirect调用并使用PrettyFacesWrappedRequest
  • 包装其他参数
  • 在两端使用flash范围(调用者bean和阶段监听器afterPhase)?

1 个答案:

答案 0 :(得分:0)

您使用的是哪个版本的JSF?使用JSF 2.0,2.1或2.2,您可以使用CDI bean并使用拦截器来更改方法的返回值。

我不相信因为商业逻辑而改变JSF生命周期是一个好主意。

您可以使用拦截器。例如

的index.xhtml



<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://xmlns.jcp.org/jsf/html">
<h:head>
  <title>Facelet Title</title>
</h:head>
<h:body>
  <h:form>
    <h:inputText id="txtNro" value="#{testCDI.value}"></h:inputText>
    <h:commandButton value="Send" action="#{testCDI.doSomething()}" />
  </h:form>
</h:body>
</html>
&#13;
&#13;
&#13;

然后你的CDI Interceptor Intercept FacesContext和HttpServletRequest(你可以使用其中任何一个):

@RedirectInterceptor
@Interceptor
public class MyInterceptor {

    @Inject
    HttpServletRequest req;

     @AroundInvoke
    public Object intercept(InvocationContext context) throws Exception {        
        Logger.getLogger("CdiInterceptor").log(Logger.Level.INFO, "REQUEST  "+req);    
        req.setAttribute("irA", "index.xhtml");
        Logger.getLogger("CdiInterceptor").log(Logger.Level.INFO, "FACES CONT "+FacesContext.getCurrentInstance());    
        for(Map.Entry<String, Object> ent : context.getContextData().entrySet()){
            Logger.getLogger("CdiInterceptor").log(Logger.Level.INFO, ent.getKey()+ " --- "+ent.getValue());    
        }
        Logger.getLogger("CdiInterceptor").log(Logger.Level.INFO, " Init logger");
        Object value = context.proceed();

        Logger.getLogger("CdiInterceptor").log(Logger.Level.INFO, " Value : "+value);
        Logger.getLogger("CdiInterceptor").log(Logger.Level.INFO, req.getAttribute("irA"));
            return req.getAttribute("irA");
    }
}

最后你使用&#34; HttpServletRequest&#34;在您的CDI控制器中用于分析HTTP servlet请求,甚至您可以使用它来放置请求属性。

@Named(value = "testCDI")
@RequestScoped
public class CdiInterceptor implements Serializable{

    @Inject HttpServletRequest req;

    private int value;

    @RedirectInterceptor
    public String doSomething(){
        if(value%3 ==0){ 
            req.setAttribute("irA", "index.xhtml");
        }else if(value%3==1){
            req.setAttribute("irA", "page1.xhtml");
        }else{
            req.setAttribute("irA", "page2.xhtml");
        }            
        return null;
    }

通过这种方式,您可以基于HTTP Servlet请求实现重定向到另一个JSF页面。

您可能还记得在beans.xml中启用CDI拦截器

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
       bean-discovery-mode="annotated">
    <interceptors>
        <class>cdi.test.MyInterceptor</class>
    </interceptors>
</beans>

更新拦截器用于横切关注点,因此您必须在将其应用于多个方法时使用它。如果每个方法在拦截中都有自己的逻辑,则可以使用装饰器。