[Web] 서블릿의 필터와 리스너 기능

kiwonkim·2021년 5월 29일
0
post-thumbnail

서블릿 속성

ServletContext, HttpSession, HttpRequest 객체에 바인딩하여 활용하는 정보.

ServletContext

ServletContext에 바인딩 된 속성은 웹 어플리케이션 전체에서 접근 가능

HttpSession

HttpSession에 바인딩 된 속성은 해당 브라우저에서만 접근가능
(해당 브라우저만 getSession을 통해 이 세션을 가져올 수 있기 때문에)

HttpRequest

HttpRequest에 바인딩 된 속성은 해당 요청/응답 사이클에서만 사용가능
(Stateless 하므로 한 사이클 끝나면 기억못함)

즉 dispatch로 포워드 하지 않고서는 타 서블릿에서 HttpRequest 바인딩 정보 사용 불가능
다른 브라우저 사용시 별도의 세션이므로 HttpSession 바인딩 정보 사용 불가능(크롬, 익스플로러)

서블릿 URL패턴 응용

URL패턴이란 : 서블릿 매핑시 활용시 되는 매핑이름

URL 패턴에 디렉토리나 * 사용 가능

@WebServlet("/first/test") : 정확히 url에 /first/test 입력해야 해당 서블릿 실행
@WebServlet("/first/*") : 디렉토리 이름만 일치하면 실행
@WebServlet("*.do") : 확장자 일치하면 실행


필터

  • Request나 Response에 미리 선작업 취해주기 위한 것
  • Request나 Response마다 항상 공통된 처리를 수행할때 필터를 활용 (인코딩 등)
  • 사용자 정의 필터는 Filter 인터페이스 구현을 통해 생성.

필터 생명주기

init()
doFilter()
destroy()

기능은 doFilter의 오버라이딩을 통해 구현

필터 적용 범위

애너테이션 @WebFilter("/URL패턴명") 을 통해 어느 서블릿과의 request, response에서 필터를 통과시킬지 결정.
@WebFilter("/*") 이면 모든 서블릿에 대해 필터링 수행.

Request와 Response 필터 구분

chain.doFilter(request, response)를 경계로
위는 request에 적용시킬 필터
아래는 response에 적용할 필터

@WebFilter("/*")
public class EncoderFilter implements Filter {

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws ServletException, IOException {
        System.out.println("doFilter 호출");
        request.setCharacterEncoding("utf-8"); // 모든 request에 CharacterEncoding 추가.
        long begin = System.currentTimeMillis();
        
        chain.doFilter(request, response); /*이 아래는 response에 대한 필터*/
        long end = System.currentTimeMillis();
        System.out.println("작업 시간:" + (end - begin) + "ms"); 
    }
}

리스너

  • 서블릿에서 특정 이벤트 발생시 처리해주는 것

Listenter 인터페이스 종류

ServletContextAttributeListner : Context 객체에 속성 추가/제거/수정 시 처리

HttpSessionAttributeListner : Session 객체에 속성 추가/제거/수정 시 처리

ServletRequestAttributeListner : Request 객체에 속성 추가/제거/수정 시 처리

HttpSessionBindingListener : Session 객체에 바인딩/언바인딩 시 처리

HttpContextListener : Context 객체 생성/소멸 시 처리

HttpSessionListner : Session 객체의 생성/소멸 시 처리

ServletRequestListner : Request 발생시 처리

목적에 따라 상기 인터페이스들의 추상메서드 구현을 통해 기능 설정.

로그인 유저 수 확인 리스너

HttpSerssionListner 인터페이스 구현을 통해 Session 생성시 count 증가. Session 삭제시 count 감소하여 구현.

Context에 ArrayList 바인딩 해놓음.
Session이 새로된 것이라면 ID를 ArrayList에 추가 후 다시 바인딩.
Context ArrayList에는 전체 로그인 중인 ID 저장되어 있음.
Session 삭제 시 ArrayList에서 해당 원소 삭제.

@WebListener
public class LoginImpl implements HttpSessionListener { //Session 생성 제거시 수행.
    String user_id;
    String user_pw;
    static int total_user = 0;

    public LoginImpl() {
    }

    public LoginImpl(String user_id, String user_pw) {
        this.user_id = user_id;
        this.user_pw = user_pw;
    }

    @Override
    public void sessionCreated(HttpSessionEvent arg0) { //추상메서드 구현. Session 생성시
        System.out.println("사용자 접속");
        ++total_user; //count 증가
    }

    @Override
    public void sessionDestroyed(HttpSessionEvent arg0) { //Session 삭제시
        System.out.println("사용자 접속 해제");
        --total_user; //count감소
    }

}
@WebServlet("/login")
public class LoginTest extends HttpServlet {
    ServletContext context = null;
    List user_list = new ArrayList();

    protected void doPost(HttpServletRequest request, HttpServletResponse response) 
    	throws ServletException, IOException {
        request.setCharacterEncoding("utf-8");
        response.setContentType("text/html;charset=utf-8");
        context = getServletContext();
        PrintWriter out = response.getWriter();
        HttpSession session = request.getSession();
        String user_id = request.getParameter("user_id");
        String user_pw = request.getParameter("user_pw");
        LoginImpl loginUser = new LoginImpl(user_id, user_pw); //로그인 시 count는 자동 증가. 리스트 추가위해 객체 생성.
        if (session.isNew()) { //최초 로그인시 ID를 ArrayList에 저장 후 context 객체에 있는 AraryList 갱신
            session.setAttribute("loginUser", loginUser);
            user_list.add(user_id);
            context.setAttribute("user_list", user_list);
        }

        out.println("<html><body>");
        out.println("아이디는 " + loginUser.user_id + "<br>"); 
        out.println("총 접속자수는" + LoginImpl.total_user + "<br><br>");
        //LoginImpl 객체의 count 변수
        
        out.println("접속 아이디:<br>");
        List list = (ArrayList) context.getAttribute("user_list"); //전체 접속자는 context에 바인딩 시켰놓았음.
        for (int i = 0; i < list.size(); i++) {
            out.println(list.get(i) + "<br>");
        }
        out.println("</body></html>");
    }

}

0개의 댓글

관련 채용 정보