Leeyebin의 블로그

3장 서블릿 프로그래밍 본문

공부 기록실/JAVA 웹 개발 워크북 요약정리

3장 서블릿 프로그래밍

안되면될때까지 2017. 4. 5. 10:58


3.1 CGI 프로그램과 서블릿


CGI의 이해

웹 서버와 프로그램 사이의 데이터를 주고받는 규칙을 CGI(Common Gateway Interface)


CGI 프로그램

컴파일 방식은 기계어로 번역된 코드를 바로 실행하기 때문에 실행 속도가 빠르지만, 변경 사항이 발생할 때마다 다시 컴파일하고 재배포할 수 있다.

스크립트 방식은 실행할 때마다 소스 코드의 문법을 검증하고 해석해야 해서 실행 속도가 느리고, 변경 사항이 발생하면 소스 코드를 수정하고 저장만하면 된다.


서블릿

자바  CGI 프로그램은 컴파일 방식 / 자바로 만든 CGI 프로그램을 '서블릿(Servlet)'이라고 부른다. 자바 서블릿이 다른 CGI 프로그램과 다른 점은, 웹 서버와 직접 데이터를 주고받지 않고 전문 프로그램에 의해 관리된다.


서블릿 컨테이너(서블릿의 생성, 실행, 소멸 등 생명주기를 관리하는 프로그램)



3.2 Servlet, JSP vs JavaEE vs WAS


Java EE 기술들

Java EE는 기능 확장이 쉽고, 이기종 간의 이식이 쉬우며, 신뢰성과 보안성이 높고, 트랜잭션 관리와 분산 기능을 쉽게 구현할 수 있는 기술을 제공한다. 기업용 애플리케이션과 클라우드 애플리케이션 개발에 필요한 여러가지 기술들을 모아 놓은 것이다.

Java EE 기술 중에 서블릿, JSP는 웹을 기반으로 한 클라이언트, 서버 기술을 정의하고 있다.


WAS의 이해

클라이언트 서버 시스템 구조에서 서버 쪽 애플리케이션의 생성과 실행, 소멸을 관리하는 프로그램을 애플리케이션 서버라 한다. 그리고 서블릿 컨테이너와 같이 웹 기술을 기반으로 동작되는 애플리케이션 서버를 'WAS(Web Application Server)'라 부른다.

특히 Java에서 말하는 WAS란, Java EE 기술 사양을 준수하여 만드 서버를 가리킨다. 'Java EE 구현체'라고도 말한다.

ex: 제우스, WebLogic, WebSphere, JBoss 등


서블릿 컨테이너

Java EE 기술 중에서 서블릿, JSP 등 웹 관련 부분만 구현한 서버도 있다.)서블릿 컨테이너 또는 웹 컨테이너라고 부름) ex: Resin, Jetty 등


3.3 웹 프로젝트 준비



Generate web.xml deployment descriptor 체크박스는 배치 설명서 파일을 자동 생성하도록 체크 상자를 선택할 수 있다. WEB-INF 폴더에 web.xml 파일이 자동 생성된다.



웹 프로젝트 폴더 구조

src

자바 소스 파일을 두는 폴더이다. 서블릿 클래스나 필터, 리스너 등 필요한 모든 자바 클래스 파일이 들어감.(.properties)


build / classes

컴파일된 자바 클래스 파일(.class)이 놓이는 폴더이다. 패키지에 소속된 클래스인 경우 이 폴더에 해당 패키지가 자동으로 만들어진다.


WebContent

HTML(.html), CSS(.css), JavaScript(.js), JSP, 이미지 파일 등 웹 콘텐츠를 두는 폴더이다. 웹 애플리케이션을 서버에 배치할 때 이 폴더의 내용물이 그대로 복사된다.


WebContent / WEB-INF

웹 애플리케이션의 설정과 관련된 파일을 두는 폴더이다. 이 폴더에 있는 파일은 클라이언트에서 요철 할 수 없다. 따라서 HTML이나 JavaScript, CSS 등 클라이언트에서 요청할 수 있는 폴더에 두면 안된다.


WebContent / WEB-INF / web.xml

웹 애플리케이션 배치 설명서(Deployment Descriptor) 파일이다. DD파일이라고도 부른다. 서블릿이나 필터, 리스너, 매개변수, 기본 웹 페이지 등 웹 애플리케이션 컴포넌트들의 배치 정보를 이 파일에 작성한다.


WebContent / WEB-INF / lib

자바 아카이브 파일(.jar)을 두는 폴더이다. 아카이브 파일은 클래스 파일(.class)과 프로퍼티 파일(.properties)들을 모아 놓은 보관소 파일이다.


3.4 서블릿 만들기

package lesson03.servlets;

import java.io.IOException;

import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

public class HelloWorld implements Servlet {
	ServletConfig config;
	
	@Override
	public void init(ServletConfig config) throws ServletException {
		System.out.println("init");
		this.config = config;
	}

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

	@Override
	public void destroy() {
		System.out.println("destroy");
	}

	@Override
	public ServletConfig getServletConfig() {
		return this.config;
	}

	@Override
	public String getServletInfo() {
		return "HelloWorld Servlet";
	}
}

javax.servlet.Servlet 인터페이스

서블릿 클래스는 반드시 javax.servlet.Servlet 인터페이스를 구현해야 한다. 서블릿 컨테이너가 서블릿에 대해 호출할 메서드를 정의한 것이 Servlet 인터페이스이다.


서블릿의 생명주기와 관련된 메서드 : init(), service(), destroy()


init()는 서블릿 컨테이너가 서블릿을 생성한 후 초기화 작업을 수행하기 위해 호출하는 메서드이다. 서블릿이 클라이언트의 요청을 처리하기 전에 준비할 작업을 작성한다. 서블릿 컨테이너는 클라이언트로부터 요청을 받으면 해당 서블릿을 찾아본다. 만약 없다면 해당 서블릿의 인스턴스를 생성하고 한 번 서블릿 객체가 생성되면 웹 애플리케이션을 종료할 때까지 계속 유지한다.

ps 인스턴스 변수에 특정 사용자를 위한 데이터를 보관해서는 안 된다. 또한 클라이언트가 보낸 데이터를 일시적으로 보관하기 위해 서블릿의 인스턴스 변수를 사용해서도 안 된다.


service()는 클라이언트가 요청할 때 마다 호출되는 메서드이다.


destroy()는 서블릿 컨테이너가 종료되거나 웹 애플리케이션이 멈출 때, 또는 해당 서블릿을 비활성화 시킬 때 호출된다.


Servlet 인터페이스 기타 메서드 : getServletConfig(), getServletInfo()

getServletConfig()는 서블릿 설정 정보를 다루는 ServletConfig 객체를 반환한다.(서블릿 이름, 초기 매개변수 값, 환경정보)

getServletInfo()는 서블릿을 작성한 사람에 대한 정보, 서블릿 버전, 권리 등을 담은 문자열을 반환한다.




  web03
  
  //서블릿 선언
  
  	Hello //서블릿 별명을 설정
  	lesson03.servlets.HelloWorld //패키지 이름을 포함한 서블릿 클래스명을 설정
  
  
  //서블릿을 URL과 연결
   //서블릿과 URL을 매핑할 때 사용
  	Hello //서블릿 별명을 설정(위에서 작성한 별명과 동일하도록)
  	/Hello //서블릿을 요청할 때 클라이언트가 사용할 URL을 설정 /Hello에서 '/'는 컨텍스트 루트를 의미함
  

  
   //웰컴 파일들이란 디렉토리의 기본 웹 페이지
    index.html
    index.htm
    index.jsp
    default.html
    default.htm
    default.jsp
  


web.xml 규칙은 JSP요약부분을 참고할 것 : http://leeyebin.tistory.com/8


서블릿 구동 절차


이미지 출처 ; https://www.tutorialspoint.com/servlets/servlets-life-cycle.htm



3.5 웹 애플리케이션의 배치

웹 애플리케이션을 서블릿 컨테이너에 배치하는 방법들

  • 이클립스를 통한 자동 배치
    • Servers 뷰의 컨텍스트 메뉴를 통해서 배치
    • 톰캣 실행 환경 설정창에서 웹 애플리케이션 배치

톰캣 실행 환경의 임시 배치 폴더
작업하는 워크스페이스 폴더에서 .metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/*

Servers 뷰에 등록된 톰캣 서버에 프로젝트를 추가하고 실행하면 이클립스에서 자동으로 웹 애플리케이션을 배치한다. 이때 배치 폴더는 워크스페이스 폴더에 있는 WTP(Web Tools Platform) 플러그인이 관리하는 임시 폴더이다.

운영 서버에 배치하기
이클립스에서 [File] - [Export] [Web]-[WAR file] 선택
만들어진 WAR파일을 톰캣이 있는 폴더의 webapps폴더에 넣고 start.up.bat(sh) 종료는 shutdown.bat(sh)


3.6 GenericServlet의 사용

GenericServlet이 없던 시절

서블릿을 만들 때마다 Servlet 인터페이스에 선언된 메서드를 모두 구현하였다. 사실 메서드 중에서 반드시 구현해야 하는 메서드는 service()이다. 클라이언트가 요청할 때마다 호출되기 때문이다. 나머지 메서드들은 상황에 따라 구현하지 않아도 된다. 하지만 '인터페이스를 구현하는 클래스는 반드시 인터페이스에 선언된 모든 메서드를 구현해야 한다'라는 자바의 규칙이기 때문에 빈 메서드라도 구현해야 한다.

이러한 불편한 점을 해소하기 위해 등장한 것이 GenericServlet 추상 클래스이다.


GenericServlet의 용도

서블릿 클래스가 필요로 하는 init(), destroy(), getServletConfig(), getServletInfo()를 미리 구현하여 상속해 준다. service()는 어차피 각 서블릿 클래스마다 별도로 구현해야 하기 때문에 GenericServlet에서는 구현하지 않도록한다. (그냥 쉽게말해 override해서 쓰면 된다)

참고 : https://docs.oracle.com/cd/E17802_01/products/products/servlet/2.1/api/javax.servlet.GenericServlet.html


ServletRequest

service()의 매개변수 중에서 ServletRequest 객체는 클라이언트의 요청 정보를 다룰 때 사용한다.


ServletRequest의 주요 메서드

이미지 출처 : http://insomniasoo.com/trac/MyLib/wiki/JspRequest


참고 : http://docs.oracle.com/javaee/6/api/javax/servlet/ServletRequest.html



ServletResponse

응답과 관련된 기능을 제공한다.(클라이언트에게 출력하는 데이터 인코딩 타입 설정, 문자집합 지정, 버퍼 크기 조정, 출력 스트림을 준비)


setContentType() - 출력할 데이터의 인코딩 형식과 문자 집합을 지정한다.

ex) response.setContentType("text/plain");


setCharacterEncoding()

출력할 데이터의 문자 집합을 지정한다.

ex) response.setCharacterEncoding("UTF-8");


getWriter()

클라이언트로 출력할 수 있도록 출력 스트림 객체를 반환한다. 이미지나 동영상과 같은 바이너리 데이터 출력을 위해서는 getOutputStream()

ex) printWriter writer = response.getWriter();

주의 - getWriter()를 호출하기 전에 setContentType()이나 setCharacterEncoding()을 호출해야 정상적으로 유니코드가 지정된 문자 집합으로 변환된다.


GET 요청으로 넘어온 매개변수 값의 인코딩 설정

GET 요청은 매개변수 값이 URI에 포함되기 때문에 setCharacterEncoding()으로는 문자 집합을 설정 할 수 없다. 서블릿 컨테이너에서 권고하는 지침에 따라 URI의 인코딩 형식을 설정해야한다.(<Connector>태그에 URIEncoding 속성을 추가한다.)


@webServlet 애노테이션을 이용한 서블릿 배치 정보 설정

이 애노테이션을 이용하면 web.xml에 있는 mapping 부분을 하지 않아도 된다.

@WebServlet("/calc") //괄호 안에 기술한다.
public class CalculatorServlet Extends GenericServlet{
}

@WebServlet 애노테이션의 주요 속성
//ex)
//name = "서블릿의 이름을 성정하는 속성. 기본값은 빈 문자열("")
@WebServlet(name = "서블릿이름")

//urlPatterns = "URL 목록을 설정하는 속성. 속성값으로는 String 배열이 온다. 기본값은 빈 배열({})이다.
//ex)
//서블릿에 대해 한 개의 URL을 설정하는 경우
urlPatterns="/calc" //일반적인 문자열로 표기 가능
urlPatterns={"/calc"} //중괄호를 사용하여 배열 표기
//서블릿에 대해 여러 개의 URL을 설정하는 경우
@urlPatterns={"/calc", "calc.do", "calculator.action"}

//value = "urlPatterns와 같은 용도. 속성 이름이 'value'인 경우는 속성 이름 없이 값만 설정할 수 있다.
value="/calc"
//"/calc" 속성명 'value' 생략 가능
//value 속성 외에 다른 속성의 값도 함께 설정하면 value 속성의 이름을 생략할 수 없다.


Comments