Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/jsf/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 会话到期时的授权重定向在提交JSF表单时不起作用,页面保持不变_Java_Jsf_Redirect_Jsf 2_Authorization - Fatal编程技术网

Java 会话到期时的授权重定向在提交JSF表单时不起作用,页面保持不变

Java 会话到期时的授权重定向在提交JSF表单时不起作用,页面保持不变,java,jsf,redirect,jsf-2,authorization,Java,Jsf,Redirect,Jsf 2,Authorization,我正在使用JSF2。我实现了一个定制的Facesservlet,如下所示: public class MyFacesServletWrapper extends MyFacesServlet { // ... } 其中,我正在进行一些授权检查,并在用户未登录时发送重定向: public void service(ServletRequest request, ServletResponse response) { HttpServletRequest req = (HttpSe

我正在使用JSF2。我实现了一个定制的Facesservlet,如下所示:

public class MyFacesServletWrapper extends MyFacesServlet {
    // ...
}
其中,我正在进行一些授权检查,并在用户未登录时发送重定向:

public void service(ServletRequest request, ServletResponse response) {
    HttpServletRequest req = (HttpServletRequest) request;
    HttpServletResponse res = (HttpServletResponse) response;

    if (...) {
        String loginURL = req.getContextPath() + "/LoginPage.faces";
        res.sendRedirect(loginURL);
    }
}
当用户尝试导航到另一个页面时,此操作有效。但是,当JSF命令链接/按钮提交JSF表单时,这不起作用。点击并执行行
sendRedirect()
行,不会引发异常,但用户仍停留在同一页面。基本上,没有任何视觉变化


为什么这对页面导航有效,而对表单提交无效?

FacesContext.getCurrentInstance().getExternalContext().redirect(“newpage.xhtml”);试试这个。。。。代替res.sendredirect(cpath)。

您的具体问题很可能是由JSF命令链接/按钮实际发送的ajax请求引起的,而该请求反过来需要特殊的XML响应。如果您发送重定向作为对ajax请求的响应,那么它只会将ajax请求重新发送到该URL。由于重定向URL返回一个完整的HTML页面,而不是一个特殊的XML响应,因此在没有反馈的情况下,此操作将失败。实际上,您应该返回一个特殊的XML响应,其中指示JSF ajax引擎更改当前的
window.location

但实际上,你还有更大的问题:在工作中使用错误的工具。您应该使用一个用于该作业的servlet,而不是一个自行开发的servlet,当然也不能取代负责所有JSF工作的
FacesServlet

假设您在请求/视图范围的JSF支持bean中执行登录,如下所示(如果您使用的是容器管理的身份验证,请参见第二个示例):

然后,过滤器的启动示例应执行以下操作:

@WebFilter("/*") // Or @WebFilter(servletNames={"facesServlet"})
public class AuthorizationFilter implements Filter {

    private static final String AJAX_REDIRECT_XML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
        + "<partial-response><redirect url=\"%s\"></redirect></partial-response>";

    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws ServletException, IOException {    
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;
        HttpSession session = request.getSession(false);
        String loginURL = request.getContextPath() + "/login.xhtml";

        boolean loggedIn = (session != null) && (session.getAttribute("user") != null);
        boolean loginRequest = request.getRequestURI().equals(loginURL);
        boolean resourceRequest = request.getRequestURI().startsWith(request.getContextPath() + ResourceHandler.RESOURCE_IDENTIFIER + "/");
        boolean ajaxRequest = "partial/ajax".equals(request.getHeader("Faces-Request"));

        if (loggedIn || loginRequest || resourceRequest)) {
            if (!resourceRequest) { // Prevent browser from caching restricted resources. See also https://stackoverflow.com/q/4194207/157882
                response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // HTTP 1.1.
                response.setHeader("Pragma", "no-cache"); // HTTP 1.0.
                response.setDateHeader("Expires", 0); // Proxies.
            }

            chain.doFilter(request, response); // So, just continue request.
        }
        else if (ajaxRequest) {
            response.setContentType("text/xml");
            response.setCharacterEncoding("UTF-8");
            response.getWriter().printf(AJAX_REDIRECT_XML, loginURL); // So, return special XML response instructing JSF ajax to send a redirect.
        }
        else {
            response.sendRedirect(loginURL); // So, just perform standard synchronous redirect.
        }
    }

    // ...
}
@WebFilter(“/*”/)或@WebFilter(servletNames={“facesServlet”})
公共类AuthorizationFilter实现筛选器{
私有静态最终字符串AJAX\u REDIRECT\u XML=“”
+ "";
@凌驾
public void doFilter(ServletRequest-req、ServletResponse-res、FilterChain-chain)抛出ServletException、IOException{
HttpServletRequest请求=(HttpServletRequest)请求;
HttpServletResponse=(HttpServletResponse)res;
HttpSession session=request.getSession(false);
字符串loginURL=request.getContextPath()+“/login.xhtml”;
布尔loggedIn=(session!=null)&&(session.getAttribute(“用户”)!=null);
布尔loginRequest=request.getRequestURI().equals(loginURL);
布尔resourceRequest=request.getRequestURI().StartWith(request.getContextPath()+ResourceHandler.RESOURCE_标识符+“/”;
布尔值ajaxRequest=“partial/ajax”.equals(request.getHeader(“Faces request”);
if(loggedIn | | loginRequest | | resourceRequest)){
如果(!resourceRequest){//阻止浏览器缓存受限制的资源。另请参阅https://stackoverflow.com/q/4194207/157882
setHeader(“缓存控制”,“无缓存,无存储,必须重新验证”);//HTTP 1.1。
response.setHeader(“Pragma”,“无缓存”);//HTTP 1.0。
response.setDateHeader(“Expires”,0);//代理。
}
doFilter(请求,响应);//所以,只需继续请求即可。
}
else if(ajaxRequest){
setContentType(“text/xml”);
响应。setCharacterEncoding(“UTF-8”);
response.getWriter().printf(AJAX_REDIRECT_XML,loginURL);//因此,返回特殊的XML响应,指示JSF AJAX发送重定向。
}
否则{
sendRedirect(loginURL);//所以,只需执行标准的同步重定向。
}
}
// ...
}
另见:

谢谢。它不起作用:
FacesContext.getCurrentInstance()
返回
null
。怎么办?肯定不行。
FacesContext
仅在
FacesServlet
中可用,而不是一个自行开发的servlet。好的,我已经通过
过滤器实现了它。但是,我仍然不理解
elseif(“partial/ajax”…)
部分。您能更详细地解释一下或者提供一些链接吗?JSF ajax请求需要一个特殊的XML响应。JSF ajax引擎不会将HTTP 302响应解释为窗口重定向,而是对新XML响应的重定向。但是,如果该重定向实际返回一个HTML页面,它将失败,并且“没有反馈”。您需要返回一个特殊的XML响应,它告诉JSF ajax引擎在给定URL上发送重定向。您可以通过检查前面提到的响应头值来识别JSF ajax请求。在JSF端,这通常是由
ExternalContext#redirect()
处理的“隐藏”。但是在JSF上下文之外,您必须手动处理它句柄
css
文件?仅当通过
引用时,才使用。
@WebFilter("/*") // Or @WebFilter(servletNames={"facesServlet"})
public class AuthorizationFilter implements Filter {

    private static final String AJAX_REDIRECT_XML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
        + "<partial-response><redirect url=\"%s\"></redirect></partial-response>";

    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws ServletException, IOException {    
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;
        HttpSession session = request.getSession(false);
        String loginURL = request.getContextPath() + "/login.xhtml";

        boolean loggedIn = (session != null) && (session.getAttribute("user") != null);
        boolean loginRequest = request.getRequestURI().equals(loginURL);
        boolean resourceRequest = request.getRequestURI().startsWith(request.getContextPath() + ResourceHandler.RESOURCE_IDENTIFIER + "/");
        boolean ajaxRequest = "partial/ajax".equals(request.getHeader("Faces-Request"));

        if (loggedIn || loginRequest || resourceRequest)) {
            if (!resourceRequest) { // Prevent browser from caching restricted resources. See also https://stackoverflow.com/q/4194207/157882
                response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // HTTP 1.1.
                response.setHeader("Pragma", "no-cache"); // HTTP 1.0.
                response.setDateHeader("Expires", 0); // Proxies.
            }

            chain.doFilter(request, response); // So, just continue request.
        }
        else if (ajaxRequest) {
            response.setContentType("text/xml");
            response.setCharacterEncoding("UTF-8");
            response.getWriter().printf(AJAX_REDIRECT_XML, loginURL); // So, return special XML response instructing JSF ajax to send a redirect.
        }
        else {
            response.sendRedirect(loginURL); // So, just perform standard synchronous redirect.
        }
    }

    // ...
}