从servlet过滤器重定向Web客户端(通过AJAX进行客户端 - 服务器连接)

时间:2011-07-15 09:23:30

标签: authentication servlets jquery servlet-filters

我正在使用JAASRealm身份验证(在tomcat 7中)。 这是servlet的过滤器:

private String loginPage = "welcome.jsp";

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

    if ((request instanceof HttpServletRequest) && (response instanceof HttpServletResponse)) {
        HttpServletRequest httpServletRequest = (HttpServletRequest) request;
        HttpServletResponse httpServletResponse = (HttpServletResponse) response;
        if (httpServletRequest.getUserPrincipal() == null) {
            // User is not logged in, redirect to login page.
            httpServletRequest.setAttribute("from", httpServletRequest.getRequestURI());
            httpServletResponse.sendRedirect(loginPage);
        }
        else {
            filterChain.doFilter(request, response);
        }
    }
}

我在web.xml中声明了它

<filter>
    <filter-name>login-filter</filter-name>
    <filter-class>LoginFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>login-filter</filter-name>
    <url-pattern>/sampleServlet</url-pattern>
</filter-mapping>

我的问题是当我没有通过身份验证并且我通过AJAX调用servlet时,这行过滤器不起作用

httpServletResponse.sendRedirect(loginPage);

所以,我没有收到任何数据,我没有被重定向到登录页面。在这种情况下我该怎么办?

3 个答案:

答案 0 :(得分:7)

我尝试使用一些优雅的解决方案,但都没有效果。我发现这一个吃了primefaces论坛,并且还在纯JSF应用程序上工作。

我使用了网络过滤器:

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
    HttpServletRequest httpRequest = (HttpServletRequest) request;
    HttpServletResponse httpResponse = (HttpServletResponse) response;

    if(!identity.isLoggedIn()){
        if (isAjax(httpRequest)) {
            httpResponse.getWriter().print(xmlPartialRedirectToPage(httpRequest, "/login.xhtml"));
            httpResponse.flushBuffer();                
        }else{
            httpResponse.sendRedirect(httpRequest.getContextPath() + "/login.xhtml");
        }
    }else{
        chain.doFilter(request, response);
    }
}

private String xmlPartialRedirectToPage(HttpServletRequest request, String page) {
    StringBuilder sb = new StringBuilder();
    sb.append("<?xml version='1.0' encoding='UTF-8'?>");
    sb.append("<partial-response><redirect url=\"").append(request.getContextPath()).append(request.getServletPath()).append(page).append("\"/></partial-response>");
    return sb.toString();
}

private boolean isAjax(HttpServletRequest request) {
    return "XMLHttpRequest".equals(request.getHeader("X-Requested-With"));
}

答案 1 :(得分:2)

以下是我在过滤AJAX请求时发送重定向的方式......

AJAX代码(jQuery)

$.ajax({
    type: 'post',
    url: '/signMeInServlet',
    data: {
        'name': name,
        'pass': passW,
        },
    dataType: 'json',
    success: processSignInReturnMethod,
    error: function (xhr, ajaxOptions, thrownError){
        if (thrownError.redirect.length) {
            window.location.replace(thrownError.redirect);
        } else {
            alert('There was an error processing your request, please try again');
        }
    }
});

相关过滤器代码

// Rest of your Filter processing and logic here, once you know you want
// to redirect, use the below code, which works for both AJAX and regualar
// requests

HttpServletRequest hreq = (HttpServletRequest) request;
String redirectUrl = "/redirected.jsp";

if (hreq.getHeader("x-requested-with") != null && 
        hreq.getHeader("x-requested-with").equalsIgnoreCase("XMLHttpRequest")) {

    // Set up your response here
    HttpServletResponse hres = (HttpServletResponse) response;
    hres.setContentType("text/json; charset=UTF-8");

    PrintWriter out = hres.getWriter();

    String json = "[{\"redirect\":\"" + redirectUrl + "\"}]";

    out.write(json);
    out.flush();
    out.close();

} else {

    ((HttpServletResponse)response).sendRedirect(redirectUrl);
}

答案 2 :(得分:0)

我解决了这个问题,但没有像我一样。 我在servler-filter中使用了这一行

httpServletResponse.setStatus(HttpServletResponse.SC_MOVED_PERMANENTLY);

并在客户端,使用ajax请求我捕获此状态,然后我执行重定向

var fAjaxRedirect = function(response, textStatus) {
    /* 301 is the code SC_MOVED_PERMANENTLY */
    if (response.status == 301) {
        location.reload(); //or location.href = 'xxxx.jsp';
 }};

    $.ajaxSetup({
        scriptCharset: "utf-8", 
        contentType: "application/x-www-form-urlencoded; charset=UTF-8"
    });
    $.ajax({
      type: "POST",
      url: "myServlet",
      complete: fAjaxRedirect,
      success: function(val) { 
          //something here
      }
    });

但是使用这种方式,是执行页面重定向的客户端,我想从服务器执行此操作,而不是依赖于客户端。