文章目录
Java基础(五)过滤器、监听器
过滤器
过滤器的使用
使用过滤器的流程:
- 配置xml,使过滤器具有拦截请求的效果。
- 编写过滤器的实现类。
看起来是不是与servlet相同?(servlet也是配置xml使得servlet具有拦截其自身名请求的效果、实现servlet类)
在经过过滤器时,会请求过滤器放行。
通过一个小例子来熟悉过滤器:(一个jsp在访问一个servlet中间添加一个过滤器)
index.jsp:
<body>
<a href="MyServlet"></a>
</body>
MyServlet.java:
@WebServlet(name = "MyServlet", urlPatterns = "/MyServlet")
public class DownFileServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("server...");
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
MyFilter.java:
要想将一个普通类变成一个具有功能的类有三个办法:1、继承一个类。2、实现一个接口。3、增加一个注解。
public class MyFilter implements Filter{
//要注意这个Fileter是java.servlet包中的类
public void init() throws ServletException{
System.out.println("init....");
}
public void doFilter(SerletRequest request, ServletResopnse resopnse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("拦截请求");
filterChain.doFilter(request, response);
//注意过滤器在过滤中会拦截请求或响应,只有放行后才能将请求送到servlet。而filterChain.doFilter()就是在放行。
//filterChain.doFilter(request, null);这是只放行request
System.out.println("拦截响应");
}
public void destory{
System.out.println("destory");
}
}
结果是(一次请求响应的):
init....
拦截请求
server...
拦截响应
为什么是这样呢?不应该是显示两遍拦截请求拦截响应吗?看下面这张图:
从上面代码可以看出filer与servlet是类似的,所以filter也有生命周期与servlet相同有五个。init在创建时执行一次,destory在服务器结束时执行一次。
既然filter与servlet类似,那么filter也需要在web.xml中配置一下(写成注解就不需要配置了)。
<!--配置过滤器(类似servlet)-->
<filter>
<filter-name>Myfilter</filter-name>
<filter-class>pers.filter.MyFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>Myfilter</filter-name>
<url-pattern>/MyServlet</url-pattern>
<!--拦截所有根目录中请求Myservlet的请求。拦截后通过映射找到Myfilter。有没有看出来有点servlet的味道。-->
</filter-mapping>
使用通配符进行请求拦截:
<!--1、拦截一切请求,只要是个请求就拦截(包括客户端访问服务端、服务端内请求转发)。-->
<url-pattern>/*</url-pattern>
<!--
2、dispatcher请求方式:
* 2-1、REQUEST:拦截http请求(get、post)。
* 2-2、FOERWARD:只拦截通过请求转发方式的请求。
2-3、INCLUDE:只拦截通过request.getRequestDispatcher("").include()、通过<jsp:include page="....">这两种方式的请求。
2-4、ERROR:只拦截<error-page>发出的请求。
-->
<filter>
<filter-name>Myfilter</filter-name>
<filter-class>pers.filter.MyFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>Myfilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
如果在拦截页面中进行请求转发(或重定向)会进行多次拦截。例如请求转发:
在MyServlet中重定向则是:请求拦截、MyServlet、响应拦截、请求拦截、响应拦截。
过滤器链
哪个mapping在前就是前面的过滤器(filter1),哪个mapping在后面就是后面的过滤器(filter2)。
监听器
监听器就类似于HTML中的onclick等操作。用于监听。
监听器作用对象:
- 四个范围对象中的三个:request,session,application。
每个监听器提供了两个方法:开始方法、结束方法。
配置监听器
<listener>
<listener-class>pers.qiu.listener.MyListener</listener-class>
</listener>
监听对象的创建与销毁
request监听器(ServerRequestListener)
public class MyListener implements ServletRequestListener{
@Override
public void requestDestroyed(ServletRequestEvent servletRequestEvent) {
//与javase中的监听器相同,servletRequestEvent是监听对象。(监听的谁它就是谁)
System.out.println("监听ServletRequest,销毁servletRequestEvent对象");
}
@Override
public void requestInitialized(ServletRequestEvent servletRequestEvent) {
//创建的对象就是servletRequestEvent这个监听对象。
System.out.println("监听ServletRequest,创建servletRequestEvent对象");
}
}
与javase中的监听器相同,servletRequestEvent是监听对象。(监听的谁它就是谁)
这个监听器是:创建request时(有一个请求时)就创建一个request监听器,创建后就会调用requestInitialized方法。在request作用完之后就会销毁,监听器就会调用requestDestroyed方法。(也就是说request监听器的作用就是监听request的创建与销毁)以下监听器同理。
session监听器(HttpSessionListener)
public class MyListener implements HttpSessionListener{
@Override
public void sessionCreated(HttpSessionEvent httpSessionEvent) {
System.out.println("监听HttpSession,创建httpSessionEvent对象");
}
@Override
public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
System.out.println("监听HttpSession,销毁httpSessionEvent对象");
}
}
application监听器(ServletContextListener)
public class MyListener implements ServletContextListener{
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
System.out.println("监听ServletContext,创建servletContextEvent对象");
}
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
System.out.println("监听ServletContext,销毁servletContextEvent对象");
}
}
ServletContext是全局对象的类所以该监听器在服务器启动时自动调用。
监听三个
public class MyListener implements ServletRequestListener, HttpSessionListener, ServletContextListener{
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
}
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
}
@Override
public void requestDestroyed(ServletRequestEvent servletRequestEvent) {
}
@Override
public void requestInitialized(ServletRequestEvent servletRequestEvent) {
}
@Override
public void sessionCreated(HttpSessionEvent httpSessionEvent) {
}
@Override
public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
}
}
监听对象中属性的变更(add、remove、replace)
- request:ServletRequestAttributeListener
- session:HttpSessionAttributeListener
- application:ServletContextAttributeListener
ServletRequestAttributeListener
public class AttributeListener implements ServletRequestAttributeListener {
@Override
public void attributeAdded(ServletRequestAttributeEvent servletRequestAttributeEvent) {
System.out.println("request增加属性"+servletRequestAttributeEvent.getName()+"value="+servletRequestAttributeEvent.getValue());
}
@Override
public void attributeRemoved(ServletRequestAttributeEvent servletRequestAttributeEvent) {
}
@Override
public void attributeReplaced(ServletRequestAttributeEvent servletRequestAttributeEvent) {
//获取修改的属性名
String name = servletRequestAttributeEvent.getName();
String value = servletRequestAttributeEvent.getServletRequest.getAttribute(name);
//这是通过request对象进行获取,使用getValue()也可以
}
}
HttpSessionAttributeListener
public class AttributeListener implements HttpSessionAttributeListener {
@Override
public void attributeAdded(HttpSessionBindingEvent httpSessionBindingEvent) {
}
@Override
public void attributeRemoved(HttpSessionBindingEvent httpSessionBindingEvent) {
}
@Override
public void attributeReplaced(HttpSessionBindingEvent httpSessionBindingEvent) {
}
}
ServletContextAttributeListener
public class AttributeListener implements ServletContextAttributeListener {
@Override
public void attributeAdded(ServletContextAttributeEvent servletContextAttributeEvent) {
}
@Override
public void attributeRemoved(ServletContextAttributeEvent servletContextAttributeEvent) {
}
@Override
public void attributeReplaced(ServletContextAttributeEvent servletContextAttributeEvent) {
}
}
三者都有
public class AttributeListener implements ServletRequestAttributeListener, HttpSessionAttributeListener, ServletContextAttributeListener {
@Override
public void attributeAdded(ServletContextAttributeEvent servletContextAttributeEvent) {
}
@Override
public void attributeRemoved(ServletContextAttributeEvent servletContextAttributeEvent) {
}
@Override
public void attributeReplaced(ServletContextAttributeEvent servletContextAttributeEvent) {
}
@Override
public void attributeAdded(ServletRequestAttributeEvent servletRequestAttributeEvent) {
}
@Override
public void attributeRemoved(ServletRequestAttributeEvent servletRequestAttributeEvent) {
}
@Override
public void attributeReplaced(ServletRequestAttributeEvent servletRequestAttributeEvent) {
}
@Override
public void attributeAdded(HttpSessionBindingEvent httpSessionBindingEvent) {
}
@Override
public void attributeRemoved(HttpSessionBindingEvent httpSessionBindingEvent) {
}
@Override
public void attributeReplaced(HttpSessionBindingEvent httpSessionBindingEvent) {
}
}