책 요약 (도서)/자바 웹 개발 워크북

3-3. 리스너(Listener)

기매_ 2022. 12. 7. 16:11

리스너 객체 : 이벤트(Event)라는 특정한 데이터가 발생하면 자동으로 실행됨

장점 : 리스너를 이용하면 어떤 정보가 발생(이벤트(event))했을 때 미리 약속해둔 동작을 수행할 수 있으므로 기존의 코드를 변경하지 않고도 추가적인 기능을 수행할 수 있음 !

(스프링 MVC가 리스너를 통해서 동작함)


옵저버(observer) 패턴

 : 특정한 변화를 구독(subscribe)하는 객체들을 보관하고 있다가 변화가 발생(발행(publish))하면 구독 객체들을 실행하는 방식

 

ex. 재난 감시 시스템

1. 이벤트(Event) : (지진이 발생하여) 지진 감지 센서가 데이터를 발생

 -> 데이터가 발생되면 해당 이벤트 관제 센터에 통보 -> 관제 센터에서는 산하 기관들에 '지진이 발생했음'을 알려줌

2. 마지막 산하 기관들 = 이벤트 리스너


서블릿 API : 여러 이벤트(Event)에 맞는 리스너들을 인터페이스들로 정의해둠

이를 이용해서 처리할 수 있는 작업 예)

1. 해당 웹 애플리케이션이 시작되거나 종료될 때 특정한 작업을 수행 (ServletContextListener)

2. HttpSession에 특정한 작업에 대한 감시와 처리 (HttpSessionListener / HttpSessionAttributeListener 등)

3. HttpServletRequest에 특정한 작업에 대한 감시와 처리

 

 

ServletContextListener 

1. 해당 웹 애플리케이션이 시작되거나 종료될 때 특정한 작업을 수행 (ServletContextListener)

(1) implements  ServletContextListener (ServletContextListener  인터페이스 구현)

(2) @WebListener 어노테이션 추가

(3) 메서드 Override 해서 원하는 코드 작성

      (contextInitialized() 는 프로그램 시작할 때 = 톰캣 시작 시,

       contextDestroyed() 는 프로그램 종료될 때 실행됨 = 톰캣 종료 시)

package org.zerock.w2.listener;

import lombok.extern.log4j.Log4j2;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;

@WebListener
@Log4j2
public class W2AppListener implements ServletContextListener {

    @Override
    public void contextInitialized(ServletContextEvent sce) {
        log.info("--------- init ---------");
        log.info("--------- init ---------");
        log.info("--------- init ---------");
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        log.info("--------- destroy ---------");
        log.info("--------- destroy ---------");
        log.info("--------- destroy ---------");
    }
}

ServletContextEvent와 ServletContext

1. contextInitialized() contextDestroyed()에 파라미터로 ServletContextEvent 객체가 전달됨

2. ServletContextEvent를 이용하면 ServletContext에 접근할 수 있음

3. ServletContext : 현재 애플리케이션이 실행되는 공간으로, 현재의 웹 애플리케이션 내 모든 자원들을 같이 사용하는 공간이므로 이 공간에 무언가를 저장하면 모든 컨트롤러나 JSP 등에서 이를 활용할 수 있게됨 !

4. ServletContext 에는 setAttribute()로 원하는 이름으로 객체를 보관할 수 있음 (ServletContext를 이용해서 저장된 객체는 서블릿 JSP/EL에 공유해서 사용할 수 있음)

 

 

package org.zerock.w2.listener;

import lombok.extern.log4j.Log4j2;

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;

@WebListener
@Log4j2
public class W2AppListener implements ServletContextListener {

    @Override
    public void contextInitialized(ServletContextEvent sce) {
        log.info("--------- init ---------");
        log.info("--------- init ---------");
        log.info("--------- init ---------");

	// 추가된 코드 !!
        ServletContext servletContext = sce.getServletContext();
        servletContext.setAttribute("appName", "W2");
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        log.info("--------- destroy ---------");
        log.info("--------- destroy ---------");
        log.info("--------- destroy ---------");
    }
}

 

JSP / EL

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
    <title>Test</title>
</head>
<body>
<h1>ServletContext Test</h1>
<h2>ServletContext에 저장되어 있는 appName : ${appName}</h2>

</body>
</html>

 

ServletContextListener와 스프링 프레임워크

ServletContextListener와 ServletContext를 이용하면, 프로젝트가 실행될 때 필요한 객체들을 준비하는 작업을 처리할 수 있음. (ex. 커넥션 풀 초기화, TodoService와 같은 객체들을 미리 생성해서 보관 등)

- 스프링 프레임워크를 웹 프로젝트에서 미리 로딩하는 작업을 처리할 때, ServletContextListener 를 이용함


세션 관리 리스너 : HttpSession 관련 작업을 감시하는 리스너

2. HttpSession에 특정한 작업에 대한 감시와 처리 (HttpSessionListener / HttpSessionAttributeListener)

 

HttpSessionListener / HttpSessionAttributeListener

 : HttpSession이 생성되거나 setAttribute() 등의 작업이 이루어질 때 이를 감지할 수 있음 !

 

(1) implements  HttpSessionAttributeListener (HttpSessionAttributeListener 인터페이스 구현)

(2) @WebListener 어노테이션 추가

(3) 메서드 Override 해서 원하는 코드 작성

 attributeAdded() : HttpSession에 setAttribute() 작업을 감지 (추가될 때 호출)

 attributeRemoved() : HttpSession에 removeAttribute() 작업을 감지 (제거될 때 호출)

 attributeReplaced() : 이미 존재하고 있는 세션 속성이 HttpSession.setAttribute()를 통해 새로운 값으로 대체될 때 호출

 

package org.zerock.w2.listener;

import lombok.extern.log4j.Log4j2;

import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionBindingEvent;

@WebListener
@Log4j2
public class LoginListener implements HttpSessionAttributeListener {

    @Override
    public void attributeAdded(HttpSessionBindingEvent event) {
        String name = event.getName();
        Object obj = event.getValue();

        if (name.equals("loginInfo")) {
            log.info("A user logined...");
            log.info("obj는 " + obj);
        }
    }
}

 

참고)

LoginController 에서 로그인 성공 시 세션에 아래와 같이 저장해둠 !

HttpSession session = req.getSession();
session.setAttribute("loginInfo", memberDTO);

'책 요약 (도서) > 자바 웹 개발 워크북' 카테고리의 다른 글

2-3. 웹 MVC와 JDBC의 결합  (0) 2022.11.23
2-2. 프로젝트 내 JDBC 구현  (0) 2022.11.23
1-5. 모델(Model)  (0) 2022.11.22
1-4. HttpServlet  (0) 2022.11.21
1-3. Web MVC 방식  (0) 2022.11.21