Filter过滤器
web中的过滤器:
当访问服务器的资源时,过滤器可以将请求拦截下来,完成一些特殊的功能
过滤器的作用:
一般用于完成通用的操作
如:登录验证、统一编码处理、敏感字符过滤...
快速入门
步骤:
1. 定义一个类,实现接口Filter
2. 复写方法
3. 配置拦截路径
web. xml
注解
@WebFilter ( "/*" )
public class MyFilter implements Filter {
@Override
public void init ( FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter ( ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException , ServletException {
filterChain. doFilter ( servletRequest, servletResponse) ;
}
@Override
public void destroy ( ) {
}
}
过滤器细节
1. web.xml配置
<filter>
<!-- 配置过滤器名称 -->
<filter-name>myFilter</filter-name>
<!-- 配置过滤器的全路径 -->
<filter-class>com.edu.filter.MyFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>myFilter</filter-name>
<!-- 拦截路径 -->
<url-pattern>/*</url-pattern>
</filter-mapping>
2. 过滤器执行流程
a. 执行过滤器
b. 执行放行后的资源
c. 回来执行过滤器放行代码下边的代码
3. 过滤器生命周期方法
a. init
在服务器启动后,会创建Filter对象,然后调用init方法。
只执行一次。用于加载资源
b. doFilter
每一次请求被拦截资源时,会执行。
执行多次
c. destroy
在服务器关闭后,Filter对象被销毁。
如果服务器是正常关闭,则会执行destroy方法。
只执行一次。用于释放资源
4. 过滤器配置详解
拦截路径配置:
a. 具体资源路径:/index.jsp
只有访问index.jsp资源时,过滤器才会被执行
b. 拦截目录:/user/*
访问/user下的所有资源时,过滤器都会被执行
c. 后缀名拦截:*.jsp
访问所有后缀名为jsp资源时,过滤器都会被执行
d. 拦截所有资源:/*
访问所有资源时,过滤器都会被执行
拦截方式配置:
资源被访问的方式
注解配置:
设置dispatcherTypes属性
a. REQUEST:默认值。浏览器直接请求资源
b. FORWARD:转发访问资源
c. INCLUDE:包含访问资源
d. ERROR:错误跳转资源
e. ASYNC:异步访问资源
web.xml配置
设置<dispatcher></dispatcher>标签即可
5. 过滤器链(配置多个过滤器)
执行顺序:如果有两个过滤器:过滤器1和过滤器2
a. 过滤器1
b. 过滤器2
c. 资源执行
d. 过滤器2
e. 过滤器1
过滤器先后顺序问题:
a. 注解配置:按照类名的字符串比较规则比较,值小的先执行
如:AFilter和BFilter,AFilter就先执行了
b. web.xml配置:
<filter-mapping>谁定义在上边,谁先执行
解决全站乱码
@WebFilter ( value = "/*" , filterName = "CharCodeFilter" )
public class CharCodeFilter implements Filter {
public void destroy ( ) {
}
public void doFilter ( ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException , IOException {
HttpServletRequest request = ( HttpServletRequest ) req;
HttpServletResponse response = ( HttpServletResponse ) resp;
String method = request. getMethod ( ) ;
if ( "POST" . equalsIgnoreCase ( method) ) {
request. setCharacterEncoding ( "utf-8" ) ;
}
response. setContentType ( "text/html;charset=utf-8" ) ;
chain. doFilter ( req, resp) ;
}
public void init ( FilterConfig config) throws ServletException {
}
}
Listener监听器
事件监听机制
事件:
一件事情
事件源:
事件发生的地方
监听器:
一个对象
注册监听:
将事件、事件源、监听器绑定在一起。
当事件源上发生某个事件后,执行监听器代码
快速入门
步骤:
1. 定义一个类,实现ServletContextListener 接口
2. 复写方法
3. 配置拦截路径
a. web. xml配置
< listener>
< listener- class > < / listener- class >
< / listener>
< ! -- 指定初始化参数 -- >
< context- param>
< param- name> < / param- name>
< param- value> < / param- value>
< / context- param>
b. 注解
@WebListener
public class MyListener implements ServletContextListener {
@Override
public void contextInitialized ( ServletContextEvent servletContextEvent) {
}
@Override
public void contextDestroyed ( ServletContextEvent servletContextEvent) {
}
}
监听器细节
作用:
监听web中中的域对象 ServletContext ServletRequest HttpSession
监听内容:
监听三个对象的创建和销毁
监听三个对象属性的变化
监听session中javabean的状态
注意:listener全部是接口
监听三个对象的创建和销毁
ServletContextListener
ServletRequestListener
HttpSessionListener
监听三个对象属性的变化
ServletContextAttributeListener
ServletRequestAttributeListener
HttpSessionAttributeListener
监听session中javabean的状态
HttpSessionActivationListener(钝化和活化)
HttpSessionBindingListener(绑定和解绑)
监听三个对象的创建和销毁
ServletContextListener
创建:服务器启动的时候,会为每一个项目都创建一个servletContext
销毁:服务器关闭的时候,或者项目被移除的时候
以后用来加载配置文件
ServletRequestListener
创建:请求来的时候
销毁:响应生成的时候
HttpSessionListener
创建:
java中第一次调用request.getSession的时候
jsp访问的时候创建
销毁:
session超时
手动销毁session
服务器非正常关闭
注解Annotation
注释:解释说明范围,给人看的,编译器在编译时,就会忽略
注解:也叫元数据,是给程序看的,一种代码级别的说明
JDK1.5版本以后引入的特性,与类、接口、枚举是在同一个层次。
可以声明在包、类、字段、方法、局部变量、方法参数等的前面,用来对这些元素进行说明,注释
注解的作用:
1.检测作用
2.为了替代配置文件,来简化配置
3.定义注解(元注解:注解上的注解)
4.分析代码(用到反射)
JDK提供的一些常用的注解
@Override 检测该方法,是不是重写父类
@FunctionInterface 检测该接口,是不是函数式接口
@Deprecated 标识该类或该方法过时
@SuppressWarnings(value="all") 压制黄色警告
注解的使用:
@注解名(属性名=属性值)
注解的本质:
其实是个接口
既然注解本质上是个接口,那么接口中可以定义抽象方法,
其实定义在注解中的抽象方法,我们叫做注解的属性
一旦注解中,定义了属性,那么在使用注解时,必须给注解的所有属性赋值,除非属性有默认值
注解中有一个特殊的属性名:叫value
如果注解中只有一个value属性,那么我们在使用这个属性时,value属性名可以省略不写
注解的数据类型(其实就是抽象方法的返回值类型)
基本数据类型
String
Class
Annotation
Enum 枚举
以及以上类型对应的一维数组
注解的属性是个数组时,你在给注解的属性赋值时,要带上大括号,如果数组中只赋值一个元素,可以省略大括号
自定义注解
格式:
@interface 注解名{}
注解属性:
注解本质就是一个接口, 可以用javap这个命令反编译一下,注解的字节码文件
例如: javap myan.class
那接口中可以有常量和抽象方法
抽象方法在注解中就称之为注解属性
public @interface MyAnnotation{
//注解本质上是一个接口
//那接口中的抽象方法,其实就是注解中的属性
//注解的属性,前面的public abstract可以省略
public abstract String name();
//前面的数据类型,不是所有类型都支持
//通过default 关健字给属性赋上默认值
int num() default 100;
Class haha();
}
注意:
一旦注解有属性了,使用注解的时候必须赋值
(除非这个注解属性有默认值)
元注解
限定注解的注解
JDK提供的两个常用的元注解
@Retention 规定注解保留在什么阶段
只在代码中保留,在字节码文件中就删除了
RetentionPolicy.SOURCE
在代码和字节码文件中保留
RetentionPolicy.CLASS
所有阶段都保留(保留到运行阶段)
RetentionPolicy.RUNTIME
@Target 限定注解用在什么地方
作用在类 接口 等上面
ElementType.TYPE
作用方法上面
ElementType.METHOD
作用字段上面
ElementType.FIELD
注解连接数据库
注解类: 定义连接数据库所需的四个参数
@Target ( ElementType . METHOD)
@Retention ( RetentionPolicy . RUNTIME)
public @interface JDBCAnnotation {
String driverClass ( ) default "com.mysql.jdbc.Driver" ;
String url ( ) default "jdbc:mysql://localhost:3306/my_database" ;
String user ( ) default "root" ;
String password ( ) default "123456" ;
}
工具类
public class JDBCUtils {
@JDBCAnnotation ( password = "123456" )
public static Connection getConnection ( ) throws Exception {
Class clazz= JDBCUtils . class ;
Method m = clazz. getMethod ( "getConnection" ) ;
boolean b = m. isAnnotationPresent ( JDBCAnnotation . class ) ;
if ( b) {
JDBCAnnotation annotation = m. getAnnotation ( JDBCAnnotation . class ) ;
String driverClass = annotation. driverClass ( ) ;
String url = annotation. url ( ) ;
String user = annotation. user ( ) ;
String password = annotation. password ( ) ;
Class . forName ( driverClass) ;
return DriverManager . getConnection ( url, user, password) ;
}
return null ;
}
}
测试类
public class Test {
public static void main ( String [ ] args) throws Exception {
Connection connection = JDBCUtils . getConnection ( ) ;
System . out. println ( connection) ;
}
}