Web基础之与Listener的第一次接触

Web基础之与Listener的第一次接触
一、JavaWeb的三大组件简介: 

JavaWeb的三大组件是:Servlet、Filter、Listener;
Servlet:主要用于处理请求;
Filter:主要用于在正式处理请求之前进行相关的预处理;
Listener:用于监听web应用程序中的ServletContext, HttpSession和 ServletRequest等域对象的创建与销毁事件,以及监听这些域对象中的属性发生修改的事件。

Web组件的特点:
1.都需要创建一个类并实现某个接口
2.都要在web.xml文件中进行配置
3.都有自己的生命周期方法


二、Listener的分类以及详解:
1.生命周期监听器(3个)
2.属性变化监听器(3个)
3.session中指定类属性变化监听器(2)
 
生命周期监听器:
        > 监听ServletContext、HttpSession、ServletRequest三个对象创建和销毁
 
        > javax.servlet.ServletContextListener --> 监听ServletContext的生命周期变化
            - 方法:
                void contextDestroyed(ServletContextEvent sce)
                    - 在ServletContext对象销毁前调用
 
                void contextInitialized(ServletContextEvent sce)
                    - 在ServletContext对象创建后调用
 
            - 参数:
                ServletContextEvent
                    - 可以用来获取ServletContext对象
 
        > javax.servlet.http.HttpSessionListener --> 监听HttpSession对象的生命周期变化
            - 方法:
                void sessionCreated(HttpSessionEvent se)
                    - 在HttpSession对象创建以后调用
 
                void sessionDestroyed(HttpSessionEvent se)
                    - 在HttpSession对象销毁前调用
 
            - 参数:
                HttpSessionEvent
                    - 可以用来获取HttpSession对象
 
        > javax.servlet.ServletRequestListener --> 监听request对象的生命周期的变化
            - 方法:
                void requestDestroyed(ServletRequestEvent sre)
                    - 在request对象销毁前调用
 
                void requestInitialized(ServletRequestEvent sre)
                    - 在request对象创建后调用
 
            - 参数:
                ServletRequestEvent
                    - 可以用来获取ServletContext对象
                    - 可以用来获取ServletRequest对象
 
属性监听器
        > ServletContext属性变化监听器
            javax.servlet.ServletContextAttributeListener
                - 方法:
                    void attributeAdded(ServletContextAttributeEvent scab)
                        - 当我们向application域中添加属性时调用
 
                    void attributeRemoved(ServletContextAttributeEvent scab)
                        - 当我们从application域中移除属性时调用
 
                    void attributeReplaced(ServletContextAttributeEvent scab)
                        - 当application域中一个属性被替换时调用
 
        > HttpSession的属性变化监听器
            javax.servlet.http.HttpSessionAttributeListener
                - 方法:
                    void attributeAdded(HttpSessionBindingEvent se)
                        - 当我们向session域中添加属性时调用
 
                    void attributeRemoved(HttpSessionBindingEvent se)
                        - 当我们从session中移除属性时调用
 
                    void attributeReplaced(HttpSessionBindingEvent se)
                        - 当session域中的一个属性被替换时调用
 
                参数:
                    HttpSessionBindingEvent:
                        作用:
                            1.获取发生变化的属性的名字 getName()
                            2.获取发生变化的属性的值 getValue() 注意属性替换时,获取到是旧的属性值
                            3.获取HttpSession对象 getSession() 可以通过session对象获取到新的属性值
 
        > ServletRequest属性变化监听器
            -javax.servlet.ServletRequestAttributeListener
                - 方法:
                    void attributeAdded(ServletRequestAttributeEvent srae)
                        - 当我们向request域中添加属性时调用
 
                    void attributeRemoved(ServletRequestAttributeEvent srae)
                        - 当我们从request域中移除属性时调用
 
                    void attributeReplaced(ServletRequestAttributeEvent srae)
                        - 当request域中的一个属性被替换时调用
 
 
session中指定类属性变化监听器
        - 这两个监听器的接口,由一个JavaBean去实现,而且不用编写配置文件
 
      >HttpSessionBindingListener
        void valueBound(HttpSessionBindingEvent event)
            - 当该类实例设置进session域中时调用
 
        void valueUnbound(HttpSessionBindingEvent event)
            - 当该类的实例从session域中移除时调用
 
        HttpSessionBindingEvent:
            作用:
                1.获取发生变化的属性的名字 getName()
                2.获取发生变化的属性的值 getValue()
                3.获取HttpSession对象 getSession()
 
      >HttpSessionActivationListener
        > 监听某个类的实例和session一起活化和钝化的监听器
        - 方法:
            void sessionDidActivate(HttpSessionEvent se)
                - 当该类实例和session一起活化时调用
 
            void sessionWillPassivate(HttpSessionEvent se)
                - 当该类实例和session一起钝化时调用
 
        - 参数:
            HttpSessionEvent
                - 可以用来获取HttpSession对象


三、JavaWeb三大组件的初始化顺序:

Listener----->Filter------>Servlet

四、三大组件的综合应用实例:
我们将通过一个简单的登录例子来演示JavaWeb三大组件的使用;
我们将在Lisetener中加载数据库配置文件;
我们将在Filter中统一设置请求编码以及简单的登录校验;
我们将在Servlet中处理真正的登录校验,首先在数据库中查找是否有该用户,如果有,则登录成功,否则提示错误信息;

整体项目框架:
Web基础之与Listener的第一次接触_第1张图片

项目源代码:
数据库表设计:
Web基础之与Listener的第一次接触_第2张图片
数据库中的登录数据
Web基础之与Listener的第一次接触_第3张图片


Bean类,和设计的数据库表相对应
package com.usc.bean;


/**
 * 简单的JavaBean类
 * @author ZHOU
 *
 */
public class UserBean {
	
	private String userName;
	
	private String passWord;

	public String getUserName() {
		return userName;
	}

	public void setUserName(String userName) {
		this.userName = userName;
	}

	public String getPassWord() {
		return passWord;
	}

	public void setPassWord(String passWord) {
		this.passWord = passWord;
	}
}


数据库操作包下的类(思考一下为什么要用静态属性)
package com.usc.dao;

public class DAOContext {
	
	private static String driver;
	
	private static String  url;
	
	private static String  user;
	
	private static String  pwd;

	public static String getDriver() {
		return driver;
	}

	public static void setDriver(String driver) {
		DAOContext.driver = driver;
	}

	public static String getUrl() {
		return url;
	}

	public static void setUrl(String url) {
		DAOContext.url = url;
	}

	public static String getUser() {
		return user;
	}

	public static void setUser(String user) {
		DAOContext.user = user;
	}

	public static String getPwd() {
		return pwd;
	}

	public static void setPwd(String pwd) {
		DAOContext.pwd = pwd;
	}
}

package com.usc.dao;

import java.sql.Connection;
import java.sql.DriverManager;


public class DAOUtil {
	
	public static Connection getConnection(){
		Connection conn=null;
		//加载驱动
		try {
			Class.forName(DAOContext.getDriver());
			conn=DriverManager.getConnection(DAOContext.getUrl(),DAOContext.getUser(),DAOContext.getPwd());
		} catch (Exception e) {
			e.printStackTrace();
		}
		return conn;
	}
}



package com.usc.dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import com.usc.bean.UserBean;

/*
 * 用户数据库操作类
 */
public class userDao {
	
//	新增用户操作
	public void addNewUser(UserBean bean) {
		//获取连接
		Connection conn=DAOUtil.getConnection();
		if(conn!=null){
			try {
				PreparedStatement pstmt=conn.prepareStatement("insert into userInfo (userName,passWord) values (?,?)");
				pstmt.setString(1, bean.getUserName());
				pstmt.setString(2, bean.getPassWord());
				int row=pstmt.executeUpdate();
				if(row!=1){
					throw new RuntimeException("新增用户失败!");
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
	
//	查询用户
	public UserBean queryUserByUserName(String userName) {
		//获取连接
		Connection conn=DAOUtil.getConnection();
		UserBean bean =null;
		if(conn!=null){
			try {
				PreparedStatement pstmt=conn.prepareStatement("select userName,passWord from userInfo where userName=?");
				pstmt.setString(1, userName);
				ResultSet rs =pstmt.executeQuery();
				if(rs.next()){
					String name=rs.getString(1);
					String pwd =rs.getString(2);
					bean = new UserBean();
					bean.setUserName(name);
					bean.setPassWord(pwd);
					
				}
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		return bean;
	}
}


测试数据库加载是否成功,真正运行时不考虑(这是可以当做一个Java项目运行)
package com.usc.dao;

public class Test {
	
//	用来测试是否加载成功,正式程序可以不用管
	
	public static void main(String[] args) {
		String Driver=DAOContext.getDriver();
		String url=DAOContext.getUrl();
		String user=DAOContext.getUser();
		String pwd=DAOContext.getPwd();
		
		System.out.println(Driver+":"+url+user+pwd);
	}

}


Filter类
package com.usc.filter;

import java.io.IOException;
import java.net.URLEncoder;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

public class LoginCheckFilter implements Filter{
	
	public LoginCheckFilter() {
		
		System.out.println("LoginCheckFilter  Constructor......");
	}

	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
		System.out.println("LoginCheckFilter  init......");
	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain chain) throws IOException, ServletException {
		System.out.println("LoginCheckFilter.......");
		//设置请求编码
		request.setCharacterEncoding("UTF-8");
		String userName=request.getParameter("userName");
		String passWord =request.getParameter("passWord");
//		登录校验
		if(userName==null || "".equals(userName.trim()) || 
				passWord==null || "".equals(passWord.trim())){
			request.setAttribute("ErrorMsg", "用户名或密码填写不完整");
			request.getRequestDispatcher("/login.jsp").forward(request, response);
			return;
		}else{
			request.setAttribute("user", userName);
			request.setAttribute("pwd", passWord);
			chain.doFilter(request, response);	
		}
		System.out.println("LoginCheckFilter end.......");
	}
	@Override
	public void destroy() {
		
	}
}

Listener类
package com.usc.listener;

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

import com.usc.dao.DAOContext;


/**
 * 
 * @author Zhou
 *当ServletContext对象创建后,通过Properties对象加载数据库配置文件
 */
public class ListenerTest implements ServletContextListener {

    public ListenerTest() {
    	System.out.println("ListenerTest Construtor.......");
    }
   

    public void contextInitialized(ServletContextEvent sce) {
    	System.out.println("ListenerTest contextInitialized.......");
    	//加载配置文件
    	System.out.println("Prepare Config.......");
    	
    	Properties pro = new Properties();
    	InputStream in =Thread.currentThread().getContextClassLoader().getResourceAsStream("db-cofig.properties");
    	try {
			pro.load(in);
			//将加载好的数据进行保存(注意DAOContext中所有的属性都是静态属性)
			DAOContext.setDriver(pro.getProperty("db.driver"));
			DAOContext.setUrl(pro.getProperty("db.url"));
			DAOContext.setUser(pro.getProperty("db.user"));
			DAOContext.setPwd(pro.getProperty("db.pwd"));
			System.out.println("Prepare Config finish.......");
		} catch (IOException e) {
			e.printStackTrace();
		}
    }
    
    public void contextDestroyed(ServletContextEvent sce) {
    	System.out.println("contextDestroyed.......");
    }
}


Servlet类
package com.usc.servlet;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.usc.bean.UserBean;
import com.usc.dao.DAOContext;
import com.usc.dao.userDao;

public class LoginServlet extends HttpServlet{
	
	private static final long serialVersionUID = 1L;
	
	public LoginServlet() {
		System.out.println("LoginServlet Constructor......");
	}
	
	@Override
	public void init() throws ServletException {
		System.out.println("LoginServlet init......");
	}

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		this.doPost(req, resp);
	}
	
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		
		//获取参数
		String userName =(String) req.getAttribute("user");
		String passWord =(String) req.getAttribute("pwd");
		
	
		userDao dao = new userDao();
		UserBean bean =dao.queryUserByUserName(userName);
		
//		String name=bean.getUserName();
//		String p=bean.getPassWord();
		if(userName.equals(bean.getUserName()) && passWord.equals(bean.getPassWord())){
			req.setAttribute("userName", userName);
			req.getRequestDispatcher("/welcome.jsp").forward(req, resp);
		}else{
			resp.sendRedirect("/Listener/error.jsp");
		}
	}
}


数据库配置文件(resoures包下的文件)
db.driver=com.mysql.jdbc.Driver
db.url=jdbc:mysql://localhost:3306/shoppingsys
db.user=root
db.pwd=zhou


web.xml配置文件


  Listener
  
    index.html
    index.htm
    index.jsp
    default.html
    default.htm
    default.jsp
  
  
  
    com.usc.listener.ListenerTest
  
  
  
  loginCheck
  com.usc.filter.LoginCheckFilter
  
  
  loginCheck
  /login
  
  
  
  login
  com.usc.servlet.LoginServlet
  1
  
  
  login
  /login
  
  
  



error.jsp错误处理页面
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>




错误处理界面


登录出现错误!


login.jsp登录界面
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>




登录界面


用户名:
密  码:
<% String info =(String)request.getAttribute("ErrorMsg") ; if( info!=null){ %> <%=info%> <% } %>

welcome.jsp欢迎界面
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>




欢迎界面


欢迎您:<%=request.getAttribute("userName")%>


五、项目运行结果:

查看三大组件的加载顺序
Web基础之与Listener的第一次接触_第4张图片



Web基础之与Listener的第一次接触_第5张图片
Web基础之与Listener的第一次接触_第6张图片

Web基础之与Listener的第一次接触_第7张图片



Web基础之与Listener的第一次接触_第8张图片

建议打断点调试;


六、总结
通过前面的学习,了解了JavaWeb中的三大组件,Listener、Filter、Servlet;
Listener(监听器)主要用于监听ServletContext、HttpSession、HeepRequest对象的创建和销毁,以及相关属性;也可以用于提前加载某些配置文件;
Filter(过滤器)主要用于拦截请求,在请求交给Servlet处理前,进行预处理,进行预处理后,如果不符合要求,则不会交给真正的Servlet处理,从而达到过滤的效果;
Servlet则是真正的逻辑处理;
三大组件都需要实现响应的接口;都有自己的生命周期;都需要在web.xml文件中配置;
最后,我们通过一个下的案例,来使用这三大组件;
学无止境!共勉!

你可能感兴趣的:(web基础)