springboot servlet、filter、listener

阅读数:69 评论数:0

跳转到新版页面

分类

python/Java

正文

一、servlet

1、由来

(1)静态页面

早期的web应用主要用于浏览静态页面,比如Apache、Nginx向浏览器返回静态HTML,浏览器负责解析HTML,将结果呈现给用户。

为了达到一些交互操作,并动态获取结果,需要扩展,因些Sun推出了servlet技术。

(2)servlet容器

servlet没有main方法,不能独立运行,因此需要由窗口来实例化和调用。

(3)servlet接口

http服务怎么知道调用哪个servlet呢?为了避免与业务逻辑耦合,所以采用了面向接口编辑,这些接口就是servlet接口,有时我们也把实现servlet接口的业务类叫作servlet

2、实现方式

(1)直接实现servlet接口

(2)继承GenericServlet,这是一个抽象类

(3)继承HttpServlet,这个类是GenericServlet的子类

3、servlet生命周期

二、Filter

过滤器的执行由Servlet容器回调完成,是AOP思想的一个实践,用于过滤浏览器发出的请求,并且决定放行请求还是对中断请求做特殊处理。

1、使用方式

(1)@WebFilter

同时需要在启动类使用@ServletComponentScan,这会扫描带@WebFilter、@WebServlet、@WebListener。

@Slf4j
@Order(1)
@WebFilter(filterName = "myFilter", urlPatterns = {"/user/*"})
public class MyFilter implements Filter {

    @Autowired
    private SysUserService sysUserService;

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        log.info("过滤器初始化");
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        log.info("请求处理");
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        log.info("MyFilter, URL:{}", request.getRequestURI());
        if (request.getRequestURI().contains("login")) {
            filterChain.doFilter(servletRequest, servletResponse);
        } else {
            log.info("非法URL:{}", request.getRequestURI());
            response.setStatus(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
            PrintWriter writer = response.getWriter();
            writer.print("no access");
        }
    }

    @Override
    public void destroy() {
        log.info("过滤器销毁");
    }
}

三、Listener

事件监听机制可以理解为一种观察者模式,它是Servlet容器为Servlet提供的扩展点,用于对特定对象的生命周期和特定事件进行响应处理。

在Java中,事件对象都是继承java.util.EventObject对象,事件监听器都是java.util.EventListener实例。EventObject没有默认构造函数,需要外部传递source参数,用于记录并跟踪事件的来源。

1、spring事件监听

(1)面向接口编程,实现ApplicationListener接口

(2)基于注解,@EventListener(Spring自定义的注解)

2、springboot事件监听

(1)监听Servlet上下文

监听类需要实现ApplicationListener接口,并实现onApplicationEvent方法(在容器初始化完成之后执行),参数是ContextRefreshEvent(上下文刷新事件)。

package com.ieslab.powergrid.demosvr.utils;

import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Component;

@Component
public class MyServletContextListener implements ApplicationListener<ContextRefreshedEvent> {

    @Override
    public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) {
        System.out.println("Spring容器加载完成触发,可用于初始化环境,准备测试数据、加载一些数据到内存");
        //此处可以开启一个线程,用于查询首页数据,并缓存在内容中,供所有的首页进行查询
        //代码省略
    }
}

(2)监听HTTP会话Session对象

监听类需要实现HttpSessionListener接口,然后重写sessionCreated方法和sessionDestroyed销毁方法。

package com.ieslab.powergrid.demosvr.utils;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;

@Component
@Slf4j
public class MyHttpSessionListener implements HttpSessionListener {
    public static Integer count = 0;   //记录在线的用户数量

    @Override
    public synchronized void sessionCreated(HttpSessionEvent httpSessionEvent) {
        log.info("新用户上线了");
        count++;
        httpSessionEvent.getSession().getServletContext().setAttribute("count", count);
    }

    @Override
    public synchronized void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
        log.info("用户下线了");
        count--;
        httpSessionEvent.getSession().getServletContext().setAttribute("count", count);
    }
}

(3)监听Servlet Request对象

package com.ieslab.powergrid.demosvr.utils;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
import javax.servlet.http.HttpServletRequest;

@Component
@Slf4j
public class MyServletRequestListener implements ServletRequestListener {
    @Override
    public void requestInitialized(ServletRequestEvent servletRequestEvent) {
        HttpServletRequest request = (HttpServletRequest) servletRequestEvent.getServletRequest();
        log.info("session id为:{}", request.getRequestedSessionId());
        log.info("request url为:{}", request.getRequestURL());
        request.setAttribute("name", "斌哥");
    }

    @Override
    public void requestDestroyed(ServletRequestEvent servletRequestEvent) {
        log.info("request end");
        HttpServletRequest request = (HttpServletRequest) servletRequestEvent.getServletRequest();
        log.info("request域中保存的name值为:{}", request.getAttribute("name"));

    }
}

3、springboot自定义监听器

(1)自定义事件

package com.ieslab.powergrid.demosvr.entity;

import org.springframework.context.ApplicationEvent;

public class TestEvent extends ApplicationEvent {
    private Person person;

    public TestEvent(Object source, Person person) {
        super(source);
        this.person = person;
    }

    public Person getPerson() {
        return person;
    }

    public void setPerson(Person person) {
        this.person = person;
    }
}

(2)自定义监听器

package com.ieslab.powergrid.demosvr.utils;

import com.ieslab.powergrid.demosvr.entity.Person;
import com.ieslab.powergrid.demosvr.entity.TestEvent;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;

@Component
@Slf4j
public class TestEventListener implements ApplicationListener<TestEvent> {
    @Override
    public void onApplicationEvent(TestEvent testEvent) {
        // 把事件中的信息获取到
        Person person = testEvent.getPerson();
        // 处理事件,实际项目中可以通知别的微服务或者处理其他逻辑等
        log.info("用户名:" + person.getFirstName());
        log.info("城市:" + person.getCity());
    }
}

(3)测试

package com.ieslab.powergrid.demosvr.service;

import com.ieslab.powergrid.demosvr.entity.Person;
import com.ieslab.powergrid.demosvr.entity.TestEvent;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;

//发布事件触发器
@Service
@Slf4j
public class TestService {
    @Resource
    private ApplicationContext applicationContext;

    /**
     * 发布事件
     * @return
     */
    public Person getPerson() {
        Person person = new Person("", "斌哥","","济南");
        // 发布事件
        TestEvent event = new TestEvent(this, person);
        applicationContext.publishEvent(event);
        log.info("触发器被触发");
        return person;
    }
}




相关推荐

一、概述 ApplicationContext事件机制是观察者设计模式的实现,通过ApplicationEvent类和ApplicationListener接口,可以实现ApplicationCont

java.io.FilenameFilter是文件名过滤器,用来过滤不符合规格的文件名,并返回合格的文件; 一般地: (1)String[] fs = f.list(

afka在有新消费者加入或者撤出时,会触发rebalance操作,在subscribe订阅主题的时候,我们可以编写回掉函数,在触发rebalance操作之前和之后,提交相应偏移量和获取偏移量。<

BloomFilter主要用于检索一个元素是否在集合中,优点是空间效率和查询效率比较高。缺点是存在误差率。 由上图我们可以看出,此时A、B、C、D四个数据各自经过f1和f2方法进行两次hash算法,

在Tomcat目录下的conf/web.xml文件里面,找到&ldquo;&lt;session-config&gt;&rdquo

一、概述 1、spring容器 spring中有三种bean容器:BeanFactory、ApplicationContext、WebApplicationContext。 (1)BeanFactor

一、概述 如果没有终端操作,中间操作是不会得到执行的(惰性求值)。 stream的使用可以将代码中大量的for循环变为简单的链式函数操作,但是需要注意性能,在数据量小的情况下二都相差不多,但是在数据

一、简介 如果需要人工执行的任务,就需要用到用户任务建模。 二、常用配置 1、执行人Assignments (1)执行人类型: Assignee 代理执行人,一般一个用户。 Candidat

一、简介 当把一个事件发布到Spring提供的ApplicationContext中,被监听器侦测到,就会执行对理原处理方法。 ApplicationContext继承了ApplicationEve

一、@ComponentScan注解 @Component只写入value,可扫描路径下装配的@Controller、@Service、@Repository。 1、常用属性 basePacka