为什么JSF打了xhtml页面3次

时间:2015-04-15 09:11:18

标签: jsf servlet-filters jsf-2.2

我有一个JSF应用程序。在点击入口点。

/MyApp/start.xhtml 

该页面包含一个视图操作,它将根据查询字符串params决定要转到哪个页面。

<f:viewAction action="#{startController.newQuote()}" />

@ManagedBean
@SessionScoped
public class StartController {
public String newQuote(){
    ....
    FacesContext fc = FacesContext.getCurrentInstance();
    ConfigurableNavigationHandler nav = (ConfigurableNavigationHandler)fc.getApplication().getNavigationHandler();
    nav.performNavigation("aboutYou.xhtml?faces-redirect=true");
}

据报道,aboutYou.xhtml根据我的过滤器被点击了3次。

@WebFilter("*.xhtml")
public class TrackingFilter implements Filter {

    private static Logger LOG = Logger.getLogger(TrackingFilter.class);

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException {    

        HttpServletRequest req = (HttpServletRequest) request;

        LOG.trace("request URI: " + req.getRequestURI());
}
这是为什么?我怀疑它与?faces-redirect=true使用的PRG模式有关,但我可能希望看到这两次,而不是3次。

如何优化我的过滤器,以便我只捕获一个移动到该页面的动作?

1 个答案:

答案 0 :(得分:3)

根据评论:

  

浏览器显示x2 HTTP200 POST

因此,这是完全预期的1 GET请求。如果您在加载请求的页面时触发了一些ajax请求,则会发生这些POST请求。例如,假设PrimeFaces,<p:outputPanel deferred="true"><p:remoteCommand autoRun="true">等,通常都与延迟加载有关。

您可以通过检查HttpServletRequest#getMethod()来过滤器识别POST请求。

if ("POST".equals(request.getMethod())) {
    // It's a POST request.
}

或者,特别是通过检查Faces-Request标题来获取JSF ajax请求。

if ("partial/ajax".equals(request.getHeader("Faces-Request"))) {
    // It's a JSF ajax request.
}

对具体问题

无关,你根本就没有在这里执行PRG。默认情况下,<f:viewAction>仅在GET请求上调用,而不是在POST请求上调用(仅在添加onPostback="true"时执行此操作)。并且,<f:viewAction action>的行为与<h:commandButton action>完全相同,包括像往常一样返回导航案例结果(唯一的区别是它是GET,而不是POST)。因此,所有导航处理程序和重定向混乱都是不必要的。

public String newQuote() {
    // ...

    return "aboutYou.xhtml";
}

仅在不支持返回String结果时才需要导航处理程序方法(如<f:event type="preRenderView">中所述)。只有在初始请求是POST请求时才需要重定向(例如<h:commandButton action><f:viewAction onPostback="true">)。