Listener:
### 监听器(了解) ### ---------- **监听器的概述** 1.概述:监听器是一个Java的类,监听另一个Java类状态的改变。 2.监听器的概念 * 事件源 -- 被监听的对象(电动车) * 监听器 -- 监听的对象(报警器) * 绑定监听器 -- 在被监听的对象上,注册一个监听器(在电动车上安装报警器) * 事件 -- 一旦事件源的状态发生了改变,创建一个事件的对象,传递给监听器的对象,监听器对象中的某一个方法就会执行了。 * 一旦电动车被踢了,产生一个事件的对象,传递给报警器,报警器就响了!! * 事件对象的作用:在监听器中可以通过事件对象获取到事件源的对象。 ---------- ### WEB的监听器 ### ---------- **WEB开发中的监听器** 1.WEB中学习监听器特点 * 事件源都已经规定好:监听3个域对象(ServletContext session request) * 监听器:需要咱们自己来编写(SUN公司已经提供对应的接口,实现这些接口,重写方法就可以了!!) * 绑定监听器:需要提供一段配置文件 * 事件:事件源的状态发生改变,产生事件对象,传递给监听器对象。 * 总结 * 接口和方法 * 绑定监听器(配置文件怎么编写) 2.编写监听器和完成监听器的配置 3.监听器的种类 * 第一类监听器:监听三个域对象的创建和销毁 * 这3个域对象什么时候创建和销毁? * 第二类监听器:监听三个域对象中的属性状态的改变 * 注意;上两类监听器需要完成配置文件 * 第三类监听器:只监听HttpSession域对象中JavaBean状态的改变的 * 只监听session对象 * 只监听session对象中的JavaBean * 最后一类监听器不需要配置文件的 ---------- **WEB监听器的开发步骤** 0.目的:监听ServletContext域对象的创建和销毁? 1.编写一个类,实现指定的监听器的接口,实现接口方法。 2.需要配置文件,在web.xml中进行编写。 <listener> <listener-class>包名+类名</listener-class> </listener> 3.总结 * 编写监听器的对象(实现特点的接口) * 提供配置文件(某个域对象创建了,哪个方法执行呢?) ---------- ### 第一类:监听三个域对象的创建和销毁 ### ---------- **ServletContextListener监听器** 1.第一个监听器是监听ServletContext对象的创建和销毁? * ServletContext什么时候创建?什么时候销毁? * 与天地同寿!! * 服务器一启动的时候,创建了ServletContext对象。停止服务器的时候,或者移除项目的时候,ServletContext销毁。 2.实现接口,ServletContextListener接口。 * void contextInitialized(ServletContextEvent sce) -- ServletContext对象创建的时候,该方法就会执行 * void contextDestroyed(ServletContextEvent sce) -- ServletContext销毁的时候就会执行 3.启动服务器的时候,ServletContext域对象被创建了,状态发生了改变,产生一个事件对象,传递给监听器的对象,监听器对象中某个方法就会执行了。 4.应用 * 目的:在启动服务器的时候,更容易去操作ServletContext域对象中。 * 来操作ServletContext域对象 * 以前在页面中,每次编写连接 * ${pageContext.request.contextPath} -- 获取项目的名称 ---------- **HttpSessionListener监听器** 1.方法: * void sessionCreated(HttpSessionEvent se) * void sessionDestroyed(HttpSessionEvent se) 2.session什么时候创建和销毁呢? * request.getSession()第一次执行的时候,创建session。 * 销毁 * session有默认销毁的时间(在web.xml中配置和方法) * 非正常原因关闭服务器(如果是正常关闭服务器,session没有销毁,序列化到磁盘上) * 调用void invalidate() 方法销毁session 3.访问JSP程序会创建session吗(会)?访问Servlet会吗(不一定)?访问HTML会吗(肯定不)? ---------- **ServletRequestListener监听器** 1.ServletRequest什么时候创建呢?什么销毁? * 只要有请求,创建一个request对象,请求结束,request对象就销毁了。 2.方法 * void requestInitialized(ServletRequestEvent sre) -- 请求一创建,方法执行 * void requestDestroyed(ServletRequestEvent sre) -- 请求结束了,方法执行 3.编写一个类,实现ServletRequestListener,重写2个方法。在web.xml中进行配置。 ---------- ### 第二类:监听三个域对象中的属性状态的改变 ### ---------- **ServletContextAttributeListener监听器** 1.监听ServletContext域对象中的属性的状态的改变 2.方法 * void attributeAdded(ServletContextAttributeEvent scab) -- 向ServletContext对象存入值,方法执行 * void attributeRemoved(ServletContextAttributeEvent scab) -- 从ServletContext对象移除值,方法执行 * void attributeReplaced(ServletContextAttributeEvent scab) -- 向ServletContext对象覆盖值,方法执行 ---------- **HttpSessionAttributeListener监听器** 1.监听HttpSession域对象中是属性的状态的改变 2.方法 * void attributeAdded(HttpSessionBindingEvent se) -- 向session中存入值,方法执行。 * void attributeRemoved(HttpSessionBindingEvent se) -- 向session中移除值,方法执行。 * void attributeReplaced(HttpSessionBindingEvent se) -- 向session中覆盖值,方法执行。 ---------- **ServletRequestAttributeListener监听器** 1..监听ServletRequest域对象中是属性的状态的改变 2.方法 * void attributeAdded(ServletRequestAttributeEvent srae) -- 向request中存入值,方法执行。 * void attributeRemoved(ServletRequestAttributeEvent srae) -- 向request中存入值,方法执行。 * void attributeReplaced(ServletRequestAttributeEvent srae) -- 向request中存入值,方法执行。 ---------- ### 第三类:监听HttpSession域对象中JavaBean状态的改变的 ### (XXXXXXXXXXXXXXXX未) ---------- **监听HttpSession中的JavaBean状态的改变** 1.监听器是监听HttpSession域对象的。 2.操作的都是JavaBean,以后如果使用第三类监听器,那么JavaBean需要实现对应的接口。 3.在web.xml不需要进行配置(编写JavaBean类的实现监听器的接口) 4.HttpSessionBindingListener * void valueBound(HttpSessionBindingEvent event) -- 把JavaBean保存到session中(绑定) * void valueUnbound(HttpSessionBindingEvent event) -- 把JavaBean从session中移除(解除绑定) 5.HttpSessionActivationListener(完成钝化(序列化到磁盘上)和活化(反序列化)) * void sessionDidActivate(HttpSessionEvent se) -- 活化 * void sessionWillPassivate(HttpSessionEvent se) -- 钝化 6.好处:对session机制的优化!! <Context> <Manager className="org.apache.catalina.session.PersistentManager" maxIdleSwap="1"> <Store className="org.apache.catalina.session.FileStore" directory="itcast"/> </Manager> </Context> 7.配置文件中的属性信息 * maxIdleSwap="1" -- 1分钟如果不操作,把session进行钝化 * directory="itcast" -- 保存到哪个目录下。
Filter:
1.解决中文 乱码问题
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> <h3>登录页面</h3> <form action="${ pageContext.request.contextPath }/login" method="post"> 用户名:<input type="text" name="username" /> <input type="submit" value="提交" /> </form> </body> </html>
LoginFilter:
public class LoginFilter implements Filter{ public void destroy() { } public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2) throws IOException, ServletException { arg0.setCharacterEncoding("utf-8"); arg2.doFilter(arg0, arg1); } public void init(FilterConfig arg0) throws ServletException { } }
LoginServlet:
public class LoginServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //接收请求的参数 String username=request.getParameter("username"); System.out.println(username); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
2.自动登录问题:
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> <h3>登录页面</h3> <font color="red">${msg }</font> <form action="${pageContext.request.contextPath }/user" method="post"> 用户名:<input type="text" name="username"/></br> 密 码:<input type="password" name="password"/></br> <input type="checkbox" name="auto_login" value="login_ok"/>自动登录</br> <input type="submit" value="登录"> </form> </body> </html>
UserServlet:
public class UserServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //接收用户名和密码 String username=request.getParameter("username"); String password=request.getParameter("password"); UserDao dao=new UserDao(); //登录的功能 User existUser=dao.login(username, password); //如果返回Null,说明输入错误,不匹配 if(existUser==null){ request.setAttribute("msg","用户名或者密码错误"); request.getRequestDispatcher("/demo2/login.jsp").forward(request, response); }else{ //判断,用户是否勾选了自动登录的功能。如果勾选了,会写cookie String auto_login=request.getParameter("auto_login"); if("login_ok".equals(auto_login)){ //说明勾选了 //cookie不能存中文 Cookie cookie=new Cookie("autoLogin",username+"-"+password); //设置有效时间 cookie.setMaxAge(60*60); //设置有效路径 cookie.setPath("/"); //回写cookie response.addCookie(cookie); } //登陆成功,把用户信息保存到session中 request.getSession().setAttribute("existUser", existUser); response.sendRedirect(request.getContextPath()+"/demo2/home.jsp"); } } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
UserDao:
public class UserDao { /** * 登录 * @param username * @param password * @return */ public User login(String username,String password){ QueryRunner runner=new QueryRunner(MyJdbcUtils.getDataSource()); String sql="select * from t_user where username= ? and password = ? "; try { return runner.query(sql,new BeanHandler<User>(User.class),username,password); } catch (SQLException e) { e.printStackTrace(); throw new RuntimeException(e); } } }
UserFilter:
public class UserFilter implements Filter{ /** * 每次拦截,都会执行 */ public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { /** * 1.先获取session,从session中获取existUser * 如果获取到existUser,说明现在就是登录状态 * 如果获取不到existUser,说明不是登录状态 * 2.获取指定cookie * 如果获取不到cookie,说明用户根本没保存过cookie,不想做自动登录的功能,放行 * 如果获取到cookie,说明用户保存过cookie,想做自动登录的功能,就帮他做这个功能 * 3.获取cookie中的用户名和密码。根据用户名和密码查询数据库 * 没查询到用户,说明用户名或者密码错误,不能做自动登录。放行 * 查询到用户,说明用户名和密码是正确的。把查询到的用户存入session中,session.setAttribute("existUser",user),放行 */ //1.先获取session HttpServletRequest req=(HttpServletRequest) request; HttpSession session = req.getSession(); //获取用户 User user=(User) session.getAttribute("existUser"); //如果用户不为空,登录状态 if(user!=null){ chain.doFilter(req, response); }else{ //用户为空,不是登录状态,获取cookie Cookie[] cookies=req.getCookies(); //根据指定的名称查找cookie Cookie cookie=CookieUtil.getCookieByName(cookies, "autoLogin"); //没找到,用户没选自动登录 if(cookie==null){ chain.doFilter(req, response); }else{ //找到cookie,用户点了自动登录 //获取cookie中保存的用户名和密码 String username=cookie.getValue().split("-")[0]; String password=cookie.getValue().split("-")[1]; //数据库中查询 UserDao dao=new UserDao(); //登录的功能 User existUser=dao.login(username, password); if(existUser==null){ //说明用户名或者密码错误 chain.doFilter(req, response); }else{ //找到了 session.setAttribute("existUser", existUser); chain.doFilter(req, response); } session.setAttribute("existUser", existUser); chain.doFilter(req, response); } } } public void destroy() { } public void init(FilterConfig arg0) throws ServletException { } }
CookieUtil:
public class CookieUtil { /** * 通过名称,从数组中查找cookie * @param cookies * @param cookieName * @return */ public static Cookie getCookieByName(Cookie[] cookies,String cookieName){ //判断,如果cookies数组Null if(cookies==null){ return null; }else{ for(Cookie cookie:cookies){ //根据传入的名称和cookie的名称对比 if(cookie.getName().equals(cookieName)){ return cookie; } } } return null; } }
home.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <!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> <h3>门户网站的LOGO</h3> <h4> <c:if test="${not empty existUser }"> <h4>欢迎您:${existUser.nickname }</h4> </c:if> <c:if test="${empty existUser }"> <h4> <a href="${pageContext.request.contextPath}/demo2/login.jsp">请登录</a> </h4> </c:if> </h4> <h4>出轨了</h4> <h4>进去了</h4> </body> </html>
原文地址:https://www.cnblogs.com/syj1993/p/8472357.html
时间: 2024-10-19 10:55:01