您的具体问题很可能是由于JSF命令链接/按钮实际上发送了一个ajax请求,该请求又期望一个特殊的XML响应所致。如果您将重定向作为对ajax请求的响应发送,那么它将只会重新发送该URL的ajax请求。这反过来会因为重定向URL返回整个HTML页面而不是特殊的XML响应而失败且没有任何反馈。您应该实际返回一个特殊的XML响应,在其中已经指示JSF ajax引擎更改当前window.location
。
但您实际上存在更大的问题:使用了错误的工具来完成任务。您应该使用servlet filter完成任务,而不是自制的Servlet,当然也不是取代FacesServlet
的Servlet,后者负责所有JSF工作。
假设您正在执行以下请求/视图范围的JSF后备Bean登录(如果您使用容器管理的身份验证,请参见Performing user authentication in Java EE / JSF using j_security_check中第二个例子):
externalContext.getSessionMap().put("user", user);
那么,这个过滤器的启动示例应该如下:
@WebFilter("/*")
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) {
response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
response.setHeader("Pragma", "no-cache");
response.setDateHeader("Expires", 0);
}
chain.doFilter(request, response);
}
else if (ajaxRequest) {
response.setContentType("text/xml");
response.setCharacterEncoding("UTF-8");
response.getWriter().printf(AJAX_REDIRECT_XML, loginURL);
}
else {
response.sendRedirect(loginURL);
}
}
}
另请参阅:
Filter
实现了它。然而,我仍然不理解else if("partial/ajax"...)
这部分。你能否详细解释一下或提供一些链接? - DanijelExternalContext#redirect()
“在幕后”处理。但是,在JSF上下文之外,您必须手动处理它。 - BalusCrequest.getRequestURI().startsWith(request.getContextPath() + ResourceHandler.RESOURCE_IDENTIFIER);
是否可以处理css
文件?看起来好像不行。 - Danijel<h:outputStylesheet>
引用时。 - BalusC