實現 javax.servlet.Filter 接口,在 doFilter 中判斷請求 URL 是否在白名單,否則檢查 Session 中是否存在用戶對象,未登錄則重定向到登錄頁。
public class LoginFilter implements Filter {
private String[] permitUrls;
private String gotoUrl;
public void init(FilterConfig config) throws ServletException {
String permitUrlsStr = config.getInitParameter("permitUrls");
this.gotoUrl = config.getInitParameter("gotoUrl");
if (permitUrlsStr != null && !permitUrlsStr.isEmpty()) {
this.permitUrls = permitUrlsStr.split(",");
}
}
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) resp;
if (!isPermitUrl(request)) {
if (needLogin(request)) {
System.out.println("---> 請登錄");
response.sendRedirect(request.getContextPath() + gotoUrl);
return;
}
}
System.out.println("---> 允許訪問");
chain.doFilter(request, response);
}
private boolean needLogin(HttpServletRequest request) {
User user = (User) request.getSession().getAttribute("user");
return user == null;
}
private boolean isPermitUrl(HttpServletRequest request) {
if (permitUrls == null) return false;
String currentUrl = getCurrentUrl(request);
for (String url : permitUrls) {
if (url.equals(currentUrl)) return true;
}
return false;
}
private String getCurrentUrl(HttpServletRequest request) {
String path = request.getContextPath();
String uri = request.getRequestURI();
String task = request.getParameter("task");
if (task != null) {
return uri.substring(path.length()) + "?task=" + task;
}
return uri.substring(path.length());
}
public void destroy() {
permitUrls = null;
gotoUrl = null;
}
}
<filter>
<filter-name>loginFilter</filter-name>
<filter-class>filter.LoginFilter</filter-class>
<init-param>
<param-name>permitUrls</param-name>
<param-value>/,/servlet/Loginservlet?task=login,/public.jsp,/login.jsp</param-value>
</init-param>
<init-param>
<param-name>gotoUrl</param-name>
<param-value>/login.jsp</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>loginFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
同理可實現基於角色的權限控制:將 needLogin() 替換為 hasPermission(),從 Session 獲取用戶角色,與資源權限映射表比對。