概念:由java编写的,线程安全的web组件,完成请求拦截和结果拦截
主要作用:作为控制层组件、请求拦截(编码拦截器、请求验证拦截器、非法文字拦截器)
结果拦截(懒加载拦截器)
语法:
1 包声明
2 包导入
import java.io.* ;
import javax.servlet.* ;
import javax.servlet.http.*;
3 包定义(实现Filter接口)
4 实现Filter接口的三个方法
public void init(FilterConfig filterConfig)
throwsServletException{}
//请求被拦截器拦截到就调用
public void doFilter(ServletRequest req,
ServletResponse resp,FilterChain chain)
throws IOException,ServletException{
//造型,使request,response 拥有http特征
HttpServletRequest request = (HttpServletRequest)req;
HttpServletResponse response = (HttpServletResponse)resp;
System.out.println("** 过滤器 doFilter (chain之前)...") ;
//一旦第一个拦截器通过,若还有拦截器,激活下一个拦截器,没有则请求下传
//如果将此语句注释,会导致所有请求都被拦截,不能下传
chain.doFilter(request,response) ;
System.out.println("** 过滤器 doFilter (chain之后)...") ;
}
public void destroy(){}
部署:打包编译
配置(/* 对所有的请求都拦截):
<filter>
<filter-name>first</filter-name>
<filter-class>cn.mldn.lxh.filter.FirstFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>first</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
编码拦截
请求拦截
只能处理用户表单里发送的汉字
语法
包声明
包导入
import java.io.* ;
import javax.servlet.* ;
import javax.servlet.http.*;
类名和文件名相同,实现Filter接口;
实现Filter接口的所有方法
public void init(FilterConfig filterConfig) throws ServletException
public void doFilter(ServletRequest request,ServletResponse response,FilterChain chain) throws IOException,ServletException{
HttpServletRequest req = (HttpServletRequest)request;
HttpServletResponse resp = (HttpServletResponse)response;
//request.setCharacterEncoding("GB2312") ;// 写死了,不够灵活,不推荐使用
request.setCharacterEncoding(this.encoding) ; // 通过配置信息获取编码,非常灵活
chain.doFilter(request,response) ; // 将请求下传
}
public void destroy()
部署:打包编译
配置(对所有的请求都拦截):
<filter>
<filter-name>encodingfilter</filter-name>
<filter-class>cn.mldn.lxh.filter.EncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>GBK</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingfilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
请求验证拦截器
请求拦截
原理
对某一类请求进行拦截,当请求来了 tomcat把请求交给拦截器,调用doFilter方法,调用session查看是否有验证信息,若没有就直接跳转到登陆界面,若有就进入首页;
实例代码:
String currentURL = request.getRequestURL(); //currentURL = /kkkk/xxxx.jsp;
String targetURL = currentURL.substring(currentURL.indexOf("/",1)); // targetURL = /xxxx.jsp;
//如果有session就返回session,否则返回NULL,默认为false
HttpSession session = request.getSession(false); //若为true:没取到session就创建一个session
if(!"/index.jsp".equals(tragetURL)){
if(session==null||session.getAttribute("name")==null){ //短路或,见真就为真,看到前 面为真就不执行后面的代码
System.out.println("request.gatContextPath()="+
request.gatContextPath()); //request.gatContextPath()=/kkkk
response.sendRedirect(request.getContextPath()+ "/index.jsp") // 服务端跳至/kkkk/index.jsp 服务端跳转不经过拦截器
return;
}
}
//请求下传
chain.doFilter(request,response);
过程
从request里获取请求字符串"/kkkk/xxxx.jsp",截取子串"/xxxx.jsp"作为目标字符串,比较目标字符串是否与"/index.jsp"一致;
若一致,判断是否有用户的session信息,若没有,跳转到登录页面,若有就将请求下传;
若不一致,直接将请求下传;
非法文字拦截器
请求拦截
只要出现指定的非法文字,就会自动跳转到出错页面,或者显示非法文字提醒;
String content = request.getParameter("content") ;
//判断是否为NULL,是NULL直接请求下传
if(content!=null)
{
// 如果indexOf返回-1则表示没有查到所要的内容
if(content.indexOf("你XX")==-1)
{
chain.doFilter(req,resp) ;
}
else
{
resp.sendRedirect("error.jsp");
System.out.println("有非法文字") ;
// 如果需要的话,此处依然可以使用RequestDispatcher进行跳转
}
}
else
{
chain.doFilter(request,response) ;
}
懒加载拦截器
结果拦截
懒加载(简单了解)
是Hibernate为提高程序执行效率而提供的一种机制,即只有真正使用该对象的数据时才会创建。
Hibernate中主要是通过代理(proxy)机制来实现延迟加载。它的具体过程:Hibernate丛数据库获取某一个对象数据时、获取某一个对象的集合属性值时,或获取某一个对象所关联的另一个对象时,由于没有使用该对象的数据,hibernate并不是数据库加载真正的数据,而只是为该对象创建一个代理对象来代表这个对象,这个对象上的所有属性都是默认值;只有在真正需要使用该对象的数据时才创建这个真实对象,真正从数据库中加载它的数据,这样在某些情况下,就可以提高查询效率。
实例:
User user=(User)session.load(class, id); // 直接返回的是代理对象
System.out.println(user.getId()); // 没有发送sql语句到数据库加载
user.getName(); // 创建真实的User实例,并发送sql语句到数据库中
懒加载拦截器
异常原因
Hibernate 允许对关联对象、属性进行延迟加载,但是必须保证延迟加载的操作限于同一个 Hibernate Session 范围之内进行。如果 Service 层返回一个启用了延迟加载功能的领域对象给 Web 层,当 Web 层访问到那些需要延迟加载的数据时,由于加载领域对象的 Hibernate Session 已经关闭,这些导致延迟加载数据的访问异常。
解决
使用"Open Session in View"的模式;
连接要在结果信息即将回到浏览器之前才关闭;
所以拦截器就是要在结果回到浏览器之前,对连接进行关闭的操作;
拦截器可以作为第三方的插件,插入项目中;
web请求大致流程:拦截器--->servlet--->jsp--->拦截器,所以servlet不适合做拦截器,因为结果最后从jsp传出去,不经过servlet;