11

史上最全面‘java监听器’解读,读完就能用进项目

 3 years ago
source link: https://my.oschina.net/u/4613350/blog/4870605
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Web监听器导图详解

  监听器是JAVA Web开发中很重要的内容,其中涉及到的知识,可以参考下面导图:

一、Web监听器

1. 什么是web监听器?

  web监听器是一种Servlet中的特殊的类,它们能帮助开发者监听web中的特定事件,比如ServletContext,HttpSession,ServletRequest的创建和销毁;变量的创建、销毁和修改等。可以在某些动作前后增加处理,实现监控。

2. 监听器常用的用途

  通常使用Web监听器做以下的内容:

  统计在线人数,利用HttpSessionLisener

  加载初始化信息:利用ServletContextListener

  统计网站访问量

  实现访问监控

3. 接下来看看一个监听器的创建以及执行过程

   首先需要创建一个监听器,实现某种接口,例如我想实现一个对在线人数的监控,可以创建如下的监听器:

public class MyListener implements HttpSessionListener{
    private int userNumber = 0;
    public void sessionCreated(HttpSessionEvent arg0) {
        userNumber++;
        arg0.getSession().setAttribute("userNumber", userNumber);
    }
    public void sessionDestroyed(HttpSessionEvent arg0) {
        userNumber--;
        arg0.getSession().setAttribute("userNumber", userNumber);
    }
}

  然后在web.xml中配置该监听器,在web-app中添加:

  <listener>
      <listener-class>com.test.MyListener</listener-class>
  </listener>

  在JSP中添加访问人数:

<body>
    在线人数:<%=session.getAttribute("userNumber") %><br/>
</body>

  当我使用我的浏览器访问时,执行结果如下:

  当打开另一个浏览器访问时:

  由于打开另一个浏览器访问,相当于另一个会话,因此在线人数会增加。

  对于3.0版本的Servlet来说,还支持使用注解的方式进行配置。

  那么接下来看看都有哪些监听器以及方法吧!

二、监听器的分类

1. 按照监听的对象划分:

  按照监听对象的不同可以划分为三种:

  ServletContext监控:对应监控application内置对象的创建和销毁。

  当web容器开启时,执行contextInitialized方法;当容器关闭或重启时,执行contextDestroyed方法。

  实现方式:直接实现ServletContextListener接口:

public class MyServletContextListener implements ServletContextListener{
    public void contextDestroyed(ServletContextEvent sce) {

    }
    public void contextInitialized(ServletContextEvent sce) {

    }
}

  HttpSession监控:对应监控session内置对象的创建和销毁。

  当打开一个新的页面时,开启一个session会话,执行sessionCreated方法;当页面关闭session过期时,或者容器关闭销毁时,执行sessionDestroyed方法。

  实现方式:直接实现HttpSessionListener接口:

public class MyHttpSessionListener implements HttpSessionListener{
    public void sessionCreated(HttpSessionEvent arg0) {

    }
    public void sessionDestroyed(HttpSessionEvent arg0) {

    }
}

  ServletRequest监控:对应监控request内置对象的创建和销毁。

  当访问某个页面时,出发一个request请求,执行requestInitialized方法;当页面关闭时,执行requestDestroyed方法。

  实现方式,直接实现ServletRequestListener接口:

public class MyServletRequestListener implements ServletRequestListener{
    public void requestDestroyed(ServletRequestEvent arg0) {

    }
    public void requestInitialized(ServletRequestEvent arg0) {

    }
}

2. 按照监听事件划分:

  2.1 监听事件自身的创建和销毁:同上面的按对象划分。

  2.2 监听属性的新增、删除和修改:

  监听属性的新增、删除和修改也是划分成三种,分别针对于ServletContext、HttpSession、ServletRequest对象:

  ServletContext,实现ServletContextAttributeListener接口:

  通过调用ServletContextAttribtueEvent的getName方法可以得到属性的名称。

public class MyServletContextAttrListener implements ServletContextAttributeListener {
	public void attributeAdded( ServletContextAttributeEvent hsbe )
	{
		System.out.println( "In servletContext added :name = " + hsbe.getName() );
	}


	public void attributeRemoved( ServletContextAttributeEvent hsbe )
	{
		System.out.println( "In servletContext removed :name = " + hsbe.getName() );
	}


	public void attributeReplaced( ServletContextAttributeEvent hsbe )
	{
		System.out.println( "In servletContext replaced :name = " + hsbe.getName() );
	}
}

  HttpSession,实现HttpSessionAttributeListener接口:

public class MyHttpSessionAttrListener implements HttpSessionAttributeListener {
	public void attributeAdded( HttpSessionBindingEvent hsbe )
	{
		System.out.println( "In httpsession added:name = " + hsbe.getName() );
	}


	public void attributeRemoved( HttpSessionBindingEvent hsbe )
	{
		System.out.println( "In httpsession removed:name = " + hsbe.getName() );
	}


	public void attributeReplaced( HttpSessionBindingEvent hsbe )
	{
		System.out.println( "In httpsession replaced:name = " + hsbe.getName() );
	}
}

  ServletRequest,实现ServletRequestAttributeListener接口:

public class MyServletRequestAttrListener implements ServletRequestAttributeListener {
	public void attributeAdded( ServletRequestAttributeEvent hsbe )
	{
		System.out.println( "In servletrequest added :name = " + hsbe.getName() );
	}


	public void attributeRemoved( ServletRequestAttributeEvent hsbe )
	{
		System.out.println( "In servletrequest removed :name = " + hsbe.getName() );
	}


	public void attributeReplaced( ServletRequestAttributeEvent hsbe )
	{
		System.out.println( "In servletrequest replaced :name = " + hsbe.getName() );
	}
}

  2.3 监听对象的状态:

  针对某些POJO类,可以通过实现HttpSessionBindingListener接口,监听POJO类对象的事件。例如:

public class User implements HttpSessionBindingListener,Serializable{

    private String username;
    private String password;

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public void valueBound(HttpSessionBindingEvent hsbe) {
        System.out.println("valueBound name: "+hsbe.getName());
    }

    public void valueUnbound(HttpSessionBindingEvent hsbe) {
        System.out.println("valueUnbound name: "+hsbe.getName());
    }

}

  Session数据的钝化与活化:

  由于session中保存大量访问网站相关的重要信息,因此过多的session数据就会服务器性能的下降,占用过多的内存。因此类似数据库对象的持久化,web容器也会把不常使用的session数据持久化到本地文件或者数据中。这些都是有web容器自己完成,不需要用户设定。

  不用的session数据序列化到本地文件中的过程,就是钝化;

  当再次访问需要到该session的内容时,就会读取本地文件,再次放入内存中,这个过程就是活化。

  类似的,只要实现HttpSeesionActivationListener接口就是实现钝化与活化事件的监听:

public class User implements HttpSessionBindingListener,
HttpSessionActivationListener,Serializable{

    private String username;
    private String password;

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public void valueBound(HttpSessionBindingEvent hsbe) {
        System.out.println("valueBound name: "+hsbe.getName());
    }

    public void valueUnbound(HttpSessionBindingEvent hsbe) {
        System.out.println("valueUnbound name: "+hsbe.getName());
    }

    public void sessionDidActivate(HttpSessionEvent hsbe) {
        System.out.println("sessionDidActivate name: "+hsbe.getSource());
    }

    public void sessionWillPassivate(HttpSessionEvent hsbe) {
        System.out.println("sessionWillPassivate name: "+hsbe.getSource());
    }

}

三、Servlet版本与Tomcat版本

  首先看一下Tomcat官网给出的匹配:

  如果版本不匹配,那么tomcat是不能发布该工程的,首先看一下版本不匹配时,会发生什么!

  我试图创建一个web工程,并且选取了Servlet3.0版本:

  然后我想要在tomcat6中发布,可以看到报错了!

  JDK版本不对....这是在平时开发如果对Servlet不熟悉的web新手,常犯的错误。

解决方法:

  1 在创建时,直接发布到Tomcat容器中,此时Servlet仅仅会列出Tomcat支持的版本:

  2 修改工程Servlet版本配置信息,文件为:工作目录\SessionExample.settings\org.eclipse.wst.common.project.facet.core.xml

<?xml version="1.0" encoding="UTF-8"?>
<faceted-project>
  <runtime name="Apache Tomcat v6.0"/>
  <fixed facet="java"/>
  <fixed facet="wst.jsdt.web"/>
  <fixed facet="jst.web"/>
  <installed facet="java" version="1.7"/>
  <installed facet="jst.web" version="2.5"/>
  <installed facet="wst.jsdt.web" version="1.0"/>
</faceted-project>
4870605

四、getAttribute与getParameter的区别

  这部分是对JSP的扩展,经常在JSP或者Servlet中获取数据,那么getAttribute与getParameter有什么区别呢?

1. 从获取到数据的来源来说:

  getAttribtue获取到的是web容器中的值,比如:

  我们在Servlet中通过setAttribute设定某个值,这个值存在于容器中,就可以通过getAttribute方法获取;

  getParameter获取到的是通过http传来的值,比如这样一个http请求:

http:localhost:8080/test/test.html?username=xingoo

  还有其他的GET和POST方式,都可以通过getParameter来获取。

2. 从获取到的数据类型来说:

  getAttribute返回的是一个对象,Object。

  getParameter返回的是,前面页面中某个表单或者http后面参数传递的值,是个字符串。

原文:https://juejin.cn/post/6911973816218435597

程序员年薪百万的飞马计划你听说过吗?

为什么阿里巴巴的程序员成长速度这么快?

从事开发一年的程序员能拿到多少钱?

字节跳动总结的设计模式 PDF 火了,完整版开放下载

关于【暴力递归算法】你所不知道的思路

开辟鸿蒙,谁做系统,聊聊华为微内核

00231


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK