본문 바로가기
네이버클라우드/JAVA 웹 프로그래밍

JAVA 54일차 (2023-08-07) 자바 프로그래밍_Servlet API 사용법_1

by prometedor 2023. 8. 7.
## 56. 웹 애플리케이션 자바 표준 기술 JavaEE 도입

- JavaEE 기술 소개
- JavaEE 버전 별 하위 기술 버전 
- JavaEE 구현 서버 및 Servlet 컨테이너 관계
- Servlet API 사용법

 

gradle 설정

servlet-app/build.gradle

plugins {
    id 'java'
    id 'eclipse-wtp'
    id 'war'
}

repositories {
    mavenCentral()
}

dependencies {
    // Servlet API
    // => providedCompile?
    //    컴파일 할 때만 사용하는 라이브러리
    //    배포할 때 제외하는 라이브러리
    //    배포 받는 쪽에서 라이브러리를 갖고 있을 때 이 옵션을 사용한다.
    providedCompile 'javax.servlet:javax.servlet-api:4.0.1'
    testImplementation 'org.junit.jupiter:junit-jupiter:5.9.2'
    testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
    implementation 'com.google.guava:guava:31.1-jre'
}

java {
    toolchain {
        languageVersion = JavaLanguageVersion.of(17)
    }
}

tasks.named('test') {
    useJUnitPlatform()
}

tasks.withType(JavaCompile) {
    options.encoding = 'UTF-8' 
    sourceCompatibility = '17'
    targetCompatibility = '17'
}

// eclipse 프로젝트 이름을 설정하기
eclipse {
    project {
        name = "servlet-app"
    }
    jdt {
      sourceCompatibility = 17
      targetCompatibility = 17
      javaRuntimeName = "JavaSE-17"
    }
    
    wtp {
        facet {
            facet name: 'jst.java', version: '17'
            //facet name: 'jst.web', version: '4.0'
        }
        component {
            contextPath = '/'
            //deployName = 'web'
        }
    }
}

war {
    archiveBaseName = "servlet-app"
}

 

ㄴ gradle 설정

=>

ㄴ gradle 재설정 해주기

=>

테스트 서버 준비하기

=>

=>

=>

 

패키지 및 클래스 준비

ㄴ eomcs.servlet.ex01 패키지 생성

 

ㄴ Servlet01 클래스 파일 생성

 

Servlet01.java

package eomcs.servlet.ex01;

// 서블릿 만들기 - javax.servlet.Servlet 인터페이스 구현
import java.io.IOException;
import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

// 서블릿 클래스를 만든 후, 서블릿 컨테이너에 등록해야만 사용할 수 있다.
// 등록 방법 1)
// 웹 애플리케이션 배치 파일(web.xml; DD(Deploy Description) 파일)에 서블릿 정보를 등록한다.
// => WEB-INF/web.xml
// => DD File: Deployment Descriptor File
// => 배치 예:
// <servlet>
// <servlet-name>서블릿별명</servlet-name>
// <servlet-class>서블릿 클래스의 전체이름(패키지명 포함)</servlet-class>
// </servlet>
//
// <servlet-mapping>
// <servlet-name>서블릿별명</servlet-name>
// <url-pattern>클라이언트에서 요청할 때 사용할 URL(/로 시작해야 한다.)</url-pattern>
// </servlet-mapping>
// 등록 방법 2)
// 서블릿 클래스 선언부에 @WebServlet 애노테이션을 붙인다.
// => @WebServlet
// @WebServlet(URL)
// @WebServlet(value=URL)
// @WebServlet(urlPatterns={"URL1", "URL2", ...})
//
// 서블릿 실행 방법
// => http://서버주소:포트번호/웹애플리케이션이름/서블릿URL
// 예) http://localhost:8080/eomcs-java-web/ex01/s01
//
// 서블릿 구동 과정
// 1) 웹 브라우저가 서블릿 실행을 요청한다.
// 2) 서블릿 컨테이너는 해당 URL의 서블릿 객체를 찾는다.
// 3.1) 서블릿 객체를 아직 만들지 않았다면,
// => 서블릿 클래스에 대해 인스턴스를 생성한다.
// => 생성자를 호출한다.
// => init()를 호출한다.
// => service()를 호출한다.
// 3.2) 서블릿 객체가 생성되어 있다면,
// => service()를 호출한다.
//
// 만약 웹 애플리케이션이 종료된다면
// => 생성된 모든 서블릿들의 destroy() 메서드를 호출한다.
//
// 결론!
// => 특별한 옵션을 주지 않으면 클라이언트가 최초로 요청했을 때 서블릿 인스턴스를 생성한다.
// => 그리고 그 서블릿 인스턴스는 클래스 마다 오직 한 개만 생성된다.
// => init(), destroy()은 오직 한 번만 호출된다.
// => service()는 클라이언트가 요청할 때 마다 호출된다.
//
// 주의!
// => 서블릿 인스턴스는 오직 클래스 마다 한 개만 생성된다.
// 그래서 모든 클라이언트가 같은 서블릿 인스턴스를 사용한다.
// => 클라이언트마다 구분되어야 할 데이터는
// 서블릿 인스턴스 변수에 보관해서는 안된다.
// => 왜?
// 인스턴스는 모든 클라이언트가 공유하기 때문이다.
//

@WebServlet("/ex01/first")
public class Servlet01 implements Servlet {

  ServletConfig config;

  public Servlet01() {
    System.out.println("Servlet01()");
  }

  @Override
  public void init(ServletConfig config) throws ServletException {
    // 서블릿 객체를 생성한 후 생성자 다음에 이 메서드가 호출된다.
    // => 서블릿을 실행할 때 사용할 자원을 이 메서드에서 준비한다.
    // => 파라미터로 받은 ServletConfig 객체는 인스턴스 변수에 보관해 두었다가 필요할 때 사용한다.
    // => 각각의 서블릿 클래스마다 객체는 한 개만 생성된다.
    // => 따라서 각 서블릿에 대해 init()는 한 번만 호출된다.
    this.config = config;
    System.out.println("Servlet01.init(ServletConfig)");
  }

  @Override
  public void service(ServletRequest req, ServletResponse res)
      throws ServletException, IOException {
    HttpServletRequest req2 = (HttpServletRequest) req;
    HttpServletResponse res2 = (HttpServletResponse) res;
    // 클라이언트가 이 서블릿의 실행을 요청할 때마다 호출된다.
    // 클라이언트가 요청한 작업을 수행한다.
    System.out.println("Servlet01.service(ServletRequest,ServletResponse)");
  }

  @Override
  public void destroy() {
    // 웹 애플리케이션을 종료할 때(서버 종료 포함) 호출된다.
    // => 이 서블릿이 만든 자원을 해제하는 코드를 이 메서드에 둔다.
    System.out.println("Servlet01.destroy()");
  }

  @Override
  public ServletConfig getServletConfig() {
    // 서블릿에서 작업을 수행하는 중에 서블릿 관련 설정 정보를 꺼낼 때 이 메서드를 호출한다.
    // 이 메서드가 리턴하는 값이 ServletConfig 객체인데
    // 이 객체를 이용하면 서블릿 설정 정보를 알 수 있다.
    // 보통 init()의 파라미터 값을 리턴한다.
    System.out.println("Servlet01.getServletConfig()");
    return this.config;
  }

  @Override
  public String getServletInfo() {
    // 서블릿 컨테이너가 관리자 화면을 출력할 때 이 메서드를 호출한다.
    // 이 메서드의 리턴 값은 서블릿을 소개하는 간단한 문자열이다.
    System.out.println("Servlet01.getServletInfo()");
    return "Servlet01";
  }

}

=>

=>

=>

 

 

=>

 

=>

=>

=>

=>

web.xml

=>

ㄴ 톰캣 경로에 있는 web.xml 파일 VsCode 로 열기

=>

ㄴ 해당 코드 복사

=>

servlet-app

web.xml

ㄴ 복사한 코드 붙여넣기

=>

servlet-app

web.xml

=>

=>

=>

=>

servlet-app

web.xml

ㄴ metadata-complete 를 "false" 로 변경해줌

=>

=>

=>

=>

=>

=>

ㄴ Servers 탭에 있는 우측에 빨간 정지버튼 선택 시 아래와 같이 출력됨

=>

 

 

서버 restart

=>

ㄴ 브라우저에서 요청할 때마다 위와 같이 출력됨을 확인

=>

servlet-app

web.xml

 

 

ㄴ Servlet02 클래스 파일 생성

 

Servlet02.java

// 서블릿 만들기 - javax.servlet.GenericServlet 추상 클래스 상속
package eomcs.servlet.ex01;

import java.io.IOException;
import javax.servlet.GenericServlet;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebServlet;

// GenericServlet 추상 클래스
// => javax.servlet.Servlet 인터페이스를 구현하였다.
// => service() 메서드만 남겨두고 나머지 메서드들은 모두 구현하였다.
// => 따라서 이 클래스를 상속 받는 서브 클래스는 service() 만 구현하면 된다.
//
// @WebServlet 애노테이션
// => web.xml 에 서블릿 정보를 설정하는 대신에
// 이 애노테이션을 사용하여 서블릿을 설정할 수 있다.
// => 이 애노테이션을 활성화시키려면
// web.xml의 <web-app> 태그에 다음 속성을 추가해야 한다.
// metadata-complete="false"
// 속성의 값은 false 여야 한다.
//
// @WebServlet(urlPatterns={"/ex01/s2","/ex01/ss2","/ex01/sss2"})
// @WebServlet(urlPatterns={"/ex01/s2"})
// @WebServlet(urlPatterns="/ex01/s2")
// @WebServlet(value="/ex01/s2")
@WebServlet("/ex01/s2")
public class Servlet02 extends GenericServlet {

  // GenericServlet 추상 클래스는 java.io.Serialize 인터페이스를 구현하였다.
  // => serialVersionUID 변수 값을 설정해야 한다.
  private static final long serialVersionUID = 1L;

  public Servlet02() {
    System.out.println("Servlet02()");
  }

  @Override
  public void service(ServletRequest req, ServletResponse res)
      throws ServletException, IOException {
    System.out.println("Servlet02.service(ServletRequest,ServletResponse)");
  }
}

 

ㄴ Servlet03.java 클래스 파일 생성

=>

Servlet03.java

=>

Servlet03.java

=>

Servlet03.java

=>

Servlet03.java

 

=>

=>

=>

=>

 

Servlet03.java

=>

=>

=>