ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Servlet Filter(서블릿 필터)
    프로그래밍/JSP 2021. 4. 15. 00:48

    tomcat이 사용자로부터 요청이 들어오면 적절한 소프트웨어를 실행해서 그 결과를 돌려주게 됩니다.
    그 소프트웨어를 우리는 서블릿이라고 하는데 이 서블릿은 사용하려고 하면
    메모리상에 존재하게 되는데 이 존재하는 공간을 Servelt Container라고 합니다.

    Servlet을 실행시켜서 이 공간에 담아두고 그결과를 response, 돌려주게 됩니다.
    이렇게 공간을 사용하다가 사용되지 않는다면 Servlet을 삭제 하게 됩니다.

     

    우리는 그동안 이 Servlet에 대해서만 만져왔는데

    오늘은 Filter라는 녀석을 배워보겠습니다.

     

    지난시간에 CharacterEncoding을 설정하는 작업을 했는데
    한글을 사용하다보니 사용자에게 입력을 받을때는 이 설정을 계속 해줘야 합니다.
    Servlet을 만드는 일이 많아질텐데
    입력을 받는 Servlet에서 모두 이 설정을 해야겠죠? 귀찮겠죠?

     

    그냥 tomcat의 인코딩의 방식을 UTF-8로 바꿔버리는것도 가능은 하지만
    그런데 이게 좀 부담스럽습니다
    tomcat은 여러 Application을 실행하는 하나의 Container인데

     

    예를들어 한 다양한 나라의 사람들이 살고 있는 빌라가 있다고 칩시다.
    이 빌라의 기본설정을 서양으로 바꾼다고 한다면
    거기에 사는 모든 구성원들이 신발을 신고 집에 있는 것을 기본으로 해야하는 것과 같게됩니다.
    특정한 구성원으로 인해 다른 구성원들이 영향을 받는 것이 됩니다. 그래서 좀 부담스럽죠.

     

    그러니 우리것에만 영향을 주고 싶긴한데 서블릿 마다 이 작업(UFT-8 인코딩)을 하기는 불편하니
    우리가 생각해볼 수 있는 옵션이 바로 filter 라는 것 입니다.

    Filter는 이렇게 중간에 낄 수 있는 소프트웨어 입니다.

    request가 들어오면 Servlet으로 가게 되는데 이걸 가로채기가 가능한 녀석이죠
    이녀석이 먼저 실행된 다음 Servlet이 실행되는 것이 순서입니다.
    그리고 Filter는 Servlet이 실행되고 말고를 결정 지을 수도 있어서
    일종의 수문장 역할을 하기도 합니다.

     

    일단 기본적으로는 모든 서블릿이 가져야하는 역할을 이녀석에게 주게되면
    어차피 한번 거쳐가는 과정이니 여기서 설정한 것이 모든 서블릿에 영향을 주게 되는 것이죠.

     

    그리고 그림처럼 Servlet이전, 이후 모두 실행되게 만들 수도 있습니다.

     

    오늘은 필터를 만드는 방법과 필터에 인코딩을 넣어둬서 서블릿에서 작업이 필요없게 만들어 볼 것입니다.

     

     

    우선 지난시간에한 Encoding을 주석처리 해줍니다.

     

    그리고 새 클래스를 생성합니다.
    이름을 바꿔주고 interface를 추가(add)해줍니다.

    이렇게 javax.servlet의 filter를 추가합니다.

     

    이렇게 되었으면 확인해보겠습니다.

    자동으로 implements Filter를 해주고
    @Override 즉, 매서드를 하나 만들어줬는데
    이제 이 매개변수를 이용해서 Filter를 구현할 겁니다.

     

    	@Override
    	public void doFilter(ServletRequest request
    			, ServletResponse response, FilterChain chain)
    			throws IOException, ServletException {
    		
    		System.out.println("Hello Filter");
    	}

    먼저 간단하게 println을 해줄 것인데
    이렇게 하고 이 필터를 설정만하면 자동으로 동작하게 됩니다.
    filter는 어떤 요청이 와도 동작되고 톰켓이 처음 실행될때도 동작됩니다.

     

    Filter는 두가지 방식으로 설정가능 합니다. 첫번째는 web.xml

    두번째는 annotation으로도 가능하죠

     

    먼저 web.xml에 가서 설정해보고 annotation으로 바꿔볼 것 입니다.

     

      <filter>
      	<filter-name></filter-name>
      	<filter-class></filter-class>
      </filter>
    

     

    서블릿 설정과 많이 비슷한데
    filter를 만들고 filter-mapping을 추가

    filter에는 현재 내가 어떤 클래스(class)를 쓸건지를 정하고 그리고 이 필터의 맵핑설정 해줄 이름(name)을 지정해줄겁니다.

      <filter-mapping>
      	<filter-name></filter-name>
      	<url-pattern></url-pattern>
      </filter-mapping>

    -mapping에는 어떤 filter에 대해서 어떤 mapping할 것이다 라는 건데
    우리가 맵핑을 무엇으로 할 것인가(name)
     url-pattern : 특정 url에 대해 이 필터를 쓸 것이다.

    라는 것입니다.

     

      <filter>
      	<filter-name>characterEncodingFilter</filter-name>
      	<filter-class>com.exam.web.filter.CharacterEncodingFilter</filter-class>
      </filter>
      <filter-mapping>
      	<filter-name>characterEncodingFilter</filter-name>
      	<url-pattern>/*</url-pattern>
      </filter-mapping>

    /* : 모든 url에 대해서 이 필터를 적용하게 할 것이다. 라는 뜻입니다.
    다음과 같이 이름을 정하고
    클래스에는 패키지가 포함된 클래스명을 적어줍시다.

     

    이제 이렇게 설정한 것만으로 이 필터를 사용할 수 있게 되었습니다.
    우리가 무언가를 요청하게 되면 이 url맵핑에 맞게 실행이 될 것 입니다.

     

    notice-reg가 실행되었지만 아무것도 나오지않습니다.

    하지만 eclipse의 console창을 확인 해보면
    notice-reg를 새로고침할때마다 filter가 실행됨을 확인 할 수 있죠.
    근데 filter는 되는데 왜 notice-reg는 안될까요?

     

    filter가 실행이 되는거 까진 좋은데
    이 요청을 서블릿으로 전이를 할지 말지를 결정 짓는 애가 있습니다.

    FilterChain이 라는 녀석이죠

     

    	@Override
    	public void doFilter(ServletRequest request
    			, ServletResponse response, FilterChain chain)
    			throws IOException, ServletException {
    		
    		chain.doFilter(request,response);
    		System.out.println("Hello Filter");

    chain.doFilter(request,response);
    요청이 오면 흐름을 넘기고 다음 필터나 서블릿을 실행되게하고 그 결과가 돌아오면
    그 다음 코드인 System.out.println("Hello Filter"); 를 실행시키게 됩니다.

     

    좀 더 쉽게 설명하죠

     

    		System.out.println("before Filter");
    		chain.doFilter(request,response);
    		System.out.println("after Filter");

    System.out.println("before Filter");
    요청이 오면 실행(콘솔에 찍는다)
    -> 다음 녀석이 오기전에 할 것이 있다면 여기에

    chain.doFilter(request,response);
    다음 필터나 다음 서블릿이 실행이 되고 그 결과가 돌아옵니다.

    System.out.println("after Filter");
    그렇게 돌아오면 실행(콘솔에 찍는다)
    -> 다음 녀석이 진행되고 나서 할 것이 있다면 여기에

     

    chain
    다음 실행을 어디로 가게 할 것인지를 결정 짓는 역할입니다.
    흐름을 원래 예정대로 가게 한다면 이대로 쓰지만
    어떤 검사를 통해 막아야한다면 다른 곳으로도 전이해버리게 할 수도 있습니다.(앞서 설명한 수문장 역할)

     

    우리 같은 경우엔 서블릿이 실행되기 전에 모든 Encoding작업을 할 것이기에 before의 위치에 입력하면 됩니다.

    	@Override
    	public void doFilter(ServletRequest request
    			, ServletResponse response, FilterChain chain)
    			throws IOException, ServletException {
    		
    		request.setCharacterEncoding("UTF-8");
    		chain.doFilter(request,response);
    	}

    주석을 해둔 request.setCharacterEncoding("UTF-8");을 before자리에 붙여주면
    모든 서블릿(url : /*)이 실행되기 전에 인코딩을 하게 해주게 되는 것이죠

     

    이 설정 하나만으로 모든 환경설정을 끝냈습니다.

     

    우선 필터에서 인코딩을 주석처리하고

    //request.setCharacterEncoding("UTF-8");


    흐름이 정상적으로 작동하는지 즉 chain이 정상적으로 작동하는지를 볼 것입니다.
    reg.html을 실행하면

    일단 정상적인 흐름으로 작동하겠죠? 모든 url에 적용시켰으니까요.

    그리고 주석처리도 제대로 됐는지 확인해보겠습니다.

     

    잘(?) 깨지네요

     

    다시 주석을 해제하고 하면 잘 적용됩니다.

     

    이제 인코딩 방식을 신경쓸거 없이 그냥 한글이든 영문이든 읽어올 수 있게 설정이 되었네요.

     

    하지만 끝이 아닙니다. 두번째 방법 annotation을 해야죠.

    web.xml의 filter설정을 주석처리합니다.

     

    저거만 붙이면 됩니다 끝입니다.

    web.xml과 비교해보면 여러가지 작업들을 굉장히 간단하게 끝냈네요

     

    앞으로는 annotation을 잘 활용합시다.

     

    실행결과는 따로 스샷을 안올리겠습니다.

    '프로그래밍 > JSP' 카테고리의 다른 글

    POST_한글깨짐 현상  (0) 2021.04.11
    POST요청  (0) 2021.04.08
    GET요청 - 사용자 입력  (0) 2021.04.07
    GET과 Query String  (0) 2021.03.24
    한글 출력 및 content형식 지정하기  (0) 2021.03.23

    댓글

Designed by Tistory.