Posts 학원 #85일차:서블릿 프로그래밍, WAS, JavaEE와 Servlet 컨테이너, Servlet 인터페이스의 Life-cycle 메서드
Post
Cancel

학원 #85일차:서블릿 프로그래밍, WAS, JavaEE와 Servlet 컨테이너, Servlet 인터페이스의 Life-cycle 메서드

서블릿 프로그래밍

  • 웹 애플리케이션 서버 아키텍쳐의 개념
  • JavaEE와 Servlet API의 관계
  • JavaEE 구현체와 서블릿 컨테이너의 관계
  • eomcs-web-project/src-00 예제 실습
  • Servlet 인터페이스와 Life-cycle 메서드

WAS(Web Application Server) 아키텍처

image

이전까지는 사용자가 본인의 컴퓨터에 앱을 설치하고 그 앱에서 공통의 DBMS에 접근하여 데이터를 수정, 변경, 조회, 삭제했다. 그러나 이렇게 각각 앱을 설치한다면, 앱에 기능이 추가될 때마다 사용자들이 재설치를 해야 하기 때문에 번거롭다는 문제가 있다.

과거에는 기능을 1년이나 2년 간격으로 업데이트를 했기 때문에 이렇게 재설치를 해도 많이 번거로움이 덜하였다. 그러나 세계화로 인해 경쟁이 가속화었고, 이로 인해 제품의 생명 주기가 짧아졌다. 생명 주기가 짧아지면서 회사의 조직 변경이 잦아지고, 업무 변경이 잦아졌으며, 이로 인해 어플리케이션의 변경이 잦아졌다. 앱의 변경이 잦으니 사용자들이 변경이 있을 때마다 재설치를 하는 것은 불가능에 가까워졌다.

이제 사용자는 클라이언트 프로그램을 가지고 서버에 접속해서 작업을 수행하는 것으로 바뀐다. 그러나 모든 작업은 서버에서 이루어진다. 그리고 이 서버 앱이 DBMS와 소통한다. 이것을 Application Server Architecture 라고 한다. 기능 추가를 클라이언트 앱에 할 필요 없이 Server App에만 추가하면 된다. 따라서 재설치가 필요 없다. 그러나 단점도 있다. 여러 클라이언트가 붙어야 하기 때문에 멀티스레딩, 네트워크가 필요하다. 그리고 UI를 어떻게 할 지에 대한 문제도 있다.

image

image

Client App과 Server App과의 소통을 할 때 각 회사마다 자신들의 소통 방식, 즉 프로토콜이 있을 것이다. 그러나 이렇게 각 회사마다 프로토콜을 가지고 있다면 일관성이 떨어지고, 개발자가 다른 회사의 앱을 개발할 때마다 각기 다른 규칙을 계속 배워야 할 것이다. 이 문제를 어떻게 해결할 수 있을까?

이미 네트워크 통신을 할 이 있고, 모든 사용자의 컴퓨터에는 운영체제가 설치될 때 기본으로 깔린 웹 브라우저가 존재한다. 웹 브라우저는 Web Server와 통신하는데, 기본적으로 HTTP라는 통신규칙에 따라 소통을 한다. 즉 프로토콜을 새로 만들 필요가 없다. 기존에 있는 웹 프로토콜을 그대로 쓰면서 App을 만들려고 하는 것이다. 또한 웹 브라우저를 위한 HTML, CSS, JS라는 UI 기술이 이미 존재한다. UI는 이 기술을 통해 구현하면 된다. 즉 서버 쪽 개발자는 웹 브라우저로부터 요청이 들어오면 실행할 서버 프로그램(앱)을 만들고, UI는 HTML, CSS, JS에 따라 출력하면 된다. 뿐만 아니라 웹 서버를 사용하면 이제 멀티스레딩, 네트워킹에 대해서는 더이상 신경쓰지 않아도 된다. 웹 서버가 알아서 이 문제를 처리하기 때문이다. 단 웹 브라우저로부터 요청이 들어오면 실행할 서버 프로그램(앱)을 만들어야 한다. 어플리케이션 아키텍처인데, 특히 Web Application Server Architecture라고 한다. 이것을 줄여서 WAS라고 한다.

HTML, CSS, JS라는 기술을 배우는 대가만 치른다면 더이상 네트워크 프로그램을 직접 짤 필요가 없다. 이전에 DBMS를 사용함으로써 파일입출력의 수고로움으로부터 해방된 대신 SQL과 JDBC(-> mybatis)를 배워야 한 것과 비슷한 흐름이다.

무슨 프로그래밍 언어를 쓰느냐의 문제지, 웹 어플리케이션 서버 구조는 전 세계에 99퍼센트를 차지한다. 아주 특별한 경우만 고유한 프로토콜에 따라 직접 소통하도록 코드를 짠다. 대표적인 예시가 JDBC이다. JDBC는 전용 프로토콜을 사용해 DBMS과 App 사이에 소통한다.

image

여기서 Application Server의 역할은 Application의 생성, 실행, 소멸을 관리하는 것이다. 이전 PMS 프로젝트에서는 ServerAppApplication Server의 역할을 담당했다. ServerApp에서 Command 객체를 호출(실행)하였다.

image

자바 웹 어플리케이션 서버 기술은 어플리케이션 서버에서 어플리케이션을 사용하는 규칙(호출 규칙)을 정의하였다. 이 규칙이 바로 Servlet API이다. 서블릿 API규칙에 따라 자바 코드로 Application Server를 구현하고, Application Server에서 호출할 Application을 구현해야 한다.

image

마치 JDBC API가 있고, Vendor 개발자가 이 JDBC API에 따라 JDBC Driver를 개발해야 하고, 우리가 그 호출 규칙에 따라 Application을 개발해야 하는 것과 같다. 호출 규칙에 맞아야 Application이 JDBC Driver를 호출할 수 있다(사용할 수 있다). 여기서 Vendor 개발자는 Callee를 구현하는 입장이고, 우리는 규칙에 따라 드라이버의 메서드를 호출하는 Caller를 개발하는 입장이다.

마찬가지로 웹에서는 HTTP 프로토콜에 따라 서비스를 요청하고 응답을 받아 화면을 뿌리는 프론트엔드 개발자가 있고, 사용되는 쪽인 서버 앱 개발자(백엔드 개발자)가 있다. 특히 일반 백엔드 개발자들은 Servlet API에 따라 Application Server가 호출할 Application(Callee)를 개발하는 쪽이다.

image

용어를 정리하고 가자. Servlet API 규칙에 따라 만든 Application을 Servlet이라고 한다. 서블릿이라는 이름이 붙은 까닭은 서버 쪽에서 실행하는 애플리케이션의 작은 조각이라는 의미이기 때문이다. 게시물 추가하기, 수정하기, 조회하기, 삭제하기 등 작은 기능들의 집합인 큰 프로그램에서, 작은 기능에 해당하는 각각의 Servlet들이 있다. 사용자 요청을 실제 처리하는 Servlet을 만드는 것이 우리가 할 일이다. 우리는 Servlet을 배우기 위해서 이때까지 자바를 배운 것이다. 서블릿들의 생성, 실행, 소멸을 담당하는 Appication Server는 Container라는 명칭으로 불린다. 톰캣 서버가 여기에 해당된다.

image

서블릿 API를 구현한 서버를 Servlet Container라고 했다. 이걸 구현한 제품의 목록은 위와 같다. 다 같은 것이 아니라 차이점이 있다. 가장 큰 차이점은 Java EE 기술 중 일부 Web 기술만 구현을 하였는지, 아니면 JavaEE 기술을 100% 구현한 Java EE 구현체(Implements)인지에 달려 있다.

JavaEE와 Servlet API의 관계

image

  • Web 기술

  • Servlet/JSP, JSTL, JSF 기술 등

    즉 서블릿 API는 Java EE의 부분집합이다.

  • 분산 컴포넌트 기술

    • 원격 관련 기술(EJB), Web-Service

      프로그램을 조각조각내서 여러 컴퓨터에 저장하는 것

Java EE는 기업용 Application 제작과 실행에 필요한 기술 모음이다. 여기에는 Servlet/JSP기술, JSTL, JSF 기술 등 Web 기술이 있고, EJB 등 분산 컴포넌트 기술과 관리 보안 기술도 있다. Servlet Container는 그 중 Web 기술만을 구현하였다. 따라서 EJB(원격 관련 기술)로 만든 자바 클래스나, 관리 및 보안 기술로 만든 자바 클래스를 실행할 수 없다. Tomcat, Jetty, Resin이 해당된다. 자바 EE 구현체 서버에는 JEUS, WebLogic, WebSpehere 등이 있다. Servlet/JSP, JSTL, JSF 이 모든 기술을 다 사용한 클래스는 Java EE 구현체만이 실행할 수 있다.

한편, Java ME는 작은(Micro) 디바이스를 위한 프로그램을 개발할 때 사용하는데, 안드로이드가 나오면서 많이 사용하지 않게 되었다. 또한 Java EE는 SE를 포함하고 있지 않는 것을 기억하자. SE와 EE는 개별적이다. Java EE는 서버기술만 존재한다.

implements: 도구(tool)

JavaEE 구현체와 Servlet 컨테이너의 관계

image

EJB라는 기술로 서버를 만든다면(EJB를 구현한 클래스를 짰다면) Servlet Container인 톰캣으로는 실행을 하지 못한다. 그러나 JEUS는 Java EE 기술을 100프로 구현한 Java EE 구현체이기 때문에 해당 Servlet을 실행할 수 있다.

요새는 EJB를 잘 쓰지 않는다. 따라서 웬만한 프로그램은 톰캣 서버를 써도 잘 돌아간다.

image

고객사에 설치되어 있는 웹서버의 버전에 맞게 Java EE의 버전을 선택하여 시스템을 개발하는 것이 중요하다. 만약 Java EE 8을 이용하여 App을 개발하였다고 하자. EE 8에 해당하는 Servlet/JSP 기술은 4.0/2.3이다. 그런데 고객사에 설치되어 있는 Tomcat이 버전 8이라면 고객사에서 실행할 하지 못할 수 있다. Servlet 버전 4.0에서 추가된 인터페이스(메서드)를 구현하였다면 이를 실행하지 못하기 때문이다.

물론 Tomcat은 업그레이드가 무료이기 때문에 고객사에게 업그레이드를 하라고 요구할 수는 있지만, WebLogic이나 WebSphere 같은 유료 서버가 고객사의 시스템에 설치되어 있는데 우리가 짠 코드가 Java EE의 맞지 않는 버전이라고 고객사에게 업그레이드를 요구할 수는 없다. 업그레이드 비용이 많이 들기 때문이다. 따라서 애초부터 고객사에 설치되어 있는 웹서버의 버전에 맞게 Servlet/JSP 기술의 버전을 선택하여 시스템을 개발해야 한다.

PMS 프로젝트

실습

4단계: 기존 프로젝트를 이클립스 용 웹 프로젝트로 전환한다.

build.gradle 변경

기존의 eclipse 플러그인 대신에 eclipse-wtp를 사용한다. 그리고 war 플러그인을 추가한다. 이 두 개의 플러그인이 있어야만 웹 프로젝트에 관련된 설정 파일을 생성할 수 있다.

1
2
3
4
5
plugins {
    id 'java'
    id 'eclipse-wtp' // 'eclipse' 대신에 'eclipse-wtp' 플러그인 사용
    id 'war' //  애플리케이션 배포 파일을 다루기 위해 'war' 플러그인 추가
}

war: web archive의 약자로, 웹 애플리케이션 배포 파일을 다루기 위해 사용한다.

명령창에서 빌드를 해야 할 때도 있다. 이때 윈도우라면 ms949 가 기본이기 때문에 인코딩을 미리 설정해 두도록 하자.

웹 프로젝트에 필요한 라이브러리를 추가한다

image

의존 라이브러리를 추가할 때 앞에 특정 옵션을 붙일 수 있다.

  • implementation: 컴파일한 후 생성되는 빌드 파일에 포함된다. 배포할 때도 사용한다. (컵)
  • compileOnly: 컴파일한 후 생성되는 빌드 파일에 포함되지 않는다. (텀블러)
  • testImplementation: 단위 테스트를 실행할 때만 사용하는 라이브러리이다.

이처럼 dependency 에서 라이브러리의 사용 범위를 지정할 수 있다.

App을 배포를 하기 위해 .war 파일로 포장(패키징)을 한다. 이때 Servlet API는 컴파일할 때만 사용한다. .war 파일에는 포함되지 않는다. 서버에 이미 이 라이브러리가 있기 때문이다.

1
2
3
4
5
6
7
dependencies {
  compileOnly 'javax.servlet:javax.servlet-api:4.0.1'

  implementation 'com.google.guava:guava:28.1-jre'

  testImplementation 'junit:junit:4.12'
}

image

gradle build를 하면 war 파일이 생성된다. 파일 뿐만 아니라 lib안에 라이브러리도 있다. 단 단위테스트 관련 파일(testImplementation)이나 compileOnly 라이브러리는 제외하고 오직 implementation을 한 라이브러리만 여기에 있다. 그리고 webapp 폴더에 있는 파일도 war 파일에 놓인다.

image

이전에는 개발자가 배포를 할 때, 작업을 한 web 프로젝트를 build해서 리눅스 서버에 직접 업로드를 했다. 이럴 경우 개발자가 악의적으로 해킹 코드를 함께 넣어 배포하는 것을 막을 방법이 없었고, 누가 했는지 특정하기가 힘들다는 단점이 있다.

image

현재 실무에서는 개발자가 바로 build해서 배포할 수 없다. 각각의 개발자가 작업을 하고 git 원격 서버에 이를 저장한다. 그리고 리눅스 서버에는 깃 repository를 클론하고 pull하여 가져온다. 그러면 작업을 하는 개발자가 아니라 관리자 또는 배포 담당자가 리눅스 서버에 원격으로 접속하여 build하고 톰캣 서버에 배포한다.

이클립스와 톰캣 서버 연동하기

  • 이클립스에 톰캣 서버 경로 등록하기
    • 이클립스 메뉴 > Window > Preference
    • Server > Runtime Environment > add
    • 톰캣 서버의 디렉토리 등록
  • 이클립스에 웹 프로젝트 실행을 위한 테스트 서버 환경 구축하기
  • 웹 프로젝트를 테스트 서버에 배포하기
  • 테스트 서버 실행하기
  • 이클립스 > Servers 뷰 > 서버 실행 환경 > start 실행
    • /home/bitcamp/eclipse-workspace/.metadata/.plugins/org.eclipse.wst.server.core 폴더
      • tmpX 폴더를 생성한다. : 이클립스에서 publish
      • tmpX/wtpwebapps/ 폴더에 웹 애플리케이션을 배포한다.
    • 배포 대상과 위치
      • 자바 클래스 => wtpwebapps/WEB-INF/classes
        • src/main/java에 있는 모든 소스 파일을 컴파일한다.
        • 클래스 파일(.class)을 해당 폴더에 복사한다.
      • 기타 자원 파일 => wtpwebapps/WEB-INF/classes
        • src/main/resources에 있는 모든 파일을 해당 폴더에 복사한다.
      • 웹 파일 => wtpwebapps/웹애플리케이션폴더/
        • src/main/webapp에 있는 모든 파일을 해당 폴더에 복사한다.
      • 라이브러리 파일 => wtpwebapps/웹애플리케이션폴더/WEB-INF/lib/
        • 프로젝트에서 사용하는 의존 라이브러리 파일(*.jar)을 해당 폴더에 복사한다.

WEB-INF: 웹 인포메이션(정보)

앞에서도 언급했듯 개발이 끝나면 서버의 깃허브에 push한다. 그러면 배포 담당자나 관리자가 원격 서버에 접속해서 github에 있는 저장소를 클론해서 war파일을 만든 후 webapps에 복사하고 startup.sh 명령어를 실행해서 서버를 restart한다.

하지만 공부를 할 때는 매번 이렇게 하기 복잡할 것이니, 이클립스의 배포 자동화 기능을 이용하도록 하자.

배포가 제대로 되었다면 Server View의 해당 서버에 Synchronized가 표시된다. html을 바꾸면 파일이 바뀌었으니 다시 바꾸라고 뜬다(Republish). 서버를 스타트시키면 프로그램이 수정 사항을 반영하여 자동으로 배포한다.

문제상황

가끔 자동으로 배포가 안 될 때가 있다. 그럴 경우 서버를 stop한 후 removepublish하여 프로젝트 폴더를 날린 후 다시 프로젝트를 add하고 publish를 한 후 해당 파일 경로로 들어가서 잘 배포가 되었는지 확인한다.

가끔 클래스 파일이 복사되지 않을 때도 있다. 프로젝트에 !가 뜬다면 설정이 잘못되어 이클립스가 해당 프로젝트를 정상적인 프로젝트로 간주하지 않은 상태이다. 이때는 설정 파일을 밀고 다시 등록하도록 하자(gradle clean => gradle cleanEclipse => gradle eclipse). 만약 그럼에도 느낌표가 사라지지 않는 경우에는 해당 폴더로 직접 가서 .class , .settings, .project, bin, build 폴더를 수작업으로 날리고 gradle eclipse를 한다. 그런 후 이클립스로 와서 refresh를 하고 느낌표가 사라진 것을 확인하자.

가끔 remove를 하고 publish를 했을 때 폴더가 날아가지 않고 일부 파일이 남아 있는 경우가 있다. 이때는 수작업으로 폴더를 날리도록 하자.

두 서버를 동시에 실행할 수는 없다.

이클립스로 톰캣 서버를 실행했을 때는 샘플 어플리케이션은 로딩이 되지 않는다(고양이 화면). 오직 배포한 프로젝트만 서버에 올라간다.

이클립스는 가상의 배포 폴더를 준비해놓고 작성한 프로젝트를 그 배포 폴더로 복사한다. 테스트 서버 환경 구축이라는 말이 이것 때문이다. 즉 server>apach-tomcat>webapps가 아니라 이클립스가 따로 배포 폴더를 만들어놓고 따로 관리를 한다. 원본을 손대지 않는다. 개발자가 개발에 집중하도록 하기 위해서이다. 쓸데없이 메모리 낭비를 하지 않는다. 원본 서버의 경우에는 우리가 관심 없는 ROOT, manager 등의 폴더도 존재한다.

세번째 프로퍼티는 컴파일할 때 jre 1.8에서 실행할 수 있게끔 그 버전으로 컴파일하라는 뜻이다. 대부분 이 소스 파일을 작성할 때 사용할 자바 버전과 실행시킬 JVM의 최소 버전은 같게 한다.

1
2
3
4
5
6
7
8
9
10
11
// 대부분의 자바 프로젝트에 대해 설정하는 옵션
tasks.withType(JavaCompile) {
    // 프로젝트의 소스 파일 인코딩을 gradle에게 알려준다.
    options.encoding = 'UTF-8' 

    // 소스 파일을 작성할  사용할 자바 버전
    sourceCompatibility = '1.8'

    // 자바 클래스를 실행시킬 JVM의 최소 버전
    targetCompatibility = '1.8'
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
dependencies {
  // Thumbnailator 썸네일 생성 라이브러리
  implementation 'net.coobird:thumbnailator:0.4.11'
  
  // Apache의 파일업로드 처리 라이브러리
  implementation 'commons-fileupload:commons-fileupload:1.4'
  
  // Servlet-API
  // => 컴파일 할 때만 사용한다.
  // => 배치할 때는 포함하지 않는다.
  // => 서버에 이미 이 라이브러리가 있기 때문이다.
  compileOnly 'javax.servlet:javax.servlet-api:4.0.1'

  implementation 'jstl:jstl:1.2'

  implementation 'com.google.guava:guava:28.1-jre'

  testImplementation 'junit:junit:4.12'
}

이미지를 올리면 서버 쪽에서 큰 이미지를 가지고 작은 크기로 출력할 때를 대비해서 thumbnail(작은 이미지)을 자동 생성한다.

자바 세계에서는 apache.org 제공 서비스를 안 쓰기는 굉장히 힘들다.

image

Servlet, Filter, Listener는 Servlet API에 따라 만들어야 한다. 마찬가지로, Servlet Container도 호출 규칙에 맞게 작성해야 호출할 수 있다.

서블릿 만들기

서블릿 실행 방법

  • http://서버주소:포트번호/웹애플리케이션이름/서블릿URL
  • 예) http://localhost:8080/eomcs-java-web/ex01/s01

서블릿 구동 과정

  • 웹 브라우저가 서블릿 실행을 요청한다.
  • 서블릿 컨테이너는 해당 URL의 서블릿 객체를 찾는다.
  • 서블릿 객체를 아직 만들지 않았다면, 서블릿 클래스에 대해 인스턴스를 생성한다. 생성자, init(), service() 순으로 호출한다.
  • 서블릿 객체가 생성되어 있다면, service()를 호출한다.
  • 만약 웹 애플리케이션이 종료된다면 생성된 모든 서블릿의 destroy() 메서드를 호출한다.

결론

  • 특별한 옵션을 주지 않으면 클라이언트가 최초로 요청했을 때 서블릿 인스턴스를 생성한다.
  • 그 서블릿 인스턴스는 클래스마다 오직 한 개만 생성된다.
  • init(), destroy()는 오직 한 번만 호출된다.
  • service()는 클라이언트가 요청할 때마다 호출된다.

주의할 점

  • 서블릿 인스턴스는 클래스마다 오직 한 개만 생성된다. 따라서 모든 클라이언트가 같은 서블릿 인스턴스를 사용한다.
  • 클라이언트마다 구분되어야 할 데이터는 서블릿 인스턴스 변수에 보관해서는 안된다.
  • 인스턴스는 모든 클라이언트가 공유하기 때문이다.

image 서블릿 클래스에는 5개의 메서드가 있다. 우선 서블릿 컨테이너가 Servlet 생성자를 호출하여 서블릿을 만들고 init()을 호출한다(생성).그리고 클라이언트 요청이 들어올 때마다 service() 메서드를 서블릿 컨테이너가 호출할 것이다(실행). 그리고 프로그램이 종료되기 전에 마무리작업을 하기 위해서 destroy()를 호출한다(소멸). getServletInfo()는 서블릿 관련 정보를 문자열로 리턴하는 메서드이고, getServletConfig()는 설정 정보를 리턴하는 메서드이다. 두 메서드는 관리 쪽에서 사용한다.

image

서블릿의 라이프사이클 관련 메서드 중 init()은 객체를 생성할 때 생성자를 호출한 후 최초 한 번 호출된다. 이전 PMS 프로젝트에서는 Command 객체를 미리 만들어 놓았다. 그러나 사용하지도 않는 객체를 미리 전부 만들어 놓는 것은 메모리 낭비이다. 반면 Servlet Container는 Servlet들을 사용하는 시점에 만들고 실행한 후, 나중에 같은 커맨드를 호출했을 때 만들어진 객체를 재사용한다. 즉, 클라이언트 요청이 서블릿에 대해 최초로 들어왔을 때, 생성자를 호출하고 init()을 호출한 후에 service()를 호출하여 응답한다. 다음 요청부터는 service()만 호출한다. 그리고 서버 종료 또는 애플리케이션을 종료할 때 인스턴스가 생성된 각 서블릿에 대해서 마무리작업할 수 있도록 destroy()를 호출한다.

init(ServletConfig config)

서블릿 객체를 생성한 후 생성자 다음에 이 메서드가 호출된다. 서블릿을 실행할 때 사용할 자원을 이 메서드에서 준비한다. 파라미터로 받은 ServletConfig 객체인스턴스 변수에 보관해 두었다가 필요할 때 사용한다. 각각의 서블릿 클래스마다 객체는 최초 요청 시 한 개만 생성되고, 다음 요청부터는 이를 재활용한다. 따라서 각 서블릿에 대해 init()한 번만 호출한다.

1
2
3
4
5
6
  @Override
  public void init(ServletConfig config) throws ServletException {
    this.config = config;
    System.out.println("Servlet01.init(ServletConfig)");
  }

service(ServletRequest req, ServletResponse res)

가장 핵심적인 메서드로, 실제 수행할 작업에 대한 코드가 들어 있다. 클라이언트가 이 서블릿의 실행을 요청할 때마다 호출된다. 클라이언트가 요청한 작업을 수행한다

1
2
3
4
5
@Override
public void service(ServletRequest req, ServletResponse res)
  throws ServletException, IOException {
  System.out.println("Servlet01.service(ServletRequest,ServletResponse)");
}

destroy()

웹 애플리케이션을 종료할 때(서버 종료 포함) 호출한다. 이 서블릿이 만든 자원을 해제하는 코드를 이 메서드에 둔다.

9시가 되면 마무리 작업을 할 수 있도록 매니저가 학생들에게 destroy()를 호출한다.

1
2
3
4
@Override
public void destroy() {
  System.out.println("Servlet01.destroy()");
}

getServletConfig()

서블릿에서 작업을 수행하는 중에 서블릿 관련 설정 정보를 꺼낼 때 이 메서드를 호출한다. 이 메서드가 리턴하는 값이 ServletConfig 객체인데 이 객체를 이용하면 서블릿 설정 정보를 알 수 있다. 보통 init()의 파라미터 값을 리턴한다.

그래서 init()에서 파라미터 값을 애써 준 것을 버리지 말고 인스턴스 필드에 잘 보관해놓고 있다가 누가 나한테 “그것 좀 줘봐” 하면 주도록 한다.

1
2
3
4
5
@Override
public ServletConfig getServletConfig() {
  System.out.println("Servlet01.getServletConfig()");
  return this.config;
}

getServletInfo()

서블릿 컨테이너가 관리자 화면을 출력할 때 이 메서드를 호출한다. 이 메서드의 리턴값은은 서블릿을 소개하는 간단한 문자열이다.

1
2
3
4
5
@Override
public String getServletInfo() {
  System.out.println("Servlet01.getServletInfo()");
  return "Servlet01";
}

image

서블릿의 배포

DD file에 배포정보 설정

image

서블릿 클래스를 만든 후, 배치 파일(web.xml; DD파일)에 서블릿 정보를 등록해야만 실행할 수 있다.

  • DD파일 위치:src/main/webapp/WEB-INF/web.xml
  • DD File: Deployment Descriptor File: 어떻게 리소스를 배치해야 할 지 결정하는 파일을 말한다.

배치 예

1
2
3
4
5
6
7
8
9
<servlet>
  <servlet-name>서블릿별명</servlet-name>
  <servlet-class>서블릿 클래스의 전체이름(패키지명 포함)</servlet-class>
</servlet>

<servlet-mapping>
  <servlet-name>서블릿별명</servlet-name>
  <url-pattern>클라이언트에서 요청할 때 사용할 URL(/로 시작해야 한다.)</url-pattern>
</servlet-mapping>
1
2
3
4
5
6
7
8
9
10
11
<!-- 서블릿 등록 -->
<servlet>
  <servlet-name>s01</servlet-name>
  <servlet-class>com.eomcs.web.ex01.Servlet01</servlet-class>
</servlet>

<!-- 서블릿을 실행할 때 사용할 URL path를 설정 -->  
<servlet-mapping>
  <servlet-name>s01</servlet-name>
  <url-pattern>/ohora/haha</url-pattern>
</servlet-mapping>

@WebServlet 애노테이션으로 배포 정보 설정

  • web.xml에 서블릿 정보를 설정하는 대신에 이 애노테이션을 사용하여 서블릿을 설정할 수 있다.
  • 이 애노테이션을 활성화시키려면 web.xml<web-app> 태그에 metadata-complete="false" 속성을 추가해야 한다. 속성의 값은 false여야 한다.

  • 서블릿 컨테이너가 객체를 저장할 때 이 이름으로 저장할 뿐만 아니라 이 객체를 찾을 때도 클라이언트가 요청한 이름으로 찾아 service를 호출한다.
1
2
@WebServlet("/ex01/first")
public class Servlet01 implements Servlet {

브라우저에는 http://localhost:8080/bitcamp-web-project/ex01/first을 주소창에 치면 접근할 수 있다.

This post is licensed under CC BY 4.0 by the author.

HTML5 CSS3 웹 표준의 정석 #6장: 텍스트 관련 스타일

DEVIL: mysql의 datatime 타입과 java.util.Date 클래스

Loading comments from Disqus ...