Spring - 오늘 방문자 수

포테이토웅·2023년 5월 19일
0

개발 환경

  • Java8
  • 전자정부프레임워크 3.9
  • 10.4.27-MariaDB
  • MyBatis
  • CentOS Linux release 7.9.2009 (Core)

HttpSessionListener

JSP/Servlet 환경에서는 접속한 클라이언트에 대한 정보는 HttpSession 객체에 담아 표현한다. HttpSession 객체는 HTTP 요청 시 생성되었다가 응답 시 사라지는 ServletRequest 객체와는 다르게 JSP나 Servlet에 의해 생성된 후 설정된 timeout에 따라서 제거된다.

HttpSession 객체가 생성되고 제거될 때 발생되는 이벤트가 HttpSessionEvent이며, 이 이벤트를 처리하는 리스너가 HttpSessionListener이다.

리스너는 위와 같이 interface 형태로 API가 제공되므로 이 리스너를 구현하여 설정으로 등록해주면 된다. 서블릿 컨테이너는 HttpSessionEvent가 발생한 시점에 자신에게 등록된 HttpSessionListener 구현체가 있는지 확인하고, 등록된 리스너가 있으면 세션이 생성된 시점에 해당 리스너의 sessionCreated()를 세션이 제거되는 시점에 sessionDestroyed()를 호출한다.


요구사항

  • 당일 총 방문자의 수 표시
  • 추후 통계를 위해 DB에 날짜별로 저장

Service 및 VO

// VisitCountService
public interface VisitCountService {

    void insertVisitCount();

    void updateVisitCount();

    VisitCountVO selectVisitCount();
}
// VisitCountDAO
@Repository("visitCountDAO")
public class VisitCountDAO extends EgovComAbstractDAO {

    public void insertVisitCount() {
        insert("visitCountMapper.insertVisitCount");
    }

    public void updateVisitCount() {
        update("visitCountMapper.updateVisitCount");
    }

    public VisitCountVO selectVisitCount() {
        return selectOne("visitCountMapper.selectVisitCount");
    }
}
// VisitCountServiceImpl
@Service("visitCountService")
public class VisitCountServiceImpl extends EgovAbstractServiceImpl implements VisitCountService {

    @Resource(name = "visitCountDAO")
    private VisitCountDAO visitCountDAO;

    @Override
    public void insertVisitCount() {
        visitCountDAO.insertVisitCount();
    }

    @Override
    public void updateVisitCount() {
        visitCountDAO.updateVisitCount();
    }

    @Override
    public VisitCountVO selectVisitCount() {
        return visitCountDAO.selectVisitCount();
    }
}
// VisitCountVO
public class VisitCountVO {

    private String regDate;

    private int visitCount;

    public String getRegDate() {
        return regDate;
    }

    public int getVisitCount() {
        return visitCount;
    }

    public void setRegDate(String regDate) {
        this.regDate = regDate;
    }

    public void setVisitCount(int visitCount) {
        this.visitCount = visitCount;
    }

    @Override
    public String toString() {
        return "VisitCountVO{" +
                "regDate='" + regDate + '\'' +
                ", visitCount=" + visitCount +
                '}';
    }
}
// VisitCount_SQL_maria.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="visitCountMapper">

    <insert id="insertVisitCount">
       INSERT INTO SPW_VISIT_COUNT
            (REG_DATE, VISIT_COUNT)
       VALUES
           (NOW(), 1);
    </insert>

    <update id="updateVisitCount">
        UPDATE
            SPW_VISIT_COUNT
        SET
            VISIT_COUNT = SPW_VISIT_COUNT.VISIT_COUNT + 1
        WHERE
            REG_DATE = DATE_FORMAT(NOW(), '%Y-%m-%d')
    </update>

    <select id="selectVisitCount" resultType="VisitCountVO">
        SELECT
            REG_DATE, VISIT_COUNT
        FROM
            SPW_VISIT_COUNT
        where
            REG_DATE = DATE_FORMAT(NOW(), '%Y-%m-%d')
    </select>
</mapper>

DB에 접속 정보를 저장하기 위한 서비스 및 VO이다.


Listener 등록

public class HttpSessionListener implements javax.servlet.http.HttpSessionListener {


    private static int todayVisitCount;

    public static int getTodayVisitCount() {
        return todayVisitCount;
    }

    public static void setTodayVisitCount(int count) {
        todayVisitCount = count;
    }

    @Override
    public void sessionCreated(HttpSessionEvent se) {
        HttpSession session = se.getSession();
        WebApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(session.getServletContext());
        VisitCountService visitCountService = ctx.getBean("visitCountService", VisitCountService.class);
        if(session.isNew()){
            VisitCountVO visitCountVO = visitCountService.selectVisitCount();
            if(visitCountVO == null) {
                visitCountService.insertVisitCount();
                setTodayVisitCount(1);
            } else {
                visitCountService.updateVisitCount();
                setTodayVisitCount(visitCountVO.getVisitCount() + 1);
            }
        }

    }

    @Override
    public void sessionDestroyed(HttpSessionEvent se) {
    }
}

세션이 생성되는 시점에, 금일 날짜에 해당하는 접속 기록이 있으면 VisitCount를 1 증가시키고, 없으면 VisitCount를 등록하는 로직이다.

// web.xml
  <listener>
    <listener-class>breeze.marketing.service.HttpSessionListener</listener-class>
  </listener>

web.xml에 위와 같이 listener를 등록해주면 사용 가능하다.

@WebListener
public class HttpSessionListener implements javax.servlet.http.HttpSessionListener {
...

Servlet 3.0 버전 이상이면 위와 같이 @WebListener 어노테이션을 붙여주는 방법도 있다.


사용자 페이지

...
<p class="today">TODAY : <span class="num"><%= HttpSessionListener.getTodayVisitCount()%></span></p>
...

static 메소드를 불러와 사용이 가능하다.


참고자료

profile
주경야독

0개의 댓글