Introduction to Java Servlets(Baeldung 번역)

Jay Jang·2022년 7월 30일
1

Java

목록 보기
4/5
post-thumbnail

https://www.baeldung.com/intro-to-servlets

Introduction to Java Servlets | Baeldung의 Introduction to Java Servlets을 번역한 것입니다.

모든 저작권은 Baeldung에 있습니다. All copyrights are in Baeldung.


Overview


이 문서에서 우리는 Java에서 웹 개발의 핵심 측면을 살펴볼 것이다 - Servlets.


The Servlet and the Container


간단히 말해, Servlet 서블릿은 요청을 처리하고, 작업하여 응답하여 돌려주는 클래스이다.

예를 들어 우리는 Servlet을 사용하여 HTML form을 통해 사용자로부터 입력을 받고, 데이터베이스에서 레코드를 쿼리하고, 페이지를 동적으로 생성할 수 있다.

ServletServlet Container 서블릿 컨테이너라는 또 다른 Java 애플리케이션의 제어 하에 있다.
웹 서버에서 실행 중인 애플리케이션이 요청을 수신하면 서버는 요청을 서블릿 컨테이너로 전달한다.

서블릿 컨테이너는 요청을 타겟 서블릿으로 전달한다.


Maven Dependencies


우리의 웹 애플리케이션에 서블릿 지원을 추가하기 위해서, javax.servlet-api 의존성이 요구된다.

<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>3.1.0</version>
</dependency>

물론 앱을 배포할 Servlet 컨테이너도 구성해야 한다. : https://www.baeldung.com/tomcat-deploy-war


Servlet Lifecycle


서블릿의 생명 주기를 정의하는 몇가지 메소드를 살펴보자.

init()


init 메소드는 오직 한번만 호출되도록 설계되었다. 서블릿 인스턴스가 존재하지 않으면 web container는 다음과 같이 동작한다.

  1. Servlet 클래스를 로드한다.
  2. Servlet 인스턴스를 생성한다.
  3. init 메소드를 호출하여 초기화한다.

서블릿이 요청을 수신하기 위해선 init 메소드가 성공적으로 완료되어야 한다.
init 메서드가 ServletException을 발생시키거나 웹 서버가 정의한 시간 내에 반환되지 않으면 Servlet 컨테이너는 서블릿을 서비스에 배치할 수 없다.

public void init() throws ServletException {
    // Initialization code like set up database etc....
}

service()


이 메소드는 서블릿이 init() 메소드를 성공적으로 완료했을 때만 호출될 수 있다.

Container는 클라이언트의 요청을 처리하기 위해 service() 메소드를 호출하고 HTTP request type(GET, POST, PUT, DELETE 등) 을 해석하며, doGet, doPost, doPut, doDelete 메서드를 호출한다.

public void service(ServletRequest request, ServletResponse response) 
  throws ServletException, IOException {
    // ...
}

destroy()


서블릿 컨테이너가 서블릿을 서비스에서 제외하기 위해 호출한다.

이 메서드는 서블릿의 서비스 메서드 내의 모든 스레드가 종료되거나 timeout된 후에만 호출된다.

컨테이너가 이 메서드를 호출한 후에는 서블릿에서 sevice() 메서드를 다시 호출하지 않는다.

public void destroy() {
    // 
}

Example Servlet


먼저 컨텍스트 루트를 javax-servlets-1.0-SNAPSHOT에서 /로 변경한다.

<Context path="/" docBase="javax-servlets-1.0-SNAPSHOT"></Context>

$CATALINA_HOME\conf\server.xml.의 Host 태그 아래에 있다.

이제 form을 사용하여 정보를 처리하는 전체 예시를 시작해보자.

시작에 앞서, form을 통해 POST된 정보를 수집하고 RequestDispatcher를 사용하여 결과를 반환하는 /calulateServlet을 사용하여 서블릿을 정의해보자.

@WebServlet(name = "FormServlet", urlPatterns = "/calculateServlet")
public class FormServlet extends HttpServlet {

    @Override
    protected void doPost(HttpServletRequest request, 
      HttpServletResponse response)
      throws ServletException, IOException {

        String height = request.getParameter("height");
        String weight = request.getParameter("weight");

        try {
            double bmi = calculateBMI(
              Double.parseDouble(weight), 
              Double.parseDouble(height));
            
            request.setAttribute("bmi", bmi);
            response.setHeader("Test", "Success");
            response.setHeader("BMI", String.valueOf(bmi));

            request.getRequestDispatcher("/WEB-INF/jsp/index.jsp").forward(request, response);
        } catch (Exception e) {
           request.getRequestDispatcher("/WEB-INF/jsp/index.jsp").forward(request, response);
        }
    }

    private Double calculateBMI(Double weight, Double height) {
        return weight / (height * height);
    }
}

위에서 볼 수 있듯이, @WebServlet 어노테이션이 달린 클래스는 javax.servlet.http.HttpServlet 클래스를 확장해야 한다.
@WebServlet 어노테이션은 Java EE 6 이후에서 사용할 수 있다.

@WebServlet 주석은 배포 시에 컨테이너에 의해 처리되며 지정된 URL 패턴에서 해당 서블릿을 사용할 수 있다.

어노테이션을 사용하여 URL 패턴을 정의하면 서블릿 매핑에 web.xml이라는 XML 배포 descriptor를 사용하지 않아도 된다.

어노테이션을 사용하지 않고 서블릿을 매핑하려면 기존 web.xml을 사용하면 된다.

<web-app ...>

    <servlet>
       <servlet-name>FormServlet</servlet-name>
       <servlet-class>com.root.FormServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>FormServlet</servlet-name>
        <url-pattern>/calculateServlet</url-pattern>
    </servlet-mapping>

</web-app>

그 다음, 기본적인 HTML form을 만들어보자.

<form name="bmiForm" action="calculateServlet" method="POST">
    <table>
        <tr>
            <td>Your Weight (kg) :</td>
            <td><input type="text" name="weight"/></td>
        </tr>
        <tr>
            <td>Your Height (m) :</td>
            <td><input type="text" name="height"/></td>
        </tr>
        <th><input type="submit" value="Submit" name="find"/></th>
        <th><input type="reset" value="Reset" name="reset" /></th>
    </table>
    <h2>${bmi}</h2>
</form>

마지막으로 모든 것이 예상대로 작동하는지 확인하기 위해 간단한 테스트를 작성해보자.

public class FormServletLiveTest {

    @Test
    public void whenPostRequestUsingHttpClient_thenCorrect() 
      throws Exception {

        HttpClient client = new DefaultHttpClient();
        HttpPost method = new HttpPost(
          "http://localhost:8080/calculateServlet");

        List<BasicNameValuePair> nvps = new ArrayList<>();
        nvps.add(new BasicNameValuePair("height", String.valueOf(2)));
        nvps.add(new BasicNameValuePair("weight", String.valueOf(80)));

        method.setEntity(new UrlEncodedFormEntity(nvps));
        HttpResponse httpResponse = client.execute(method);

        assertEquals("Success", httpResponse
          .getHeaders("Test")[0].getValue());
        assertEquals("20.0", httpResponse
          .getHeaders("BMI")[0].getValue());
    }
}

Servlet, HttpServlet and JSP


Servlet 기술이 HTTP 프로토콜에 한정되지 않는다는 것을 이해하는 것이 중요하다.

실제로는(거의 항상 그렇지만) Servlet은 generic 인터페이스이고 HttpServlet은 그 인터페이스의 화장으로 doGet, doPost 등과 같은 HTTP 특정 지원을 추가한다.

마지막으로, Servlet 기술은 JSP(자바 서버 페이지), 스프링 MVC등과 같은 수많은 다른 웹 기술들의 메인 드라이버이기도 하다.


Conclusion


이번 간단한 문서를 통해 우리는 Java 웹 애플리케이션에서 서블릿의 기초를 알아보았다.


REFERENCE


Introduction to Java Servlets

profile
그때는맞고지금은틀리다

0개의 댓글