[필독][기초] / 서블릿 / servlet [part 6]

2016. 1. 5. 15:00language/jsp

리슨너
리슨너는 웹 애플리케이션의 이벤트에 실행된다.
웹 애플리케이션 이벤트는 서블릿 스펙 2.3 이후 등장했다.
웹 애플리케이션 이벤트는 다음과 같이 나뉜다.

•애플리케이션 스타트업과 셧다운
•세션 생성 및 세션 무효


애플리케이션 스타트업 이벤트는 톰캣과 같은 서블릿 컨테이너에 의해 웹 애플리케이션이 처음 로드되어 스타트될 때 발생한다.
애플리케이션 셧다운 이벤트는 웹 애플리케이션이 셧다운될 때 발생한다.


세션 생성 이벤트는 새로운 세션이 생성될 때 발생한다.
세션 무효 이벤트는 세션이 무효화 될때 매번 발생한다.


이벤트를 이용하기 위해서는 리슨너라는 클래스를 작성해야 한다.
리슨너 클래스는 순수 자바 클래스로 다음의 인터페이스를 구현한다.

•javax.servlet.ServletContextListener
•javax.servlet.http.HttpSessionListener


애플리케이션 스타트업 또는 셧다운 이벤트를 위한 리슨너를 원한다면 ServletContextListener 인터페이스를 구현한다.
세션 생성 및 세션 무효 이벤트를 위한 리슨너를 원한다면 HttpSessionListener 인터페이스를 구현한다.

ServletContextListener 인터페이스는 다음 2개의 메소드로 구성되어 있다.

•public void contextInitialized(ServletContextEvent sce);
•public void contextDestroyed(ServletContextEvent sce);


 HttpSessionListener 인터페이스는 다음 2개의 메소드로 구성되어 있다.

•public void sessionCreated(HttpSessionEvent se);
•public void sessionDestroyed(HttpSessionEvent se);


다음은 애플리케이션 스타트업과 셧다운 이벤트를 이용하는 예제이다.
우리의 웹 애플리케이션이 스타트업되면 OracleConnectionManager 객체를 생성하여 ServletContext 에 저장하기 위해 아래와 같은 클래스를 작성한다.


MyServletContextListener.java


package net.java_school.listener;

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

import net.java_school.db.dbpool.OracleConnectionManager;

public class MyServletContextListener implements ServletContextListener {

          @Override
          public void contextInitialized(ServletContextEvent sce) {
                    ServletContext sc = sce.getServletContext();
                    OracleConnectionManager dbMgr = new OracleConnectionManager();
                    sc.setAttribute("dbMgr", dbMgr);
          }

          @Override
          public void contextDestroyed(ServletContextEvent sce) {
                    ServletContext sc = sce.getServletContext();
                    sc.removeAttribute("dbMgr");
          }

}


이 클래스가 제 기능을 다하도록 하려면 web.xml 에 아래를 web-app 엘리먼트의 자식 엘리먼트로 추가한다.
이때 다음 http://java.sun.com/dtd/web-app_2_3.dtd 를 참고하여 엘리먼트의 순서에 맞게 추가해야 한다.
context-param 보다는 아래에 servlet 보다는 위에 추가해야 함을 알 수 있다.


<!ELEMENT web-app (icon?, display-name?, description?, distributable?, context-param*, filter*, filter-mapping*, listener*, servlet*, servlet-mapping*, session-config?, mime-mapping*, welcome-file-list?, error-page*, taglib*, resource-env-ref*, resource-ref*, security-constraint*, login-config?, security-role*, env-entry*, ejb-ref*, ejb-local-ref*)>


web.xml


<listener>
    <listener-class>net.java_school.listener.MyServletContextListener</listener-class>
</listener>


JDBC 메뉴의 ConnectionPool 소스를 WEB-INF/src 에 추가한다.
net.java_school.util.Log.java 파일에서 다음 부분을 수정한다.
public String dbgFile = "C:/www/myapp/WEB-INF/debug.txt";
 orcale.properties 파일은 WEB-INF 폴더에 위치시킨다.
ConnectionManager.java 파일에서 다음 부분을 수정한다.
configFile = "C:/www/myapp/WEB-INF/"+poolName+".properties";
이제 우리의 웹 애플리케이션이 시작될 때 OracleConnectionManager 객체를 생성되고 그 레퍼런스가 ServletContext 에 저장될 것이다.
테스트를 위해 GetEmpServlet.java 파일을 아래와 같이 수정한다.


GetEmpServlet.java


package example;

import java.sql.*;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

import net.java_school.db.dbpool.*;

public class GetEmpServlet extends HttpServlet {

          private OracleConnectionManager dbMgr;
         
          @Override
          public void init() throws ServletException {
                    ServletContext sc = getServletContext();
                    dbMgr = (OracleConnectionManager) sc.getAttribute("dbMgr");
          }
         
          @Override
          public void doGet(HttpServletRequest req, HttpServletResponse resp)
                              throws IOException, ServletException {
                             
                    resp.setContentType("text/html; charset=UTF-8");
                    PrintWriter out = resp.getWriter();
                   
                    Connection con = null;
                    PreparedStatement stmt = null;
                    ResultSet rs = null;
                   
                    String sql = "SELECT * FROM emp";
                   
                    try {
                              con = dbMgr.getConnection();
                              stmt = con.prepareStatement(sql);
                              rs = stmt.executeQuery();
                             
                              while (rs.next()) {
                                        String empno = rs.getString(1);
                                        String ename = rs.getString(2);
                                        String job = rs.getString(3);
                                        String mgr = rs.getString(4);
                                        String hiredate = rs.getString(5);
                                        String sal = rs.getString(6);
                                        String comm = rs.getString(7);
                                        String depno = rs.getString(8);
                                       
                                        out.println( empno + " : " + ename + " : " + job + " : " + mgr +
                                                  " : " + hiredate + " : " + sal + " : " + comm+" : " + depno + "<br>" );
                              }
                    } catch (SQLException e) {
                              e.printStackTrace(out);
                    } finally {
                              if (rs != null) {
                                        try {
                                                  rs.close();
                                        } catch (SQLException e) {
                                                  e.printStackTrace();
                                        }
                              }
                              if (stmt != null) {
                                        try {
                                                  stmt.close();
                                        } catch (SQLException e) {
                                                  e.printStackTrace();
                                        }
                              }
                              if (con != null) {
                                        try {
                                                  con.close();
                                        } catch (SQLException e) {
                                                  e.printStackTrace();
                                        }
                              }
                    }
         
          }
         
}


GetEmpServlet를 컴파일하고 톰캣을 재가동 후 http://localhost:8989/empList를 방문한다.
 (GetEmpServlet 서블릿에 대한 선언과 매핑은 이미 이전 예제 테스트에서 설정했다.)


다음은 HttpSessionListener 에 대한 설명과 예제이다.
HttpSessionListener 인터페이스 역시 2개의 메소드로 구성되어 있는데 하나는 세션 생성되는 이벤트와 세션이 무효화 되는 이벤트를 위한 것이다.

•public void sessionCreated(HttpSessionEvent se);
•public void sessionDestroyed(HttpSessionEvent se);


SessionCounterListener.java


package net.java_school.listener;

import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;

public class SessionCounterListener implements HttpSessionListener {
          public static int totalCount;
         
          @Override
          public void sessionCreated(HttpSessionEvent event) {
                    totalCount++;
                    System.out.println("세션증가 총세션수:" + totalCount);
          }

          @Override
          public void sessionDestroyed(HttpSessionEvent event) {
                    totalCount--;
                    System.out.println("세션감수 총세션수:" + totalCount);
          }

}


web.xml 에 다음을 추가한다.


<listener>
    <listener-class>net.java_school.listener.SessionCounterListener</listener-class>
</listener>


설정파일인 web.xml이 변경되었으므로 톰캣을 재실행한 후
http://localhost:8989/simple를 방문한다.
다른 웹브라우저로 http://localhost:8989/simple를 방문한다.
톰캣 로그 파일에서 로그 메시지를 확인한다.

 

 

참고
http://docs.oracle.com/javaee/7/api/index.html?overview-summary.html
http://www.mkyong.com/servlet/a-simple-httpsessionlistener-example-active-sessions-counter/
http://commons.apache.org/proper/commons-fileupload/download_fileupload.cgi
http://commons.apache.org/proper/commons-io/download_io.cgi
http://commons.apache.org/proper/commons-fileupload/using.html
http://www.albumbang.com/board/board_view.jsp?board_name=free&no=292
http://www.docjar.com/docs/api/javax/servlet/GenericServlet.html
http://www.java-school.net/jsp/Servlet

 

 

도움이 되셨다면 공감을 부탁드립니다. ^^