ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • javax.servlet 패키지
    백엔드/서블릿&JSP 2021. 1. 6. 18:57
    import java.io.IOException;
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    public class Test extends HttpServlet {
    	
    }

     

    우리가 흔히 쓰는 서블릿은 위와 같이 HttpServlet라는 추상 클래스를 상속 받는다.

     

    그리고 이러한 HttpServlet의 상속도를 보면 다음과 같다.

     

     

     

    HttpServlet 추상 클래스는 Generic Servlet 추상 클래스를 상속한다.

     

    그리고 Generic Servlet 추상 클래스Servlet 인터페이스Servlet Config 인터페이스구현한다.

     

    이러한 관계와 더불어 우리가 쓰는 서블릿 패키지가 어떻게 된 것인지 알수 있다면

     

    서블릿에 대한 이해도가 한층 높아질 것이다.

     

    참고로 우리가 흔히 서블릿을 쓸 때 상속받는 httpServlet 추상클래스는 Http 프로토콜에 대응하는

     

    서블릿 관련 인터페이스와 클래스를 모아둔 javax.servlet.http라는 패키지에 속한다.

     

    하지만 상속 관계에서 더 상위에 위치한 Generic Servlet클래스, Servlet, Servlet Config 인터페이스는

     

    javax.servlet 패키지에 속해 있기 때문에 이 글에서는 이에 대해서 알아보고자 한다.

     


    javax.servlet 패키지란?

    서블릿과 관련된 인터페이스와 클래스를 모아둔 패키지로서 우리가 서블릿에서 사용하게 될 다양한 기능은

     

    거의 대부분 javax.servlet 패키지에 있는 인터페이스와 클래스 그리고 거기에 속한 메서드로 구현가능하다.

     

    여기에 해당하는 주요 인터페이스와 추상 클래스는 다음과 같다.

     

    주요 인터페이스

    1. Servlet 인터페이스

    모든 서블릿이 구현해야 하는 메서드를 정의하고 있는 인터페이스.

     

    해당 인터페이스를 구현하려면 GenericServlet 클래스 혹은 HttpServlet 클래스를 상속 받으면 된다.

     

    해당 인터페이스는 서블릿 패키지의 중심이라 할 수 있는데, 서버가 서블릿을 관리할 수 있도록

     

    서블릿의 생명주기에 필요한 라이프사이클메서드( init(), service(), destroy() )를 제공하기 때문이다.

     

    주요 메서드는 다음과 같다.

     

    메서드

    설명

    init()


    서블릿 컨테이너가 서블릿을 초기화하기 위해 호출하는 메서드.

    컨테이너는 서블릿 초기화할 때 해당 메서드를 단 한번 호출하게 된다.

    그리고 이 과정이 성공적으로 끝나야 service()메서드가 이용 가능하다.

    참고로 초기화 할 때 init()은 서블릿 초기화를 위한 정보를 가진

    ServletConfig 객체를 파라미터로 전달받아서 서블릿을 초기화 한다.

    service()


    서블릿이 클라이언트의 요청(request)에 응답(response)할 수 있도록 하는 메서드.

    컨테이너는 클라이언트 요청이 있을 때 해당 메서드를 실행한다.

    그러면 클라이언트는 service() 메서드에 기술된 내용대로 서블릿 이용이 가능하다.

    destroy()


    서블릿이 더이상 사용되지 않을 때 컨테이너에 의해 호출된다.

    서비스 메서드 내 모든 스레드가 종료되거나 제한 시간이 지나면 호출된다.

    이 메서드를 실행함으로서 서블릿과 관련된 각종 리소스들이 종료된다.

    getServletConfig()


    ServletConfig란 인터페이스는 서블릿 컨테이너가 서블릿이 초기화될 때

    정보 전달을 해주기 위해 사용되는 인터페이스다.

    해당 인터페이스를 통해서 컨테이너가 만든 ServletConfig 객체는

    web.xml을 참고하여 서블릿 초기화에 관련된 정보를 저장하게 된다.

    그리고 이 객체는 init() 메서드가 호출 될 때 서블릿 초기화를 돕기 위해

    파라미터 값으로 전달된다.

    그리고 이때 전달되는 객체 값을 불러올 수 있는 메서드가 getServletConfig()다.

    getServletInfo()


    서블릿과 관련된 다양한 정보를 문자열로 반환해준다.

    2. Servlet Config 인터페이스

    서블릿 컨테이너가 서블릿을 초기화 할 때 필요로 하는 정보를 전달해주기 위해 만든 인터페이스.

     

    해당 인터페이스를 기반으로 만든 servletConfig 객체는 배포서술자로도 불리는 web.xml을 참고하여

     

    서블릿 초기화를 위한 정보를 저장한다.

     

    그리고 컨테이너가 init()로 서블릿을 초기화 할때 servletConfig 객체가 파라미터로 전달된다.

     

    즉 서버가 구동될 때 하나의 servlet은 각자 하나의 servletConfig 객체를 갖게 된다.

     

    ServletConfig 인터페이스는 이 과정과 관련한 메서드들을 제공하고 있다.

     

    메서드

    설명

    getInitParameter(String name)


    파라미터로 이름을 전달하면

    web.xml에 미리 지정해둔 같은 이름을 가진 매개변수 값을 반환한다.

    getInitParameterNames()


    초기화에 필요한 모든 매개변수의 이름을 반환한다.

    getServletContext()

    ServletContext 객체를 반환한다.

    이때 servletContext란 servletContext 인터페이스의 객체다.

    servletContext은 servletConfig 객체와 같은 역할을 한다.

    web.xml 파일을 기반으로 쓰여진 정보를 저장하는 역할을 한다.

    getServletName()


    서블릿의 이름을 반환한다.

    3. ServletContext 인터페이스

    ServletContext 인터페이스는 서블릿 컨테이너와 서블릿을 사이에서

     

    둘을 연결하는데 필요한 각종 메서드를 제공한다.

     

    비유를 들자면 servletContext는 우리가 인터넷을 할 때 사용하는 인터넷 망과 같은 역할을 한다.

     

    어떠한 정보를 서블릿 컨테이너로부터 받아서 특정 서블릿에 전달할 수도 있고

     

    서블릿에서 다른 서블릿으로 사용자 요청을 전달하는데 사용할 수도 있다.

     

    ServletContext 객체는 서블릿 컨테이너가 프로젝트를 구동할 때 자동으로 생성된다.

     

    그리고 하나의 프로그램(웹 어플리케이션)에 단 하나의 객체만 존재한다.

     

    ServletContext객체는 servletConfig처럼 생성시 web.xml을 참고해서 각종 정보를 저장하게 된다.

    (물론 둘이 같은 정보를 공유하는 것은 아니다. 같은 web.xml만 참고할 뿐이다.)

     

    두 객체 모두 같은 web.xml을 참고하고 서블릿 구동 혹은 서버 구동 초기에 만들어지지만

     

    서블릿 초기화를 위해 만들어진 servletConfig객체의 정보는 해당 서블릿에서만 사용가능하고

     

    ServletContext 객체의 정보는 컨테이너 안 속한 모든 서블릿이 공유하고 있다.

     

    추가적으로 ServletContext 객체는 web.xml을 통한 정보 뿐 아니라

     

    setAttribute()라는 메서드를 통해서 사용자가 직접 정보를 저장하고

     

    getAttribute()라는 메서드를 통해 정보를 꺼내올 수 있는 저장소의 역할까지 한다.

     

    주요 메서드들은 다음과 같다.

     

    메서드

    설명

    getInitParameter(String name)


    web.xml을 참고하여

    매개변수로 전달한 이름과 같은

    프로젝트 구동시(초기화)할때 쓰이는 매개변수 값을

    반환 받는다.

    setInitParameter(String name, String value)


    주어진 이름과 값을
    초기화에 필요한 매개 변수를 설정한다.

    getAttribute(String name)


    웹 어플리케이션에 속하는 servletContext에서

    파라미터로 입력한 이름과

    같은 속성이 있을 경우 그 객체를 반환한다.

    setAttribute(String name, Object object)


    해당 웹 어플리케이션에 속하는
    servletContext에

    파라미터로 입력한 이름과 객체를 저장한다.

    이렇게 저장한 객체는 getAttribute를 써서 사용 가능하다.

    4. ServletRequest 인터페이스

    ServletRequest 인터페이스는 요청을 통해 서블릿에 전달되는 클라이언트의 정보를

     

    전달하는 객체를 정의하고 그 객체를 이용할 수 있는 메서드를 제공한다.

     

    클라이언트가 서버에 요청(request)을 하면 서버는 고객 요청에 같이 딸려온 정보를 저장하고 서블릿에

     

    전달하기 위한 목적으로 ServletRequest 객체를 만든다.

     

    이렇게 만들어진 ServletRequest객체는 서블릿 실행을 위한 service() 메서드에 매개변수로서 전달된다.

     

    그리고 이 객체를 통해 전달 받은 정보를 기반으로 서블릿은 각종 로직을 수행하게 된다.

     

    간단히 말하면 고객의 요청에 딸려온 정보를 전달하고자 요청을 객체로 만드는 역할을 하는 것이

     

    ServletRequest 인터페이스다.

     

    그리고 이 객체에는 고객이 요청한 정보가 저장되있다.

     

    추가적으로 service()의 로직을 수행하면서 사용자가 객체에 정보를 따로 저장도 가능하다.

     

    그럴 때는 servletContext와 마찬가지로 setAttribute() 메서드를 사용하면 된다.

     

    주요 메서드는 다음과 같다.

     

    메서드명

    설명

    getAttribute(String name)


    만약 ServletRequest 객체에 전달된 이름과 같은

    속성이 있다면 해당 속성을 반환한다.

    setAttribute(String name, Object object)


    ServletRequest 객체에 전달한 이름과 오브젝트를

    속성으로 등록한다.

    이 오브젝트를 사용하고 싶다면 getAttribute()메서드를 사용한다.

    setCharacterEncoding(String charset)


    request를 통해 전달된 문자열을  파라미터에 전달된 문자코드로

    인코딩하라는 메서드.

    즉 파라미터 안에 UTF-8 등의 문자 코드를 넣으면 request로

    전달된 문자열은 해당 문자 코드로 인코딩하게 된다.

    5. ServletResponse 인터페이스

    ServletResponse 인터페이스는 이름에서도 알 수 있듯이 ServletRequest의 반대 역할을 한다.

     

    즉 고객 요청(request)에 따른 응답(response)를 할 때 사용되는 객체를 정의하고 메서드를 제공한다.

     

    이름만 보면 ServletRequest객체가 생성되고 service()메서드에 전달 된 이후 서비스 로직을 마치면

     

    생성될 것 같다. 하지만 생성 시점은 ServletRequest와 동일하다.

     

    고객이 서버에 요청(request)하면 두 객체는 동시에 생성된다.

     

    그리고 동시에 service()메서드의 매개변수로서 제공된다.

     

    주요 메서드는 다음과 같다.

     

    주요 메서드

    설명

    setCharacterEncoding(String charset)


    고객의 요청에 응답할 때 전달되는 문자열을 어떻게 인코딩해서

    전달할지 설정하는 메서드.

    해당 메서드 안에 문자 코드를 넣으면

    응답(response)할 때 서버가 어떻게 전달되는 문자열을

    어떻게 인코딩해서 전달할지 설정하는 메서드.

    setContentType(String type)


    브라우저가 응답(response)를 받았을 때

    같이 전달된 문자열을 어떻게 읽어야 할지 설정하는 메서드.

    예를 들어 setCharacterEncoding("UTF-8")로 문자를

    UFT-8 형식으로 인코딩 했을 경우

    setContentType("UTF-8")처럼 사용해야 한다.

    이것은 내가 전달하는 문자열이 UTF-8로 인코딩됐으므로

    이것을 UTF-8로 인식하고 화면에 표현하라는 의미다.

    6. RequestDispatcher 인터페이스

    RequestDispatcher는 클라이언트가 서버에 요청(request)을 보냈을 때 생성되는 request 객체를

     

    서버 안의 다양한 리소스로 전달하는 역할을 한다.

     

    클라이언트가 서버 측에 요청(request)를 할 경우 단 하나의 서블릿만 거칠 때도 있지만

     

    다중의 서블릿을 거쳐야 하는 경우도 있다.

     

    이때 해당 요청을 서블릿에서 서블릿으로 옮길 때 혹은 서블릿에서 jsp나 html 파일 등으로 옮길 때

     

    RequestDispatcher 인터페이스를 이용하게 된다.

     

    RequestDispatcher의 경우 고작 2개의 메서드 밖에 없다.

     

    바로 forward()와 include()다.

     

    forward는 클라이언트의 request를 고객이 요청한 서블릿에서 다른 서블릿으로 아예 넘겨 줄 때 쓴다.

     

    그래서 response의 책임 request와 함께 또한 다른 서블릿으로 넘어간다.

     

    반면 include는 클라이언트의 request를 고객이 요청한 서블릿에서 다른 서블릿으로 넘겼다가 돌려받는다.

     

    그래서 response의 책임을 고객이 요청한 서블릿이 가져오게 된다.

     

    그림을 넣어보자면 대략 다음과 같다.

     

    forward()를 사용할 경우 request의 흐름은 다음과 같다.

     

     

    include()를 사용할 경우 흐름은 다음과 같다.

     

    7. Filter 인터페이스

    필터란 서블릿을 향하는 클라이언트의 요청(request)와 응답(response)를 중간에서 가로채서

     

    필터링하는 것을 목적으로 하는 객체를 정의하고 메서드를 제공하는 인터페이스다.

     

    서블릿 컨테이너에는 수 많은 서블릿이 존재한다.

     

    그런데 이 모든 서블릿의 요청이나 응답할 때 공통적으로 수행해야 하는 작업이 있다면 굉장히 피곤해진다.

     

    매번 모든 서블릿에 해당 작업 코드를 집어 넣어야 하기 때문이다. 그럴 때 필터를 쓰면 편하다.

     

    필터의 구조는 다음과 같다.

     

     

    그림처럼 클라이언트가 서블릿에 대해 요청하거나 서블릿이 클라이언트에 응답할 때

     

    중간에서 필터링하는 역할을 한다.

     

    가장 대표적인 예가 인코딩 작업이다.

     

    흔히 한글은 UTF-8 코드를 쓰다 보니 request나 response 객체에 인코딩 메서드를 추가해주지 않으면

     

    입출력에 오류가 나기 때문에 매번 서블릿에 코드를 적어야 한다.

     

    하지만 필터를 통하면 모든 requst와 response에 별도의 추가 작업 없이 메서드를 추가할 수 있다.

     

    해당 필터의 주요 메서드는 다음과 같다.

     

    doFilter(ServletRequest request, ServletResponse response, FilterChain chain)


    해당 메서드는 요청이나 응답이 필터를 지나갈 때마다 호출된다.

    그러면서 요청, 응답에 대해 필터에서 특정한 작업을 처리할 수 있도록 만든다.

    주요 클래스

    1. GenericServlet 클래스

    기존의 Servlet 인터페이스를 구현해야했다면 해당 인터페이스 메서드도 같이 구현해야 했다.

     

    특히 라이프사이클 메서드라 불리는 init(), service(), destroy()를 일일이 구현해야 했다.

     

    하지만 해당 추상 클래스를 사용하면 service()만 구현하면 바로 서블릿을 사용할 수 있다.

     

    하지만 서블릿을 공부해보면 알겠지만 일반적으로 해당 추상 클래스는 쓸 일이 거의 없다.

     

    왜냐면 Http 프로토콜에 대응하는 전용 서블릿인 HttpServlet 추상클래스가 따로 제공되기 때문이다.

     

    다만 특수한 경우로 Http 프로토콜이 아닐 때 서블릿을 써야 한다면 GenericServlet 클래스를

     

    상속받아서 서블릿을 구현하면 된다.

    '백엔드 > 서블릿&JSP' 카테고리의 다른 글

    세션과 쿠키(Session과 Cookie)  (0) 2021.01.07
    javax.servlet.http 패키지  (0) 2021.01.07
    JSP 기초 문법  (0) 2020.11.02
    JSP(JavaServer Pages)란?  (0) 2020.11.01
    서블릿(Servlet)이란?  (0) 2020.10.30
Designed by Tistory.