1.过滤器(Filter)
1)Servlet过滤器能够对Servlet容器的请求和响应对象进行检查和修改
2)Servlet过滤器本身并不生成请求和响应对象,只提供过滤作用
3)Servlet过滤器能够在Servlet被调用之前检查Request对象,修改Request Header和Request内容
4)在Servlet被调用之后检查Response对象,修改Response Header和Response内容。Servlet过滤器负责过滤的web组件可以是Servlet,jsp或者HTML文件
2.Filter接口
1)所有的Servlet过滤器类都必须实现javax.servlet.Filter接口,这个接口含有3个过滤器类必须实现的方法:
init(FilterConfig filterConfig):这是Servlet过滤器初始化方法,Servlet容器创建Servlet过滤器实例后调用这个方法,在这个方法中可以读取web.xml文件中Servlet过滤器的init-param初始化参数,获取参数方法:
String value1=filterConfig.getInitParameter("hello");//hello是我们在web配置的param-name,这里只能配置字符串,不能使用变量
doFilter(ServletRequest,ServletResponse,FilterChain):这个方法完成实际过滤操作,当用户去请求访问与过滤器关联的URL时,Servlet容器将先调用过滤器的doFilter方法。其中ServletRequest和ServletResponse是通用的请求和响应对象,通常我们需要将其向下转型为我们需要的HttpServletRequest和HttpServletResponse,FilterChain(过滤器链)参数用于访问后续过滤器,过滤器会使用过滤器链来调用链中的下一个过滤器,如果调用的过滤器是链中的最后一个过滤器,那么它会调用链中的最后的资源(jsp,servlet,HTML)使用的是FilterChain中的doFilter()方法来表示继续执行。
destroy():
3.Filter在web.xml配置方法:
<filter>
<filter-name>LoginFilter</filter-name>
<filter-class>com.qjw.AllLoginFilter</filter-class>
<init-param> //init-param可以配置初始化参数
<param-name>hello</param-name>
<param-value>world</param-value>
</init-parm>
</filter>
<filter-mapping>
<filter-name>LoginFilter</filter-name>
<url-pattern>/*</url-pattern> // *号代表对当前web应用的所有请求配置这个Filter,或者我们需要过滤的servlet类
</filter-mapping>
也可以使用:
@WebFilter(name="LoginFilter",urlPattern="/*")
注意:过滤器在xml中声明的位置应该在servlet声明之前,并且和servlet一样,第一个过滤器的<filter>和第二个相连,filter-mapping也是相连,我们在web.xml文件中配置的Filter执行顺序是按照在xml文件配置的前后顺序来执行的,也就是说从最上面的Filter一直到最下面的Filter,那么如果我们使用下面注解的方式,因为其没有指定执行顺序的参数,大部分说是按照Filter文件名之类的来排序,但是我目前还没有找到能真正指定执行顺序的可行办法,所以暂时保留,以后找到了再回来补充,暂时不推荐使用这种方式。
4.Filter启动:
Servlet容器启动时Filter就会启动,执行init方法,所以在web应用中,如果有一个Filter启动失败了(比如init方法中抛异常了),那么整个应用就不能启动了。
5.多个过滤器串联的使用过程:
其中,两个Filter执行顺序是根据xml配置的前后顺序来执行的,当执行完Servlet返回时,经过后一个Filter的chain doFilter()后面的代码,然后执行前一个Filter的chain doFilter()后面的代码,然后返回给客户端。
6.注意事项:
当我们编写Filter时要注意屏蔽我们的登录页面和登录页面对应的servlet,因为我们在Filter中判断的是session是否为null,如果我们没有屏蔽登录登录页面,那么我们将一直重定向到我们的登录页,怎么屏蔽呢,是通过先获取请求的uri,通过HttpRequest对象的getRequestURI()方法获取到请求的uri,然后进行字符串的endwith(需要屏蔽的文件)判断,然后调用chain.doFilter()来继续执行。
7.Listener:
1)Listener是Servlet的监听器,它可以监听客户端的请求,服务端的操作等,通过监听器,可以自动激发一些操作,比如监听在线用户的数量
2)当增加一个HttpSession时,就激发sessionCreated(HttpSessionEvent se)方法,这样就可以给在线人数加1.
3)在web.xml声明:
<listener>
<listener-class>com.qjw.MyListener</listener-class>//只要声明我们的listener类位置就行
</listener>
8.常用的监听接口:
1)ServletContextListener监听:监听的是整个服务器的启动和关闭,这个接口的实现类会接收到一个ServletContext所处的web项目上下文改动的通知,为了接受到通知的事件,实现类必须配置到web.xml里。
contextInitialzed(ServletContextEvent sce):在所有的filter和servlet启动前会调用这个方法
contextDestoryed(ServletContextEvent sce)):在所有的filter和servlet已经被destroy后调用这个方法
2)ServletContextAttributeListener:监听的是整个web应用上下文的属性操作,增加,修改,删除,
attributeAdded(ServletContextAttributeEvent scab):当属性添加完后调用
attributeRemoved(ServletContextAttributeEvent scab):当属性移除后调用
attributeReplace(ServletContextAttributeEvent scab):当属性修改后调用
ServletContextAttributeEvent中有:
String getName():返回的是ServletContext被改变的属性名
Object getValue():返回被添加的值,返回被删除的值,返回被替换之前的值
3)HttpSessionListener:
sessionCreated(HttpSessionEvent se):当一个session被创建的时候得到通知
sessionDestroyed(HttpSessionEvent se):当一个session被销毁的时候得到通知
HttpSessionEvent有个方法HttpSession getSession()
4)HttpSessionAttributeListener:监听HttpSession中的属性的操作
attributeAdded(HttpSessionBindingEvent se):当在Sesion增加一个属性时激发
attributeRemoved(HttpSessionBindingEvent se):当在Sesion删除一个属性时 激发
attributeReplaced(HttpSessionBindingEvent se):当在Sesion重新设置一个属性时激发
HttpSessionBindingEvent:getName(),getValue()(返回的是被替换之前的值),getSession()
9.EL(Expression language表达式语言)
1)作用:尽量消除jsp页面的脚本段代码
${}
\${}直接在页面显示这个表达式
运行方式:
刻画的一些属性值和标准的动作运行,可以直接插入模板数据中,jsp包含:jsp脚本和jsp模板数据
2)内置对象:
pageScop:
requestScop:${requestScop.username}相当于<%=request.getAttribute(“username”)%>
sessionScop:${sessionScop.username}相当于<%=session.getAttribute(“username”)%>
applicationScop:${applicationScop.username}相当于<%=application.getAttribute(“username”)%>
param:${param.username}相当于<%=request.getparameter(“username”)%>
paramValues:${paramValues.username[2]}相当于<%=request.getparameterValues(“username”)[20]%>
header:
cookie:
3)运算符
+,-,*,/,%
4)比较操作符
==,!=,<,>,<=,>=
5)逻辑运算符
&&,||,!
6)用多个点来表示从对象中取属性。
${session.user.sex}
7)EL提供了.和[]两种运算符来存储数据
${sessionScope.user.sex}和${sessionScop.user.["sex"]}是一样的
${sessionScop.user[0].name}表示回传第一个用户的name
注意:
当要存取的属性名称中包含一些特殊字符如点或者-等非字母或数字的符号就一定要使用[]
${sessionScope.uesr[data]}此时,data是一个变量,若data值为sex,那么等价于${sessionScope.user.sex},若data值为name,它就等价于
${sessionScope.user.name},因此要动态取值时,就要用[]来完成。
8)EL变量
${username}如果这种情况,也就是说前面没有指定范围,比如${sessionScope.username}就指定了范围是session意思是取出某一范围中名称为username的变量,因为我们没有指定哪一个范围的username,所以默认从page找,没有依次到Request,Session,Application,找到就回传不再继续找,都没有回传null。
9)自动转变类型
${param.cout+20},将传回字符串转换为int类型再和20进行+操作
10)调用方法
${pageContext.session.id}取的session的ID