oracle的监听器listener 和 java web的监听器listener 的联系是啥?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了oracle的监听器listener 和 java web的监听器listener 的联系是啥?相关的知识,希望对你有一定的参考价值。

参考技术A

区别如下:

1、从定义方面的区别:

1)oracle监听器是Oracle基于服务器端的一种网络服务,主要用于监听客户端向数据库服务器端提出的连接请求。既然是基于服务器端的服务,那么它也只存在于数据库服务器端,进行监听器的设置也是在数据库服务器端完成的。

2)java web中的listener可以监听web服务器中某一个执行动作,并根据其要求作出相应的响应。通俗的语言说就是在application,session,request三个对象创建消亡或者往其中添加修改删除属性时自动执行代码的功能组件。比如spring 的总监听器 会在服务器启动的时候实例化配置的bean对象 、 hibernate 的 session 的监听器会监听session的活动和生命周期,负责创建,关闭session等活动。

2、从实现方面的区别:

oracle的监听是基于网络和端口号实现的:

Servlet的监听器Listener,它是实现了javax.servlet.ServletContextListener 接口的服务器端程序,它也是随web应用的启动而启动,只初始化一次,随web应用的停止而销毁。主要作用是: 做一些初始化的内容添加工作、设置一些基本的内容、比如一些参数或者是一些固定的对象等等。

二者的联系:都是通过后台守护进程捕获某一事件的发生。

参考技术B 你说的是服务器端的监听是吧。
listener.ora的文件中,有一个oracle_sid的字段,这个字段写的是oracle的sid,你和数据库的sid去对比,就知道监听的是哪一个数据库。
或者通过lsnrctl status能够调出监听状态,下面有四个监听正太,其中我忘了第几个,那个也是数据库的sid,跟数据库对比下,就知道了。
一本来说服务器监听的都是本机的数据库。 java监听器(Listener)和Servlet是两个不同功能的JavaWeb组件。
监听器是实现了javax.servlet.ServletContextListener这个接口的类,里面有两个方法需要你在子类实现:
public void contextDestroyed(ServletContextEvent evt)
//监听器被销毁的时候调用


public void contextInitialized(ServletContextEvent evt)
//监听启动的时候调用,初始化servletcontext事件


创建好后,配置到web.xml中即可。

对于Servlet自己没有监听器,只有当用户请求Servlet映射的路径时会触发Servlet对应的方法来处理,以此来响应客户的请求。

监听参数是用来初始化监听上下文使用的,不能被其他入口所调用。
<!--Spring ApplicationContext载入-->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- Spring ApplicationContext配置文件的路径,此参数用于后面的Spring-Contextloader -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:beans.xml</param-value>
</context-param>
<!-- 系统服务初始化 -->
<listener>
<listener-class>pams.servlet.SysInitServlet</listener-class>
</listener>

Java:Listener和Filter


本文内容:

 

  • Listener
  • Filter

 

首发日期:2018-07-15

 


Listener

 

  • 监听器Listener负责监听事件的发生。我们能在事件发生后执行一些自定义的操作,这就是监听器的意义。
  • 监听器的本质是接口回调

 

分类:

  • 监听域对象的创建:监听三个域(request,session,context)的创建和销毁 【这里不讨论这些域什么时候创建什么时候销毁,因为太基础了。】
  • 监听三个域的数据的创建:监听三个域的数据的添加、移除、替换
  • 监听一个javabean在session域的存值的变化:监听某个javabean在session域的值的存储、移除、钝化、活化

 

使用:

1.监听域对象的创建与销毁:

    1. 定义一个类,实现对应的接口(右图是监听不同域需要实现的接口)image。每一个接口主要有xxxInitialized函数和xxxDestroyed函数,xxxInitialized函数是当域对象创建的时候调用的,xxxDestroyed函数是当域对象销毁时调用的。
    2. 在web.xml中配置监听器image

 

image

 

2.监听三个域的数据的创建

    1. 定义一个类,实现对应的接口(右图是监听不同域需要实现的接口)image。每一个接口主要有attributeAdded函数、attributeReplaced函数和attributeRemoved函数,attributeAdded函数是当域对象中添加了属性的时候调用的,attributeReplaced函数是当域对象属性被替换的时候调用的,attributeRemoved函数是当域对象中属性被移除的时候调用的。
    2. 在web.xml中配置监听器image

image

 

3.监听一个javabean在session域的存值的变化【这些监听器不需要在web.xml中配置】【由于它要有javabean实现对应接口采用功能。但面对的对象是session,换了一个session后,并且这个session没有那种数据,那么是不会有响应的】

    1. 定义一个javabean,实现对应的接口image【对于钝化和活化还需要继承Serializable,使得能在硬盘中重新序列化到内存】
      1. 对于HttpSessionBindingListener接口,需要实现valueBound函数(当bean数据存储到session中时调用)和valueUnbound函数(当bean数据在session中移除时调用)
      2. 对于HttpSessionActivationListener接口,需要实现sessionDidActivate函数(当bean数据活化到内存时调用)和sessionWillPassivate函数(当bean数据钝化到硬盘时调用)。

题外话:什么是钝化和活化,以及怎么配置?

活化是指数据从硬盘到内存的过程;钝化是指数据从内存到硬盘的过程。

由于数据要使用,所以数据在内存中没有什么问题。但为什么需要钝化呢?这是因为内存是有限的,一些很久不用的数据不应该占用可贵的内存资源。

数据默认是内存中的,钝化需要进行配置(在tomcat里面 conf/context.xml 里面配置或在conf/Catalina/localhost/context.xml 配置或者在自己的web工程项目中的 META-INF/context.xml):【钝化的配置还有更多参数,这里不做详细讲解。有兴趣自查。】

<Context>
        <Manager className="org.apache.catalina.session.PersistentManager" maxIdleSwap="1" maxActiveSessions="1">
            <Store className="org.apache.catalina.session.FileStore" directory="session"/>
        </Manager>
</Context>

image

钝化已经配置好了,但如果想把数据重新取出来,bean必须实现Serializable.这样才能活化成功

 

 

 

实现HttpSessionBindingListener接口的例子:

package work.domain;

import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener;

public class User implements HttpSessionBindingListener  {
    private int age;
    private String name;
    private String gender;
    
    public User(int age, String name, String gender) {
        super();
        this.age = age;
        this.name = name;
        this.gender = gender;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    @Override
    public void valueBound(HttpSessionBindingEvent arg0) {
        System.out.println("bean数据被绑定了!");
    }

    @Override
    public void valueUnbound(HttpSessionBindingEvent arg0) {
        System.out.println("bean数据被解绑了");
        
    }

}

实现HttpSessionActivationListener接口的例子:

package work.domain;

import java.io.Serializable;

import javax.servlet.http.HttpSessionActivationListener;
import javax.servlet.http.HttpSessionEvent;

public class Person implements HttpSessionActivationListener,Serializable {
    private int age;
    private String name;
    private String gender;

    public Person(int age, String name, String gender) {
        super();
        this.age = age;
        this.name = name;
        this.gender = gender;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    @Override
    public void sessionDidActivate(HttpSessionEvent arg0) {
        System.out.println("数据被活化了!");
        
    }

    @Override
    public void sessionWillPassivate(HttpSessionEvent arg0) {
        System.out.println("数据被钝化了!");
    }

}

 

 

作用:

  • 由于监听器是在事件发生后才触发的,所以你可以自己考虑需要在事件触发后执行哪些动作。
  • 有些人会在context创建后,执行某些初始化操作。
  • 有人会用session的创建来统计在线人数。【不过我觉得可能使用redis的bit可能更节省】

 

 

 


Filter

 

  • Filter是过滤器的意思。
  • 过滤器可以对请求进行过滤,过滤器要比Servlet早处理请求,只有过滤器对请求放行,Servlet才可以去处理请求。
  • 由于过滤器可以预先处理请求,所以可以把一些任务交给过滤器来做,从而减少Servlet的处理消耗。
  • 过滤器可以做到一些比如“和谐”、请求非法拒绝服务、统一数据编码等功能。总的来说,过滤器的意义是提前处理。

 

 

使用:

1.定义一个类, 实现Filter接口(是servlet包中的Filter)

    • init函数负责一些过滤器的初始化工作
    • doFilter函数负责过滤工作,它有三个参数request,response, chain,request和response如你所想,它跟servlet中的没什么区别,chain可以理解成过滤链,它有一个doFilter函数,调用的时候传入request和response,代表你对这个请求放行了!如果你不想放行就不要调用它!
    • destroy函数是过滤器销毁的时候调用的。
package work.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;

public class MyFilter implements Filter {
    @Override
    public void destroy() {
    }
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        System.out.println("证明一下,你经过了过滤器!");
        chain.doFilter(request, response);//这一步是放行!
    }
    @Override
    public void init(FilterConfig arg0) throws ServletException {
        // TODO Auto-generated method stub
        
    }

}

2.在web.xml中配置过滤器:基本上与servlet的配置没什么区别,url-pattern也是一样的用法。

image

 

 

使用注意:

  1. 多个过滤器的通过顺序取决于web.xml中配置的过滤器的mapping的顺序
  2. 在多个过滤器过滤过程中,只要有一个不通过,那么后面的就不会再继续了。
  3. 过滤器会在服务端启动的时候就创建,会在服务端关闭时销毁。
  4. web.xml中的filter-mapping中可以配置一个属性dispatcher,它的值可以为REQUEST ,FORWARD,ERROR ,INCLUDE
    • 这些值的意义是:REQUEST 代表只要是请求就过滤;FORWARD代表过滤所有请求转向;ERROR代表过滤所有页面错误时的跳转;INCLUDE代表包含页面时就过滤。

 

 

 

小例子:

利用过滤器来统一请求数据的编码:

1.一般来说,对于post请求中的中文数据问题,可以使用request.setCharacterEncoding来解决,但如果每一个请求交给一个servlet来处理的话,就会在很多个servlet中加上这一个重复多次的代码(当然实际使用中,不会有那么多servlet,会利用一些手段将多个功能汇集到一个servlet中)

image

image

2.所以为了处理n多个请求的编码问题(这里只演示一个),可以使用过滤器来统一处理。

package work.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;
import javax.servlet.http.HttpServletResponse;

public class MyFilter implements Filter {

    @Override
    public void destroy() {
        
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        HttpServletRequest req=(HttpServletRequest)request;
        HttpServletResponse resp=(HttpServletResponse)response;
        String method = req.getMethod();
        if("POST".equals(method)) {
            request.setCharacterEncoding("utf-8");
            chain.doFilter(req, resp);//这一步是放行!
        }
        //简单演示起见,不对get处理,tomcat8已经不需要了        
    }
    

    @Override
    public void init(FilterConfig arg0) throws ServletException {
        // TODO Auto-generated method stub
        
    }



}

 

 

 

 


以上是关于oracle的监听器listener 和 java web的监听器listener 的联系是啥?的主要内容,如果未能解决你的问题,请参考以下文章

Oracle数据库学习_Oracle监听程序LISTENER和网络服务名Tnsname

Oracle11g监听器日志 listener.log文件过大处理

oracle数据库中有2个实例,监听怎么配置

设置 Oracle 监听器密码(LISTENER)

Oracle-清理监听日志文件 listener.log

oracle rac 监听日志在啥位置