拦截器是什么?
一张图来解释:
总结:
拦截器目的:
编写一次公共代码,到处运行
JSP是servlet
拦截器是特殊的servlet
特点:
继承 Filter //过滤器核心接口
重要接口和方法:
Filter接口:
//初始化方法,在服务器启动过程中执行
Void init(filterConfig);
//过滤器拦截的业务处理方法(公共代码写在此)
Void doFilter(request,response,filterChain);
//销毁过滤器实例时候调用
Void destroy();
注意:
servlet是服务器启动结束后启动 不过也可以提前 不过需要配置
FilterConfig接口 获取初始化参数信息
String getInitParameter(java.lang.String name)
Enumeration getInitParameterNames()
FilterChain接口 过滤器链参数;
//一个个过滤器形成一个执行链;
//执行下一个过滤器或者退出过滤器进入Servlet或者JSP资源
void doFilter(ServletRequest request,
ServletResponse response) ;
Web.xml也要配置:
<filter>
<filter-name>NewFilter</filter-name>
<filter-class>Filter.NewFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>NewFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
注意三点:
第一点:拦截的范围
<!-- 拦截指定的jsp
<url-pattern>/index.jsp</url-pattern>
<url-pattern>/list.jsp</url-pattern>
-->
<!-- 拦截所有的jsp
<url-pattern>*.jsp</url-pattern>
-->
<!-- 拦截所有的资源
<url-pattern>/*</url-pattern>
-->
<!-- 3. 根据servlet的内部名称拦截
<servlet-name>IndexServlet</servlet-name>
-->
<!-- 拦截指定的servlet
<url-pattern>/index</url-pattern>
第二点:配置初始化参数
<init-param>
是servlet范围内的参数,只能在servlet类的init()方法中取得
<filter>
<filter-name>Filter</filter-name>
<filter-class>Filter.Filter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
<init-param>
<param-name>path</param-name>
<param-value>www.baidu.com</param-value>
</init-param>
</filter>
拦截器获取配置参数:
@Override
public void init(FilterConfig filterConfig) throws ServletException {
//根据参数名字获取指定的内容
System.out.println(filterConfig.getInitParameter("encoding")+"|"+
filterConfig.getInitParameter("path"));
//获取全部参数以及内容
Enumeration<String> enumeration = filterConfig.getInitParameterNames();
while(enumeration.hasMoreElements()) {
String name = enumeration.nextElement();
String value = filterConfig.getInitParameter(name);
System.out.println(name+":"+value);
}
}
第三点:拦截的类型
默认拦截的类型:(直接访问或者重定向)
<dispatcher>REQUEST</dispatcher>
拦截转发:
<dispatcher>FORWARD</dispatcher>
拦截包含的页面(RequestDispatcher.include(/page.jsp);
对page.jsp也执行拦截)
<dispatcher>INCLUDE</dispatcher>
拦截声明式异常信息:
<dispatcher>ERROR</dispatcher>
web.xml配置:
<filter-mapping>
<filter-name>Filter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
如果有多个拦截器,那顺序呢?
arg2.doFilter(arg0, arg1);就是个拦截器链
顺序就是xml中的配置前后顺序
过程:
1.用户访问服务器
2.过滤器: 对Servlet或者JSP请求进行拦截
3.先进入过滤器, 过滤器处理
4.过滤器处理完后, 再放行, 此时,请求到达Servlet/JSP
5.Servlet处理
6.Servlet处理完后,再回到过滤器, 最后在由tomcat服务器相应用户
注意:
拦截器拦截后进入servlet后 虽然servlet执行了操作,但是转发之类的都是等跳出拦截器后才触发显示
拦截器拦截jsp也是等拦截器结束后
访问的资源是jsp的时候也是先进入拦截器 然后进入jsp 再跳到拦截器 注意:在拦截器跳转的过程中浏览器的地址栏都是空的 最后响应浏览器 浏览器才会显示jsp内容
几个不同的request 就几个不同的拦截器
request拦截几次?
1. servlet里面如果有转发的话 就只拦截一次
转发是属于同一个request 所以创建的也是同一个拦截器 只有一个init
而重定向有两种方式:
因为不是 同一个request 所以会创建多个拦截器
重定向中:
response.sendRedirect("https://www.baidu.com");
如果是访问外部的网站如www.baidu.com则一次拦截,
第二次没有访问服务器内部 所以也没有创建第二个拦截器
response.sendRedirect(request.getContextPath()+
"/NewServlet");
如果是访问内部的资源 那就是 两次进入拦截器
注意:
先进入拦截器 再进入原来的资源 然后跳出到原来的拦截器
然后再此进入新的拦截器 进入重定向的资源 然后再跳到拦截器
然后再响应浏览器的请求 这里其实创建了两个拦截器
错误:
cvc-complex-type.2.4.a: Invalid content was found starting with element 'init-param'. One of '{"http://java.sun.com/xml/ns/javaee":description, "http://java.sun.com/xml/ns/
javaee":display-name, "http://java.sun.com/xml/ns/javaee":icon, "http://java.sun.com/xml/ns/javaee":filter-name}' is expected.
原因:
init-param要放到<filter-name>和<filter-class>下面才行
不然会报错