Filter简介:
过滤器是执行过滤任务的对象,这些任务是针对对某一资源(servlet 或静态内容)的请求或来自某一资源的响应执行的,抑或同时针对这两者执行。
Filter的开发过程:
1.书写一个class实现Filter接口
2.将filter注册到web.xml
Filter的配置
如果一个访问路径中配置了多个FIlter,那么谁的<filter-mapping>配置在前面谁就先调用。
两种配置模式
(1)url-pattern模式:
路径匹配:<url-pattern>/*</url-pattern> 拦截所有访问项目的请求
后缀名匹配: <url-pattern>*.do</url-pattern> 拦截以".do"结尾的请求路径的请求
(2)指定拦截Servlet模式:
<servlet-name>AServlet</servlet-name> 按照访问的Servlet来拦截(不常用).
注意:配置方式1和方式2可以同时使用.
注意:如果某个路径同时符合模式1和模式2,该FIlter将会被调用两次
注意: FIlter的路径配置中, 可以同时使用两种配置模式,并每种配置模式还可以使用多次.
Filter的生命周期
init 该方法在服务器启动时运行. Filter对象随着服务器 的启动而创建.
doFIlter 当需要拦截时 该方法运行.
destory 服务器关闭时调用,FIlter对象随着服务器的关闭而销毁.
Filter的相关对象
1.Servlet的init方法中也会接收一个ServletConfig对象
1>getInitParameter 获得初始化参数
2>getInitParameterNames 获得初始化参数的键们
3>getServletContext 获得ServletContext
4>getServletName (没用)获得Servlet的配置名称<servlet-name>
2.FilterConfig
String getFilterName() 获得FIlter注册的名称
String getInitParameter(String name) 根据键获得FIlter元素中的 键值对
Enumeration getInitParameterNames() 获得所有Filter元素中的键.
ServletContext getServletContext() 获得ServletContext(application)对象
总结: 获得ServletContext的方法
1>ServletConfig
2>HttpSession
3>PageContext
4>FilterConfig
FilterChain 滤器链
FilterChain就是在请求时,服务器会把所有要经过的Filter实例引用交给FilterChain. 我们在Filter的doFilter方法中可以拿到该对象.并且调用该对象的doFilter方法(放行),filterchain会去向下找后续要调用的过滤器.如果有就继续调用下一个过滤器的doFilter方法.如果没有就执行对应的资源,例如servlet.所以,在开发时使用FilterChain对象的doFilter方法放行.如果想要拦截下来不再向后执行. 不要调用doFIlter方法.
Filter 的4种过滤方式
<dispatcher></dispatcher>使用该配置来决定Filter的拦截方式.
*REQUEST(默认值) ==> 当正常请求时,Filter会拦截
*FORWARD ==> 在请求转发时才会拦截
*INCLUD ==> 请求包含时才会拦截
*ERROR ==> 转向错误页面时会拦截
案例:
1,在filter中处理get/post提交时中文参数乱码问题.
(1). 创建一个Request对象(使用装饰设计模式装饰原始request),装 与参数相关方法,解决get乱码
package cn.web.filter; import java.io.UnsupportedEncodingException; import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; //解决全站中文乱码问题 public class MyRequest extends HttpServletRequestWrapper implements HttpServletRequest { private HashMap<String, String[]> map2; //装饰request类 public MyRequest(HttpServletRequest request) { super(request); //调用getParameterMap获得含有乱码的Map集合 Map<String, String[]> map = request.getParameterMap(); //创建新的map对象 map2= new HashMap<String, String[]>(); //遍历Map集合 for(Entry<String, String[]> en :map.entrySet()){ //获得key键 String key = en.getKey(); //获得value值 String[] values = en.getValue(); //遍历修改每一个键对应的所有值乱码 for(int i=0;i<values.length;i++){ try { values[i] = new String(values[i].getBytes("ISO-8859-1"),"UTF-8"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } } //将解决乱码后的键值对加入新的map集合中 map2.put(key, values); } } //解决单个键获取单个值的乱码情况 @Override public String getParameter(String name) { //获取键对应的值 String[] values_01 = map2.get(name); //值不为空时,才进行编码修改 if(values_01!=null&&values_01.length>0){ return values_01[0]; } return null; } //解决单个键获取多个值得乱码情况 public Map getParameterMap() { // TODO Auto-generated method stub return map2; } @Override public String[] getParameterValues(String name) { return map2.get(name); } }
(2). 创建Filter 并设置其拦截路径为/*.
package cn.web.filter; import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; public class EncodingFilter implements Filter { public EncodingFilter() { } public void destroy() { } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { //0.解决相应乱码问题 response.setCharacterEncoding("UTF-8"); //1.使用myRequest装饰原生request对象 MyRequest myRequest = new MyRequest((HttpServletRequest)request); //2.放行请求与相应 chain.doFilter(myRequest, response); } public void init(FilterConfig fConfig) throws ServletException { } }
2.权限访问控制,根据url来进行权限控制
三类资源:
所有用户都可访问的资源(登录页面)
登录用户可访问的页面
admin用户可以访问的后台管理页面
Filter处理流程
1>. 获得 当前请求访问路径
2>. 判断当前访问的资源是否属于1类资源
//属于=>放行
3>.获得session中的登陆标示
//获得不到=>重定向到登陆页面
4>.判断用户访问是不是2类资源
//是=>放行
5.判断登陆用户是否是管理员
//是=>放行
//不是=>提示您没有权限访问
LoginServlet.java
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("UTF-8"); //获得用户名 String username = request.getParameter("username"); //将用户名放入session中 request.getSession().setAttribute("username", username); //重定向到用户登录成功页面 response.sendRedirect(request.getContextPath()+"/success.jsp"); }
PrivilegeFilter.java
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest req = (HttpServletRequest)request; HttpServletResponse resp = (HttpServletResponse) response; //1.获得当前请求的访问路径 String servletPath = req.getServletPath(); System.out.println(servletPath); //2.判断访问页面为登录页面,即为1类资源,所有用户均可访问予以放行 if("/LoginJsp.jsp".equals(servletPath)||"/LoginServlet".equals(servletPath)){ chain.doFilter(request, response); return; } //3.获取session中的登录标识 String userName = (String)req.getSession().getAttribute("username"); if(userName==null){ //如果获取不到,则重定向到登录页面 resp.sendRedirect(req.getContextPath()+"/LoginJsp.jsp"); return; } //4.判断用户访问的是不是二类资源,如果是的话,放行 if("/success.jsp".equals(servletPath)||"/noprivilige.jsp".equals(servletPath)){ chain.doFilter(request, response); return; } //5.判断用户是不是admin用户 if("admin".equals(userName)){ //如果是admin用户,则放行 chain.doFilter(request, response); return ; } else{ //如果不是,返回没有权限 resp.sendRedirect(req.getContextPath()+"/noprivilige.jsp"); } }
listener简介:
listener监听器是一个专门用于对其他对象身上发生的事件或状态改变进行监听和相应处理的对象,当被监视的对象发生情况时,立即采取相应的行动。监听器其实就是一个实现特定接口的普通java程序,这个程序专门用于监听另一个java对象的方法调用或属性改变,当被监听对象发生上述事件后,监听器某个方法立即被执行。Servlet中的监听器(8个):
ServletContext对象:
1.监听application对象的创建与销毁. ServletContextListener
2.监听application对象的属性变化 ServletContextAttributeListener
Session对象:
1.监听session对象的创建与销毁. HttpSessionListener
2.监听session对象的属性变化 HttpSessionAttributeListener
request对象:
1.监听request对象的创建与销毁.ServletRequestListener
2.监听request对象的属性变化 ServletRequestAttributeListener
Session对象:(以下两个监听器不需要注册)
1.javaBean与session的绑定与解绑 HttpSessionBindingListener 该接口需要JAVABean实现
2.javaBean在session中的活化(开启服务器时将硬盘中的session恢复到服务器内存)与钝化(关闭服务器将session的内容保存到硬盘) HttpSessionActivationListener