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中处理真正的登录校验,首先在数据库中查找是否有该用户,如果有,则登录成功,否则提示错误信息;
整体项目框架:
项目源代码:
数据库表设计:
数据库中的登录数据
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"%>
登录界面
welcome.jsp欢迎界面
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
欢迎界面
欢迎您:<%=request.getAttribute("userName")%>
五、项目运行结果:
查看三大组件的加载顺序
建议打断点调试;
六、总结
通过前面的学习,了解了JavaWeb中的三大组件,Listener、Filter、Servlet;
Listener(监听器)主要用于监听ServletContext、HttpSession、HeepRequest对象的创建和销毁,以及相关属性;也可以用于提前加载某些配置文件;
Filter(过滤器)主要用于拦截请求,在请求交给Servlet处理前,进行预处理,进行预处理后,如果不符合要求,则不会交给真正的Servlet处理,从而达到过滤的效果;
Servlet则是真正的逻辑处理;
三大组件都需要实现响应的接口;都有自己的生命周期;都需要在web.xml文件中配置;
最后,我们通过一个下的案例,来使用这三大组件;
学无止境!共勉!