虽已工作多年,但对于过滤器与拦截器还是搞不清楚,今天特意留心学习了下:
1、拦截器是基于java的反射机制的,而过滤器是基于函数回调
2、过滤器依赖与servlet容器,而拦截器不依赖与servlet容器
3、拦截器只能对action请求起作用,而过滤器则可以对几乎所有的请求起作用
4、拦截器可以访问action上下文、值栈里的对象,而过滤器不能
5、在action的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次
1.过滤器
Servlet中的过滤器Filter是实现了javax.servlet.Filter接口的服务器端程序,主要的用途是过滤字符编 码、做一些业务逻辑判断等。其工作原理是,只要你在web.xml文件配置好要拦截的客户端请求,它都会帮你拦截到请求,此时你就可以对请求或响应 (Request、Response)统一设置编码,简化操作;同时还可进行逻辑判断,如用户是否已经登陆、有没有权限访问该页面等等工作。它是随你的 web应用启动而启动的,只初始化一次,以后就可以拦截相关请求,只有当你的web应用停止或重新部署的时候才销毁
例:
public class ChineseFilter implements Filter {
@Override
public void destroy() {
// TODO Auto-generated method stub
}
@Override
public void doFilter(ServletRequest req, ServletResponse resp,
FilterChain chain) throws IOException, ServletException {
// TODO Auto-generated method stub
req.setCharacterEncoding("UTF-8");
resp.setCharacterEncoding("UTF-8");
chain.doFilter(req, resp);
}
@Override
public void init(FilterConfig arg0) throws ServletException {
// TODO Auto-generated method stub
}
<!-- 编码过滤器 -->
<filter>
<filter-name>ChineseFilter</filter-name>
<filter-class>com.dianzhi.filter.ChineseFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>ChineseFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
例2:url
public class ChinaFilter implements Filter {
public void destroy() {
// TODO Auto-generated method stub
}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse res = (HttpServletResponse) response;
String uri = req.getRequestURI();// /web1.0/admin/index.jsp
// StringBuffer url
// =req.getRequestURL();//http://localhost:8080/web1.0/admin/index.jsp
String path = req.getContextPath();// /web1.0
String reqPath = uri.substring(path.length());// /admin/login.jsp
// System.out.println(uri);
// System.out.println(path);
// System.out.println(reqPath);
if (reqPath.startsWith("/admin") && !reqPath.startsWith("/admin/js")
&& !reqPath.startsWith("/admin/css")
&& !reqPath.startsWith("/admin/images")){
if(reqPath.equals("/admin/login.jsp")){
chain.doFilter(request, response);
return;
}else{
Users u=(Users)req.getSession().getAttribute("loginUser");
if(u==null){
res.sendRedirect(req.getContextPath()+"/admin/login.jsp");
return;
}else{
chain.doFilter(req, res);
}
}
}else{
chain.doFilter(req, res);
}
}
/* public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
// TODO Auto-generated method stub
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse res = (HttpServletResponse) response;
String uri = req.getRequestURI();// /web/admin/index.jsp
String path = req.getContextPath();// /web
String reqpath = uri.substring(path.length());
if(reqpath.startsWith("/admin")&&!reqpath.startsWith("/admin/csss")&&!reqpath.startsWith("/admin/images")&&!reqpath.startsWith("/admin/js")){
if(reqpath.equals("/admin/login.jsp")){
chain.doFilter(request, response);
return;
}else{
Users u = (Users) req.getSession().getAttribute("loginUser");
if(u==null){
res.sendRedirect(req.getContextPath()+"/admin/login.jsp");
return;
}else{
chain.doFilter(req, res);
}
}
}else{
chain.doFilter(req, res);
}
}
*/
public void init(FilterConfig filterConfig) throws ServletException {
// TODO Auto-generated method stub
}
}
2.监听器
监听器:一个类一个实现监听器接口的类一个要在web.xml配置的类
现在来说说Servlet的监听器Listener,它是实现了javax.servlet.ServletContextListener 接口的服务器端程序,它也是随web应用的启动而启动,只初始化一次,随web应用的停止而销毁。主要作用是: 做一些初始化的内容添加工作、设置一些基本的内容、比如一些参数或者是一些固定的对象等等。
监听对象:request,session,application
何时监听:
监听器就是可以在
application,session,request三个对象
创建消亡或者往其中
添加修改删除属性时
自动执行代码的组件
监听器接口:
request
ServletRequestAttributeListener
ServletRequestListener
session
HttpSessionAttributeListener
HttpSessionListener
application
ServletContextAttributeListener
ServletContextListener
web.xml
<listener>
<listener-class>com.wangwang.ContextListener</listener-class>
</listener>
案例:统计网站在线数
public class InitNumberServletContextListener implements ServletContextListener{
public void contextDestroyed(ServletContextEvent arg0) {
}
public void contextInitialized(ServletContextEvent event) {
ServletContext application = event.getServletContext();
//在线人数
application.setAttribute("onLineCount", 0);
//到目前为止访问量
application.setAttribute("fangke", 0);
//最高在线人数
application.setAttribute("maxOnLineCount", 0);
}
public class HttpSessionListenerImpl implements HttpSessionListener{
public void sessionCreated(HttpSessionEvent event) {
ServletContext application = event.getSession().getServletContext();
//在线人数加一
int onLineCount = Integer.parseInt(application.getAttribute("onLineCount").toString());
onLineCount ++;
application.setAttribute("onLineCount", onLineCount);
//累积访问人次加一
int fangke = Integer.parseInt(application.getAttribute("fangke").toString());
fangke ++;
application.setAttribute("fangke", fangke);
event.getSession().setAttribute("myweizhi", fangke);
int maxOnLineCount = Integer.parseInt(application.getAttribute("maxOnLineCount").toString());
//如果现在的在线人数大于最大在线人数
if (onLineCount > maxOnLineCount) {
application.setAttribute("maxOnLineCount", onLineCount);
String dateStr = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
application.setAttribute("maxOnLineCountDate", dateStr);
}
}
public void sessionDestroyed(HttpSessionEvent event) {
//在线人数减一
ServletContext application = event.getSession().getServletContext();
int onLineCount = Integer.parseInt(application.getAttribute("onLineCount").toString());
onLineCount --;
application.setAttribute("onLineCount", onLineCount);
}
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<listener>
<listener-class>com.yun4j.HttpSessionListenerImpl</listener-class>
</listener>
<listener>
<listener-class>com.yun4j.InitNumberServletContextListener</listener-class>
</listener>
</web-app>
index.jsp
<%@ page language="java" contentType="text/html; charset=gbk"%>
<html>
<head>
<title>网站人数统计</title>
</head>
<body>
您好,您是本网站第${sessionScope.myweizhi}位访客.<br>
目前的在线人数为${applicationScope.onLineCount}位.<br>
本网站在${applicationScope.maxOnLineCountDate}达到了最多访问人数,为${applicationScope.maxOnLineCount}位<br>
<hr>
您好,您是本网站第<%=session.getAttribute("myweizhi")%>位访客.<br>
目前的在线人数为<%=application.getAttribute("onLineCount")%>位.<br>
本网站在<%=application.getAttribute("maxOnLineCountDate")%>达到了最多访问人数,
为<%=application.getAttribute("maxOnLineCount")%>位<br>
<a href="invalidate.jsp">注销</a>
</body>
</html>
invalidate.jsp
<%@ page language="java" import="java.util.*" pageEncoding="ISO-8859-1"%>
<%
session.invalidate();
%>
//其是有一个严重问题就是如果是当前的访问量可以用session,但是如果是累计访问量就不能用application对象(如果是需要登陆的系统就不能用),如果上下文一消失,累计访问量就又成了0,所以应该在用户登陆后,把累计的数据写到一个文件中,用户登陆时,再从文件中读取文件。
3.拦截器
拦截器是在面向切面编程中应用的,就是在你的service或者一个方法前调用一个方法,或者在方法后调用一个方法。是基于JAVA的反射机制。拦截器不是在web.xml,比如struts在struts.xml中配置