我有一个简单的登录过滤器实现。
public class LoginFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {}
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
HttpSession session = request.getSession(false);
if (session == null || session.getAttribute("loggedInUser") == null) {
response.sendRedirect(request.getContextPath() + "/login.jsp");
} else {
chain.doFilter(request, response);
}
}
@Override
public void destroy() {}
}
当我转到任何注册页面(即/account?id=1
( 没有会话属性loggedInUser
,过滤器工作正常。它将我重定向到登录页面。 但是如果我转到不存在的页面(即/blablabla.html
(,过滤器再次将我重定向到登录页面。有什么方法可以在输入不存在的页面时获得 404 错误并重定向到存在/login
?
错误在于要求:您过滤所有请求以拒绝来宾的访问,但如果请求是 404,则仍希望处理该请求。这在概念上是错误的:404仍然是一个应用响应,因为它为用户提供了系统内部的视图 - 因此用户必须在知道某些东西存在或不存在之前获得授权。
另一种选择是将应用拆分为公共区域和专用区域:
/public/style.css
/public/app.js
- 。
/private/customer/123
/private/oder/8932
- 。
并且只需过滤专用区域中的请求。
注意:如果您担心URL的美观性,请考虑/private/
前缀不是必需的。过滤器可以以可以省略任何前缀的方式附加
请记住,过滤器用于过滤任何传入请求或传出响应,因此实际上流程是这样的。
客户机----->请求---->过滤器----> servlet dispather ---->资源
所以现在,不幸的是,无论资源是否存在,请求都会被过滤器拦截,这发生在 servlet 解析器获取请求并意识到资源不存在之前。
我希望,这个解释可以回答你的问题。
谢谢。