过滤器(Filter)案例:检测用户是否登陆的过滤器
*****检测用户是否登陆的过滤器:不需要用户跳转到每个页面都需要登陆,访问一群页面时,只在某个页面上登陆一次,就可以访问其他页面;
1.自定义抽象的 HttpFilter类, 实现自 Filter 接口
package com.lanqiao.javaweb; import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; // 自定义的 HttpFilter, 实现自 Filter 接口 public abstract class HttpFilter implements Filter { // 用于保存 FilterConfig 对象. private FilterConfig filterConfig; // 不建议子类直接覆盖. 若直接覆盖, 将可能会导致 filterConfig 成员变量初始化失败 @Override public void init(FilterConfig filterConfig) throws ServletException { this.filterConfig = filterConfig; init(); } //供子类继承的初始化方法. 可以通过 getFilterConfig() 获取 FilterConfig 对象. protected void init() {} // 直接返回 init(ServletConfig) 的 FilterConfig 对象 public FilterConfig getFilterConfig() { return filterConfig; } /** * 原生的 doFilter 方法, 在方法内部把 ServletRequest 和 ServletResponse * 转为了 HttpServletRequest 和 HttpServletResponse, 并调用了 * doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) * * 若编写 Filter 的过滤方法不建议直接继承该方法. 而建议继承 * doFilter(HttpServletRequest request, HttpServletResponse response, * FilterChain filterChain) 方法 */ @Override public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) req; HttpServletResponse response = (HttpServletResponse) resp; doFilter(request, response, chain); } //抽象方法, 为 Http 请求定制. 必须实现的方法. public abstract void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws IOException, ServletException; //空的 destroy 方法。 @Override public void destroy() {} }
2.在src目录下建立类:LoginFilter ,其继承于父类: HttpFilter
package com.lanqiao.javaweb; import java.io.IOException; import java.util.Arrays; import java.util.List; import javax.servlet.FilterChain; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.lanqiao.javaweb.HttpFilter; public class LoginFilter extends HttpFilter{ //1. 从 web.xml 文件中获取 sessionKey, redirectUrl, uncheckedUrls private String sessionKey; private String redirectUrl; private String unchekcedUrls; @Override protected void init() { ServletContext servletContext = getFilterConfig().getServletContext(); sessionKey = servletContext.getInitParameter("userSessionKey"); redirectUrl = servletContext.getInitParameter("rediretPage"); //不需要检查的url是: login/a.jsp,/login/list.jsp,/login/login.jsp,/login/doLogin.jsp unchekcedUrls = servletContext.getInitParameter("uncheckedUrls"); } @Override public void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws IOException, ServletException { //1. 获取请求的 servletPath // /login/b.jsp String servletPath = request.getServletPath(); //2. 检查 1 获取的 servletPath 是否为不需要检查的 URL 中的一个, 若是, 则直接放行. 方法结束 List<String> urls = Arrays.asList(unchekcedUrls.split(",")); if(urls.contains(servletPath)){ filterChain.doFilter(request, response); return; } //3. 从 session 中获取 sessionKey 对应的值, 若值不存在, 则重定向到 redirectUrl Object user = request.getSession().getAttribute(sessionKey); if(user == null){ response.sendRedirect(request.getContextPath() + redirectUrl); return; } //4. 若存在, 则放行, 允许访问. filterChain.doFilter(request, response); } }
3.在lib下边的web.xml文件为:对LoginFilter类进行配置和映射;
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
<filter>
<filter-name>loginFilter</filter-name>
<filter-class>com.lanqiao.javaweb.LoginFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>loginFilter</filter-name>
//映射到WebContent目录下的login里
<url-pattern>/login/*</url-pattern>
</filter-mapping
<!-- 用户信息放入到 session 中的键的名字 --> <context-param> <param-name>userSessionKey</param-name> <param-value>USERSESSIONKEY</param-value> </context-param> <!-- 若未登录, 需重定向的页面 --> <context-param> <param-name>rediretPage</param-name> <param-value>/login/login.jsp</param-value> </context-param> <!-- 不需要拦截(或检查)的 URL 列表 --> <context-param> <param-name>uncheckedUrls</param-name> <param-value>/login/a.jsp,/login/list.jsp,/login/login.jsp,/login/doLogin.jsp,/login/b.jsp</param-value> </context-param>
</web-app>
4.WebContent目录下的login里面的jsp;页面之间进行跳转,只要一个页面输入用户名一次就可以实现跳转到其他页面不需要输入用户名了
a.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<h4>AAA PAGE</h4>
<a href="list.jsp">Return...</a>
</body>
</html>
b.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<h4>BBB PAGE</h4>
<a href="list.jsp">Return...</a>
</body>
</html>
c.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<h4>CCC PAGE</h4>
<a href="list.jsp">Return...</a>
</body>
</html>
d.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<h4>DDD PAGE</h4>
<a href="list.jsp">Return...</a>
</body>
</html>
doLogin.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> <% //1. 获取用户的登录信息 String username = request.getParameter("username"); //2. 若登录信息完整, 则把登录信息放到 HttpSession if(username != null && !username.trim().equals("")){ session.setAttribute(application.getInitParameter("userSessionKey"), username); //3. 重定向到 list.jsp response.sendRedirect("list.jsp"); }else{ response.sendRedirect("login.jsp"); } %> </body> </html>
list.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<a href="a.jsp">AAA</a>
<br><br>
<a href="b.jsp">BBB</a>
<br><br>
<a href="c.jsp">CCC</a>
<br><br>
<a href="d.jsp">DDD</a>
<br><br>
</body>
</html>
login.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> <form action="doLogin.jsp" method="post"> username: <input type="text" name="username"/> <input type="submit" value="Submit"/> </form> </body> </html>