주니어 기초 코딩공부/JSP 기초

[JSP] 필터란 무엇인가

jju_developer 2023. 1. 30. 21:18
728x90

안녕하세요 jju_developer입니다.

오늘은 JSP의 필터의 기능은 무엇이고 어떻게 사용하는지에 대해 알아보도록 하겠습니다.

필터는 말 그대로 클라이언트의 요청을 선처리하거나 서버의 자원을 가공하여 보내주는 역할을 합니다.

즉, 브라우저의 요청이 들어오고 나갈 때 웹 컨테이너(WAS)에 어떠한 작업이 동작을 하기 전에 필터를 낍니다.

필터는 요청과 응답의 내용을 변경이 가능합니다.

필터는 N개 이상이 연동할 수 있습니다.

 

필터의 구현

 필터를 구현하는데 있어 핵심은 다음의 3개 타입이 있습니다.
1. javax.servlet.Filter 인터페이스:

클라이언트와 최종 자원 사이에 위치하는 필터를 나타내는 객체가 구현해야 하는 인터페이스입니다.

 

2. javax.servlet.ServletRequestWrapper 클래스:

필터가 요청을 변경한 결과를 저장하는 레퍼입니다.

 

3. javax.servlet.ServletResponseWrapper 클래스:

필터가 응답을 변경하기 위해 사용하는 래퍼입니다.

 

 

Filter 인터페이스의 메서드

public void init(FilterConfig filterConfig) throws ServletException : 필터를 초기화할 때 호출된다.
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws java.io.IOException, ServletException : 체인을 따라 다음에 존재하는 필터로 이동한다. 
체인의 가장 마지막에는 클라이언트가 요청한
최종 자원이 위치한다.
public void destroy() : 필터가 웹 컨테이너에서 삭제될 때 호출된다

 

 

필터 설정하기: web.xml 이용

 

web,xml

여기 web.xml 보면 로그인 체크에 보드가 들어오면 위의 필터가 돌아간다는 내용입니다.

 


예제 1

 

보드로 시작하는 URL은 필터가 실행된다고 했죠?

그럼 그 필터가 무엇인지 볼까요?

 

 

package filter;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

public class LoginCheckFilter implements Filter {
    @Override
    public void init(FilterConfig config) throws ServletException {
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        HttpSession session = httpRequest.getSession(false);

        boolean login = false;
        if (session != null) {
            if (session.getAttribute("MEMBER") != null) {
                login = true;
            }
        }
        if (login) {
            chain.doFilter(request, response);
        } else {
            RequestDispatcher dispatcher = request
                    .getRequestDispatcher("/loginForm.jsp");
            dispatcher.forward(request, response);
        }
    }

    @Override
    public void destroy() {
    }
}

세션을 찾고 세션 안에 멤버가 있는지를 찾습니다.

MEMBER는 지금까지 보지 못했으니, 로그인은 여전히 flase입니다.

if절의 else로 돌아가서 세션의 멤버가 없으니

getRequestDispatcher 로그인폼. jsp로 포워드를 해주는 모습을 볼 수 있습니다.

 

그럼 로그인 폼. jsp의 코드를 볼까요?

<%@ page contentType="text/html; charset=utf-8" %>
<html>
<head><title>로그인</title></head>
<body>
<form action="<%= request.getContextPath() %>/login.jsp">
아이디<input type="text" name="memberId">
암호<input type="password" name="password">
<input type="submit" value="로그인">
</form>
</body>
</html>

이렇게 나는 boardList.jsp를 실행해도

필터를 통해 세션에 원하는 값이 있는지를 확인하고 false면 로그인을 먼저 하고 보드리스트를

확인하라고 보내준 것입니다.

 

아이디: jju_developer와 비밀번호: 123을 입력하였더니, 로그인 처리라는 메시지가 뜹니다.

 

그럼 이제 다시 보드리스트를 실행하면

 

이렇게 보드리스트 페이지에 접근이 가능한 것을 볼 수 있습니다.

보드리스트.jsp
<%@ page contentType="text/html; charset=utf-8" %>
<html>
<head><title>리스트</title></head>
<body>
게시판 리스트입니다.
</body>
</html>

원래 저번시간에 세션을 헤더에 두어서 헤더에서 로그인 체크가 되어있는지를 확인했다면

예전 코드

이렇게 하면 내 페이지와 로그인 기능의 로직이 들어있어 복잡합니다.

 

이번의 게시판 로직은 어땠나요?

아주 간단하게 게시판에 관련된 내용만 있으니, 훨씬 유지보수하기가 쉽겠죠?

이렇게 할 수 있는 이유는 바로!!!

 

필터가 세션을 체크해주고 있기 때문입니다.

 

필터 하나를 만들어 놓고 web.xml에 어디에 적용할지 추가만 해주면 됩니다.

이렇게 각 페이지에는 로그인 체크하는 기능은 없지만

필터를 적용할 수가 있습니다!!!!

그렇게 한다면 유지보수도 쉽겠죠?

 

※ web.xml 파일에 지정하지 않더라도 Filter 클래스가 @WebFilter 애노테이션을 가지면 자동으로 필터로 등록됩니다.


 

필터 설정하기: 캐릭터 인코딩 필터

 요청 파라미터의 글자를 올바르게 처리하기 위해 캐릭터 인코딩을 설정합니다.

 

이런 필터는 web.xml에 선언되어 계속해서 만들어지는 것이 아닌 한 번 만들어진 클래스가 계속해서 재사용될 수 있습니다.

 

원래라면 인코딩 정보, 로그인 정보 기타 등등 반복해서 사용하는 자원을 이용할 때 모든 JSP파일, 혹은 Java 클래스 파일에 <% %>, encoding, session, cookie... 이러한 코드를 전부 다 넣어 처리해야 한다. 

 

그러나 이런 반복적인 일을 필터를 사용하면 손쉽게 처리할 수 있다.

 

웹 프로그래밍에서 가장 먼저 만나는 UTF-8 필터를 예시로 들어보겠다.

<% request.setCharacterEncoding("utf-8"); %>

 

예시)

package util;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

public class CharacterEncodingFilter implements Filter {

	private String encoding;
	
	@Override
	public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
			throws IOException, ServletException {
		req.setCharacterEncoding(encoding);
		chain.doFilter(req, res);
	}

	@Override
	public void init(FilterConfig config) throws ServletException {
		encoding = config.getInitParameter("encoding");
		if (encoding == null) {
			encoding = "UTF-8";
		}
	}

	@Override
	public void destroy() {
	}

}

encoding = config.getInitParameter("encoding"); 설정에 따라 각 설정된 값을 가져오는 거 ㅅ입니다.

웹.xml에 설정이 있는지 볼까요?

UTF-8 인코딩이 되어있는지 보고 아니라면 인코딩을 UTF-8로 적용하겠다는 뜻입니다.

/*은 모든 페이지에 이 필터를 다 적용하겠다는 뜻입니다.

 


 

그럼 지금까지 JSP 필터에 대한 설명을 마치겠습니다.

 

오늘도 수고하셨습니다.

 

감사합니다.

 

728x90