2010-08-18 80 views
3

如果我的问题没有任何意义,我很抱歉。所以这里是我的:2页,A.jsfB.jsf。当我按下A.jsf中的按钮时,代码将设置object的值并重定向到B.jsf。包含B.jsf将取决于我在A.jsf中设置哪个对象(取决于我点击哪个按钮)。因此,我不想让用户在网络浏览器防止用户向页面发出GET请求

http://myhost:myport/myproject/B.jsf

键入这一点,并直接到达B.jsf。所以,没有GET请求到B.jsf,只有POST。如果我看到GET请求B.jsf,我重定向到A.jsf。我觉得解决方案在web.xml之内。
顺便说一句,我使用Netbean 6.8和Java EE 6

编辑 这里是解决方案。由于BalusC
MyFilter.java

package org.xdrawings.filter; 

public class MyFilter implements Filter{ 

    private FilterConfig filterConfig = null; 

    public void destroy(){} 

    public void init(FilterConfig filterConfig){ 
     this.filterConfig = filterConfig; 
    } 

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException{ 
     HttpServletRequest req = (HttpServletRequest)request; 
     HttpServletResponse res = (HttpServletResponse) response; 
     if("GET".equals(req.getMethod()) && "/B.jsf".equals(req.getServletPath())){ 
      res.sendRedirect("A.jsf"); 
     }else { 
      chain.doFilter(request, response); 
     } 
    } 
} 

然后我web.xml

<filter> 
    <filter-name>My Filter</filter-name> 
    <filter-class>org.xdrawings.filter.MyFilter</filter-class> 
</filter> 
<filter-mapping> 
    <filter-name>My Filter</filter-name> 
    <url-pattern>*.jsf</url-pattern> 
</filter-mapping> 

All credits go to BalusC

回答

7

是的,如你所猜,可以从web.xml中控制。您需要声明security-constrainturl-pattern/b.jsfhttp-methodGET,以及一个空的auth-constraint

<security-constraint> 
    <display-name>Prevent GET requests on the b.jsf file</display-name> 
    <web-resource-collection> 
     <web-resource-name>The b.jsf file</web-resource-name> 
     <url-pattern>/b.jsf</url-pattern> 
     <http-method>GET</http-method> 
    </web-resource-collection> 
    <auth-constraint /> 
</security-constraint> 

然而这显示HTTP 403 error。这不(也不能)重定向到a.jsf(至少,不是没有提供必要的检查提供自定义403错误页面,但这是很难看的)。如果重定向是强制性的,其他的解决方案可供选择:

  1. 在请求的构造函数通过ResponseStateManager#isPostback()作用域与b.jsf支票回传相关的bean,然后使用ExternalContext#redirect()重定向相应。

    FacesContext context = FacesContext.getCurrentInstance(); 
    if (!context.getRenderKit().getResponseStateManager().isPostback(context)) { 
        context.getExternalContext().redirect("a.jsf"); 
    } 
    

    如果你已经在JSF 2.0,您还可以使用便捷的方法,而不是FacesContext#isPostback(),这是打字少。

  2. 或者作为更高层次的方法,创建一个完成任务的Filter。请求的页面和HTTP方法分别可以通过HttpServletRequest#getServletPath()getMethod()获得,重定向可以使用HttpServletResponse#sendRedirect()完成。

    HttpServletRequest req = (HttpServletRequest) request; 
    HttpServletResponse res = (HttpServletResponse) response; 
    if ("GET".equals(req.getMethod()) && "/b.jsf".equals(req.getServletPath())) { 
        res.sendRedirect("a.jsf"); 
    } else { 
        chain.doFilter(request, response); 
    } 
    

    这可以更容易地扩展到未来的方法和页面,你可以在web.xmlFilter的各init-param下配置。

+1

令我惊讶的是,您对Web开发了解多少。你的第一种方法很好。但是,我也想学习第二种方法,因为我总是听到有人创建过滤器,但不知道它是什么。所以你好像在这里创建一个自定义的'Filter',并告诉项目通过'web.xml'使用该过滤器,对吗?让我试试看,然后回到你身边。非常感谢你 – 2010-08-19 23:50:27

+0

我实现你的第二种方法,但我有几个问题,你可以看看我的更新后的帖子,看看我的实现。 – 2010-08-20 00:26:10

+1

过滤器可以映射到'/ *'的'',或者更具体的'* .jsf',甚至更具体的'/ b.jsf'(然后删除'if'块中的不必要的检查)。 ''是可选的。如果您定义了任何,则可以通过['FilterConfig#getInitParameter()'](http://download.oracle.com/javaee/5/api/javax/servlet/FilterConfig.html#getInitParameter%28java.lang .String%29)在'init()'方法内部,然后你可以将它指定为实例变量,并在'doFilter()'逻辑中进一步使用它。例如。一串逗号分隔的页面名称等等。 – BalusC 2010-08-20 00:29:14

1

是不是有什么毛病让B.jsf您在A.jsf设置的值,并发出一个重定向,如果是不存在?