阻止用户向页面发出GET请求

Tha*_*ham 3 java jsf web.xml web-applications

如果我的问题没有任何意义,我很抱歉.所以这就是我所拥有的:2页,A.jsfB.jsf.当我按下一个按钮时A.jsf,代码设置一个值object并重定向到B.jsf.包含B.jsf将取决于我设置的对象A.jsf(这取决于我点击的按钮).因此,我不想让用户在Web浏览器上键入它

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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

然后在我的 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>
Run Code Online (Sandbox Code Playgroud)

All credits go to BalusC

Bal*_*usC 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>
Run Code Online (Sandbox Code Playgroud)

但是,这显示HTTP 403错误.这不会(也不能)重定向到a.jsf(至少,没有提供必要的检查提供自定义403错误页面,但这很简单).如果重定向是强制性的,则可以使用其他解决方案:

  1. 在请求作用域的构造函数中,b.jsf检查回发方式ResponseStateManager#isPostback(),然后使用相应的方式重定向ExternalContext#redirect().

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

    如果您已经使用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);
    }
    
    Run Code Online (Sandbox Code Playgroud)

    这可以更容易地扩展到未来的方法和页面,您可以配置为在各init-param的的Filterweb.xml.