Servlet_Filter & Listener
Filter & Listener : Servlet을 상속받는 NOT POJO 클래스
Filter는 클라이언트의 요청을 가장 먼저 받아 사전에 처리하는 역할을 하고,
Listener는 웹 컨테이너에서 발생하는 이벤트를 감지하고 처리함
Filter와 Listener를 사용하면 JSP와 Servlet 같은 동적 자원에서 개별적으로 처리해야 하던 업무를 일괄 처리 가능
Filter
- 요청 정보에 특정한 처리를 미리 적용(전처리)하거나 응답 내용을 변경or취소(후처리) 가능
- 클라이언트 요청 → Filter → 웹서버
- 웹서버 응답 → Filter → 클라이언트
메서드명 | 설명 |
*-기본생성자 | |
init() | 필터를 초기화할 때 호출 (처음 실행될때 1번 수행_connect()) |
doFilter() | 필터를 리소스에 적용할 때마다 호출 |
destroy() | 필터가 소멸될 때 호출 (메모리 해제될때 1번 수행_disconnect) |
ex) 한글 인코딩 문제 해결
인코딩 설정 분리함으로써, 인코딩 필터를 만들면 여기만 바꾸면됨. 결합도 낮, 응집도 높, 유지보수 용이! ★★★
Add Filter Mapping - URL pattern
어떤 URL 요청에 대해 해당 필터를 호출할지 추가
꼼꼼한 인코딩을 위해 요청받고 응답할때 모두 추가
*.do : 요청받을 때
*.jsp : 응답전달할 때
mapping두개해서 @WebFilter({중괄호 생김})
EncodingFilter.java
#1 @WebFilter({})
Servlet @어노테이션으로 new
해당 설정 덕분에 서블릿 컨테이너(현재톰캣)가 싱글톤 유지 + 제때 메서드 수행시켜줌
컨테이너의 역할 == 객체를 생성(new를 대신해줌) & 관리(싱글톤 유지) & 수행(.메서드() 해줌)✨✨
#2 chain.doFilter(request, response)
다음 필터가 존재한다면, 그곳으로 이동해라
더이상 수행할 필터가 없다면, 원래 수행하던 요청으로 돌아가라
#3 if(request.getCharacterEncoding() == null)
.do, .jsp 올때마다 메서드가 수행돼서, 설정이 안돼있을때만 메서드 실행
request를 설정했다면 String("UTF-8")이 반환됨, 그래서 설정안돼있으면 null임
#4 request.setCharacterEncodint("UTF-8")
로직 부분에 값 "UTF-8"이 하드코딩 되면 안됨 → 하드코딩은 유지보수 용이성을 망가뜨림
로직 부분에서 하드코딩을 제거해 멤버변수로 선언
자바는 멤버변수 초기화를 생성자에서 하지만, Filter는 init()에서 제공해줌
init() : 최초에 단한번 실행되는 메서드(유사 생성자)에 UTF-8로 초기화
생성자: 외부 설정값 받아올 수 없음
init(): 외부 설정값 받아올 수 있음
#5 this.encoding = fConfig.getServletContext().getInitParameter("encoding")
근데 여기서 다른 문자로 바꾸면 컴파일을 다시해야함 (== 서버를 OFF → ON 해야함) → 결국 이것도 하드코딩
서블릿 설정파일은 웹 .xml이라고함, 서블릿 컨테이너에게 설정사항을 알려주는 파일 == web.xml
WEB-INF 하위에 설정파일 생성 → XML File (파일 이름은 web.xml로 맞추기 - 톰캣이 이 이름가진 파일을 참고)
↓
web.xml
<context-param> : 변수 설정 (파라미터값 넘겨주기)
<param-name> : 이름이 encoding
<param-value> : 값이 UTF-8 → 여기서 값을 바꾸면됨, xml이 바뀌는거라 컴파일 다시 안해도됨
Listener
- 외부의 요청, 자극, 액션, 수행, ... 등을 항상 감지(모니터링)하는 것
- 즉, 웹 어플리케이션에서 발생하는 다양한 이벤트를 맡아 처리해주는 역할
- 서블릿에서는 다양한 이벤트 발생을 감지하기 위한 인터페이스를 정의하고 있는데, 이를 가리켜 리스너라고 함
ex) 크롤링 관련 리스너
아래 예시는 "서블릿 컨테이너가 시작될때"로 설정 == 톰캣이 시작될 때 == 톰캣을 킬 때
Listener는 대기하고있다가 톰캣이 시작되면 감지!
contextInitialized() : 처음에 단 1번 실행되는 메서드 - 크롤링 관련 코드 작성
Scope범위가 가장 넓은 attribute에 값 넣어두기 aapplication.setAttribute("name", "홍길동")
하지만 attribute는 JSP 내장객체라 사용 불가
SevletContext sc = sce.getServletContext()