FireDrago

[JSP] Filter로 로그기록 만들기 본문

프로그래밍/템플릿 엔진(thymeleaf, jsp)

[JSP] Filter로 로그기록 만들기

화이용 2023. 6. 19. 17:32

필터(Filter)

- 클라이언트와 서버 사이에서 Request와 Response 객체를 먼저 받아서 사전/사후 작업을 처리하는 것

- 클라이언트의 요청이 JSP나 HTML 페이지에 도달하기 전, 클라이언트에게 응답하기 전에 필요한 처리가능

- 재사용이 가능하다. 여러개의 필터를 묶은 필터체인을 제공하기도 한다.

 

1. Filter 역할을 할 자바 클래스 만들기

 - 반드시 Filter 인터페이스를 구현해야한다. - > init( ) , doFilter( ) , destroy( ) 3가지 메서드를 구현

public class LogFileFilter implements Filter {
	PrintWriter writer;
	
	@Override
    //init 서버실행시 최초한번 실행
	public void init(FilterConfig filterConfig) throws ServletException {
		String filename = filterConfig.getInitParameter("filename");
        //web.xml 파일에서 설정한 init-param을 가져와서 변수에 담는다. (파일경로)
		if(filename == null) throw new ServletException("로그 파일의 이름을 찾을 수 없습니다.");
        //web.xml 연결이 안되어서 inti-param 받을 수 없다면 찾을 수 없음을 표시
		try {
			writer = new PrintWriter(new FileWriter(filename, true),true);
            // 파일경로(filename)에 파일을 생성하고 내용을 입력하기위한 객체생성 
		} catch (Exception e) {
			throw new ServletException("로그 파일을 열 수 없습니다.");
		}
	}

int ( ) 메서드를 오버라이딩 한다. web.xml 에서 전달받은 filename을 이용하여 파일을 생성하고 내용을 입력하기위한

객체를 생성한다. 

@Override
//doFilter 실질적인 필터의 기능을 정의, request할때마다 실행
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterchain)
        throws IOException, ServletException {

    writer.printf("현재 일시 : %s %n", getCurrentTime());
 //init( )에서 생성한 객체에 현재시간 입력
    String clientAddr = request.getRemoteAddr();
    writer.printf("클라이언트 주소 : %s %n", clientAddr);
//request가 가진 클라이언트의 주소를 파일에 작성
    filterchain.doFilter(request, response);
// 다른 필터가 있다면 실행, 다시 돌아온다.
    String contentType = response.getContentType();
    writer.printf("문서의 콘텐츠 유형 : %s %n", contentType);
    writer.println("-----------------------------------");
// 문서의 컨텐츠 유형을 마지막으로 작성
}

@Override
// 필터 종료시
public void destroy() {
    writer.close();
}

//현재 시간을 특정 포맷으로 전달하는 메서드
private String getCurrentTime() {
    DateFormat formatter = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
    Calendar calendar = Calendar.getInstance();
    calendar.setTimeInMillis(System.currentTimeMillis());
    return formatter.format(calendar.getTime());
}

doFilter( ) 메서드는 실질적인 필터의 기능을 정의한다. request의 주소와 요청시간, 컨텐츠 유형을 담은 로그를 

init( ) 에서 만든 파일에 작성한다. destroy( )는 필터 종료시 writer 객체를 닫는다. 

 

2. Filter를 web.xml을 통해 연결하기

web.xml 파일은 webapp > WEB-INF 있어야한다. 없다면  eclipse 기준 

프로젝트 우클릭 > java EE Tools > Generate Deployment Descriptor Stub 클릭하면 생긴다.

....
<filter>
    <filter-name>Filter02_2</filter-name>                <!--필터이름 설정-->
    <filter-class>filter.LogFileFilter</filter-class>    <!--필터클래스--> 
    <init-param>                                         <!--파라미터로 init( )에 주소를 전달-->
        <param-name>filename</param-name>                <!--파라미터명 (호출시 사용)-->
        <param-value>c:\\logs\\monitor.log</param-value> <!--값 (여기선 경로)-->
    </init-param>
</filter>
<filter-mapping>                                          <!--필터와 적용될 JSP 연결-->
    <filter-name>Filter02_2</filter-name>                 <!--필터명-->
    <url-pattern>/filter02_process.jsp</url-pattern>      <!--필터가 적용될 페이지-->
</filter-mapping>
...

 

맨위의 경로에 나와있듯이, filter02.jsp에서 파라미터를 filter02_process.jsp로 넘기고 이때마다 로그가 기록된다.

두번실행한 결과 로그가 두번 기록되는 것을 확인할 수 있다.