从servletfilter重定向Web客户端(通过AJAX进行客户端 – 服务器连接)
我正在使用JAASRealm身份validation(在tomcat 7中)。 这是servlet的filter:
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中声明了它
login-filter LoginFilter login-filter /sampleServlet
我的问题是当我没有经过身份validation并且我通过AJAX调用servlet时,这行filter不起作用
httpServletResponse.sendRedirect(loginPage);
所以,我没有收到任何数据,我没有被重定向到登录页面。 在这种情况下我该怎么办?
这是我在过滤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'); } } });
相关filter代码
// 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); }
我尝试使用一些优雅的解决方案,但没有一个工作。 我发现这一个吃了primefaces论坛,并且还在一个纯JSF应用程序上工作。
我使用了Webfilter:
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(""); sb.append(" "); return sb.toString(); } private boolean isAjax(HttpServletRequest request) { return "XMLHttpRequest".equals(request.getHeader("X-Requested-With")); }
我解决了这个问题,但没有像我想的那样。 我在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 } });
但是使用这种方式,是执行页面重定向的客户端,我想从服务器执行此操作,而不是依赖于客户端。