1、Listener监听器java
Javaweb开发中的监听器,是用于监听web常见对象 HttpServletRequest HttpSession ServletContext 监听它们的建立与销毁 属性变化 session绑定javaBean
一、监听机制mysql
事件 就是一个事情 事件源 产生这个事情的源头 监听器 用于监听指定的事件的对象 注册监听 要想让监听器能够监听到事件产生,必须对其进行注册。 ------------------------------
二、Javaweb开发中常见监听器
2.一、监听域对象的建立与销毁
监听ServletContext建立与销毁 ServletContextListener
监听HttpSession建立与销毁 HttpSessionListener
监听HttpServletRequest建立与销毁 ServletRequestListener
2.二、监听域对象的属性变化
监听ServletContext属性变化 ServletContextAttributeListener
监听HttpSession属性变化 HttpSessionAttributeListener
监听HttpServletRequest属性变化 ServletRequestAttributeListenerweb
2.三、监听session绑定javaBean
它是用于监听javaBean对象是否绑定到了session域 HttpSessionBindingListener
它是用于监听javaBean对象的活化与钝化 HttpSessionActivationListener
三、监听器的快速入门算法
关于建立一个监听器的步骤
1.建立一个类,实现指定的监听器接口
2.重写接口中的方法
3.在web.xml文件中对监听器进行注册。
3.一、关于域对象建立与销毁的演示
1.ServletContext对象的建立与销毁
这个对象是在服务器启动时建立的,在服务器关闭时销毁的。sql
2.HttpSession对象的建立与销毁
HttpSession session=request.getSession();
Session销毁
1.默认超时 30分钟
2.关闭服务器
3.invalidate()方法
4.setMaxInactiveInterval(int interval) 能够设置超时时间apache
问题:直接访问一个jsp页面时,是否会建立session?
会建立,由于咱们默认状况下是能够在jsp页面中直接使用session内置对象的。设计模式
3.HttpServletRequest建立与销毁
Request对象是发送请求服务器就会建立它,当响应产生时,request对象就会销毁。数组
3.二、演示了Request域对象中属性变化浏览器
在java的监听机制中,它的监听器中的方法都是有参数的,参数就是事件对象,而咱们能够经过事件对象直接获取事件源。
3.三、演示session绑定javaBean
1.javaBean对象自动感知被绑定到session中.
HttpSessionBindingListener 这个接口是由javaBean实现的,而且不须要在web.xml文件中注册.服务器
2.javabean对象能够活化或钝化到session中。
HttpSessionActivationListener若是javaBean实现了这个接口,那么当咱们正常关闭服务器时,session中的javaBean对象就会被钝化到咱们指定的文件中。
当下一次在启动服务器,由于咱们已经将对象写入到文件中,这时就会自动将javaBean对象活化到session中。
咱们还须要个context.xml文件来配置钝化时存储的文件
在meta-inf目录下建立一个context.xml文件
<Context>
<Manager className="org.apache.catalina.session.PersistentManager" maxIdleSwap="1">
<Store className="org.apache.catalina.session.FileStore" directory="it315"/>
</Manager> </Context>
案例-定时销毁session
1.怎样能够将每个建立的session全都保存起来?
咱们能够作一个HttpSessionListener,当session对象建立时,就将这个session对象装入到一个集合中.
将集合List<HttpSession>保存到ServletContext域中。
2.怎样能够判断session过时了?
在HttpSession中有一个方法public long getLastAccessedTime()
它能够获得session对象最后使用的时间。
可使用invalidate方法销毁。
咱们上面的操做须要使用任务调度功能. 在java中有一个Timer定时器类
关于三个域对象获取
若是在Servlet中要获取 request,在方法上就有,request.getSession() getServletContext();
若是咱们有request对象了, request.getSession() request.getSession().getServletCotnext();
程序在使用时,须要考虑并发问题,由于咱们在web中,它必定是一个多线程的,那么咱们的程序对集合进行了添加,还有移除操做。
2、Filter过滤器(重要)
Javaweb中的过滤器能够拦截全部访问web资源的请求或响应操做。
一、Filter快速入门
1.一、步骤:
1.建立一个类实现Filter接口
2.重写接口中方法 doFilter方法是真正过滤的。
3.在web.xml文件中配置
注意:在Filter的doFilter方法内若是没有执行chain.doFilter(request,response)
那么资源是不会被访问到的。
1.二、FilterChain
FilterChain 是 servlet 容器为开发人员提供的对象,它提供了对某一资源的已过滤请求调用链的视图。过滤器使用 FilterChain 调用链中的下一个过滤器,若是调用的过滤器是链中的最后一个过滤器,则调用链末尾的资源。
问题:怎样能够造成一个Filter链?
只要多个Filter对同一个资源进行拦截就能够造成Filter链
问题:怎样肯定Filter的执行顺序?
由<filter-mapping>来肯定 1.三、Filter生命周期
Servlet生命周期:
实例化 --》 初始化 --》 服务 --》 销毁
当服务器启动,会建立Filter对象,并调用init方法,只调用一次.
当访问资源时,路径与Filter的拦截路径匹配,会执行Filter中的doFilter方法,这个方法是真正拦截操做的方法.
当服务器关闭时,会调用Filter的destroy方法来进行销毁操做.
1.四、FilterConfig 在Filter的init方法上有一个参数,类型就是FilterConfig. FilterConfig它是Filter的配置对象,它能够完成下列功能
1.获取Filtr名称
2.获取Filter初始化参数
3.获取ServletContext对象。
问题:怎样在Filter中获取一个FIlterConfig对象?
1.五、Filter配置
基本配置 <filter> <filter-name>filter名称</filter-name> <filter-class>Filter类的包名.类名</filter-class> </filter> <filter-mapping> <filter-name>filter名称</filter-name> <url-pattern>路径</url-pattern> </filter-mapping> 关于其它配置 1.<url-pattern> 彻底匹配 以”/demo1”开始,不包含通配符* 目录匹配 以”/”开始 以*结束 扩展名匹配 *.xxx 不能写成/*.xxx 2.<servlet-name> 它是对指定的servlet名称的servlet进行拦截的。 3.<dispatcher> 能够取的值有 REQUEST FORWARD ERROR INCLUDE
它的做用是:当以什么方式去访问web资源时,进行拦截操做.
1.REQUEST 当是从浏览器直接访问资源,或是重定向到某个资源时进行拦截方式配置的 它也是默认值
2.FORWARD 它描述的是请求转发的拦截方式配置
3.ERROR 若是目标资源是经过声明式异常处理机制调用时,那么该过滤器将被调用。除此以外,过滤器不会被调用。
4.INCLUDE 若是目标资源是经过RequestDispatcher的include()方法访问时,那么该过滤器将被调用。除此以外,该过滤器不会被调用
3、自动登录
一、建立库与表 CREATE DATABASE day17
USE day17
CREATE TABLE USER(
id INT PRIMARY KEY AUTO_INCREMENT, username VARCHAR(100), PASSWORD VARCHAR(100)
)
INSERT INTO USER VALUES(NULL,"tom","123");
二、自动登录功能实现:
1.当用户登录成功后,判断是否勾选了自动登录,若是勾选了,就将用户名与密码持久化存储到cookie中
2.作一个Filter,对须要自动登录的资源进行拦截
问题
1.若是用户想要登录操做,还须要自动登录吗?
2.若是用户已经登录了,还须要自动登录吗?
4、MD5加密
在mysql中能够对数据进行md5加密 Md5(字段) UPDATE USER SET PASSWORD=MD5(PASSWORD); 在java中也提供了md5加密 /**
*/
public static String md5(String plainText) {
byte[] secretBytes = null; try { secretBytes = MessageDigest.getInstance("md5").digest( plainText.getBytes()); } catch (NoSuchAlgorithmException e) { throw new RuntimeException("没有md5这个算法!"); } String md5code = new BigInteger(1, secretBytes).toString(16); for (int i = 0; i < 32 - md5code.length(); i++) { md5code = "0" + md5code; } return md5code;
5、全局的编码过滤器
分析: 咱们以前作的操做,只能对post请求是ok
怎样能够作成一个通用的,能够处理post,get全部的请求的?
在java中怎样能够对一个方法进行功能加强?
1.继承
2.装饰设计模式
1.建立一个类让它与被装饰类实现同一个接口或继承同一个父类
2.在装饰类中持有一个被装饰类的引用
3.重写要加强的方法
问题:咱们获取请求参数有如下方法
1.getParameter
2.getPrameterValues
3.getParameterMap
这三个方法均可以获取请求参数。
分析后,咱们知道getParameter与getParameterValue方法能够依赖于getParamterMap方法来实现。
// 这个就是咱们对request进行装饰的类
class MyRequest extends HttpServletRequestWrapper {
private HttpServletRequest request;// 是用于接收外部传递的原始的request
public MyRequest(HttpServletRequest request) {
super(request); // 是由于父类没有无参数构造 this.request = request;
}
// @Override
// public String getParameter(String name) {
// // 1.获得原来的getParameter方法的值
// String value = request.getParameter(name); // 乱码
//
// try {
// return new String(value.getBytes("iso8859-1"), "utf-8");
// } catch (UnsupportedEncodingException e) {
// e.printStackTrace();
// }
// return null;
// }
@Override
public String getParameter(String name) {
if (name != null) { String[] st = (String[]) getParameterMap().get(name); if (st != null && st.length > 0) { return st[0]; } } return null;
}
@Override
public String[] getParameterValues(String name) {
if (name != null) { return (String[]) getParameterMap().get(name); } return null;
}
private boolean flag = true;
@Override
public Map getParameterMap() {
// 1.获得原始的map集合 Map<String, String[]> map = request.getParameterMap();// 乱码 if (flag) { // 2.将map集合中的String[]获得,解决每个元素的乱码问题. for (String key : map.keySet()) { String[] st = map.get(key); // 获得每个数组 for (int i = 0; i < st.length; i++) { try { st[i] = new String(st[i].getBytes("iso8859-1"), "utf-8"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } } } flag = false; } return map;
}
}