Filter(过滤器):可以对 请求(响应) 进行过滤 使用filter技术,对web服务器管理的web资源进行拦截 实现一些特殊功能的,例如对敏感消息,对url进行过滤等
Filter进行过滤的流程:
Filter的创建和使用:
1:实现一个 javax.servlet.Filter 接口
2: 添加注解,标明要进行过滤的请求路径 @WebFilter( urlPattterns = " 目标径 ")
3: 实现 Filter 接口中的三个抽象方法 init( 初始化 ) , doFilter( 执行过滤功能 ) , destory( 销毁 )
doFilter:(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain){
FilterChain : servlet 容器为开发人员提供的对象,它提供了对某一资源的已过滤请求调用链的视图 过滤器使用 FilterChain 调用链中的下一个过滤器,如果调用的过滤器是链中的最后一个过滤器 则调用链末尾的资源
***** 注意:
在Filter的 doFilter() 方法内如果没有执行, 那么资源是不会被访问到的 多个Filter对同一个资源进行了拦截, 访问下一下Filter,直到最后一个Filter执行时, 它后面没有了Filter,才会访问web资源
doFilter()的访问顺序:
多个过滤器都匹配目标,执行顺序和过滤器类名有关, 按类名的 字母顺序 排序
想要指定访问时,可以在 web.xml 里配置 <filter-mapping> 的先后顺序
}
public class Filter1 implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// 初始化
FilterConfig是Filter的配置对象
它的作用:
1.获取Filter的名称
2.获取初始化参数
3.获取ServletContext对象
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("进入了过滤器1");
HttpServletRequest request = (HttpServletRequest) servletRequest;
System.out.println("请求的当前路径:" + request.getRequestURI());
// 访问下一下Filter,直到最后一个Filter执行时,它后面没有了Filter,才会访问web资源
// 调用此方法,表示请求继续前进,不调用,请求就停止不前了
filterChain.doFilter(servletRequest, servletResponse);
}
@Override
public void destroy() {
// 销毁
}
}
Filter的生命周期:
1) 当服务器启动时,会创建 Filter 对象, 并调用 init() 方法进行初始化,仅且调用 一次
2) 当访问资源时,路径与Filter的拦截路径匹配,会执行Filter中的 doFilter() 方法,这个方法是真正拦截操作的方法 ,
3) 当服务器关闭时,会调用Filter的 destroy() 方法来进行销毁操作, 仅且调用 一次
匹配路径的三种写法:
1)精确匹配: 目标路径是过滤器路径就是什么
@WebFilter( urlPattrens= " /s1 " )
2) 前缀匹配: /filter/f1 , /filter/f2, filter/f3 匹配所有以 filter 开头的路径
@WebFilter( urlPattrens=" /filter/* ")
@WebFilter( urlPattrens=" /* ") 匹配此应用程序中的所有路径
3) 后缀匹配: 1.jsp , 2.jsp, 3.jsp 后缀匹配不能以 “ / ” 开头 *.xxx
@WebFilter( urlPattrens=" *.jsp ") 匹配以所有的 .jsp 结尾的路径
web.xml 文件的配置: xml 可扩展的标记语言,跟注解的方式作用一样
1) 配置 servlet
<!-- 配置一个servlet -->
<servlet>
<!-- servlet名字 -->
<servlet-name>servlet1</servlet-name>
<!-- servlet对应的java类 -->
<servlet-class>controller.Servlet1</servlet-class>
<!-- 在tomcat启动时就创建servlet的实例,而不是等到第一次请求时
其中数字表示优先级,数字小的优先级高
-->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>servlet1</servlet-name>
<!-- servlet的路径 -->
<url-pattern>/s1</url-pattern>
</servlet-mapping>
<!-- 等价于 @WebServlet(urlPatterns = "/s1", loadOnStartup = 1 ) -->
2) 配置 filter
<filter>
<!-- 过滤器名字 -->
<filter-name>f1</filter-name>
<!-- 过滤器对应的java类 -->
<filter-class>filter.Filter1</filter-class>
</filter>
过滤器的过滤顺序可以通过 filter-mapping标签的顺序调整,先进入filter-mapping在前面的过滤器
<filter-mapping>
<filter-name>f1</filter-name>
<!-- 过滤器要过滤的路径 -->
<url-pattern>/ *</url-pattern>
</filter-mapping>
<!-- 等价于 @WebFilter(urlPatterns="/*") -->
3) 配置 session 的生存时间
<session-config>
<!-- 配置session的超时时间, 单位是分钟 -->
<session-timeout>10</session-timeout>
</session-config>
MD5 加密算法:
Message Digest Algorithm MD5为计算机安全领域广泛使用的一种散列函数 用以提供消息的完整性保护,主流编程语言普遍已有MD5实现
1)mysql中的md5加密实现 md5(字段)
例如 update user set password=md5(password);
2)java 中实现 MD5 加密:
public static String md5(String str) {
byte[] secretBytes = null;
try {
// 调用 MessageDigest的getInstance(" md5 ")方法进行加密
secretBytes = MessageDigest.getInstance("md5").digest(str.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;
}
Listener(监听器):用于监听 web 的常见对象,监听它们的创建和销毁
1) 监听机制:
事件 就是一个事情
事件源 产生这个事情的源头
监听器 用于监听指定的事件的对象
注册监听 要想让监听器可以监听到事件产生,必须对其进行注册。
2) 常见的监听对象:
监听 域对象 的创建和销毁
1)监听ServletContext(应用程序)创建与销毁 ServletContextListener
2)监听HttpSession创建与销毁 HttpSessionListener
3)监听HttpServletRequest创建与销毁 ServletRequestListener
监听 域对象属性 的变化
1)监听ServletContext属性变化 ServletContextAttributeListener
2)监听HttpSession属性变化 HttpSessionAttributeListener
3)监听HttpServletRequest属性变化 ServletRequestAttributeListener
监听 session 绑定 javaBean
1) 它是用于监听javaBean对象是否绑定到了session域 HttpSessionBindingListener
2) 它是用于监听javaBean对象的激活与钝化 HttpSessionActivationListener
session的 激活 和 钝化
1) 钝化 : 当tomcat服务器停止时,会把session中所有变量存储到磁盘上 ,钝化过程调用是java序列化
2) 激活 : 当tomcat服务器重新启动时,把刚才存入磁盘的信息读取出来,恢复至session作用域
激活过程调用是java反序列化
*****注意:
向Session中存储的变量要实现序列化接口(Serializable) ,都是针对自定义的java类,如:Student类
Listener监听器的创建和使用:
- 创建一个类,实现指定的监听器接口
- 重写接口中的方法
- 添加注解: @WebListener (或者在 web.xml文件中对监听器进行注册)
例: 监听ServletContext(应用程序)创建与销毁
// 注解
@WebListener
// 实现 指定的监听器接口
public class ApplicationListener implements ServletContextListener {
// 重写接口中的方法
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
System.out.println("应用程序初始化事件发生...");
}
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
System.out.println("应用程序销毁事件发生...");
}
}
例: 监听HttpSession创建与销毁
// 注解
@WebListener
// 实现 session 的监听器接口
public class SessionListener implements HttpSessionListener {
// 避免多线程访问时出现并发问题,使用原子类
static AtomicInteger count = new AtomicInteger(0);
// 重写接口中的方法
@Override
// session 创建时触发
public void sessionCreated(HttpSessionEvent httpSessionEvent) {
count.getAndIncrement(); // 自增
// 存入应用程序作用域
httpSessionEvent.getSession().getServletContext().setAttribute("count", count);
}
@Override
// session 销毁时触发
public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
count.getAndDecrement(); // 自减
httpSessionEvent.getSession().getServletContext().setAttribute("count", count);
}
}
例: 监听HttpServletRequest属性变化
// 注解
@WebListener
// 实现接口
public class RequestListener implements ServletRequestAttributeListener {
@Override
public void attributeAdded(ServletRequestAttributeEvent servletRequestAttributeEvent) {
System.out.println("调用了request.setAttribute方法");
}
@Override // 调用了request.removeAttribute方法
public void attributeRemoved(ServletRequestAttributeEvent,servletRequestAttributeEvent) {
System.out.println("调用了request.removeAttribute方法");
}
@Override // 调用了request.setAttribute方法 ,用新值覆盖了旧值
public void attributeReplaced(ServletRequestAttributeEvent servletRequestAttributeEvent) {
System.out.println("调用了request.setAttribute方法 ,用新值覆盖了旧值");
}
}