4 minute read

서블릿 기본 구조

서블릿은 Server+Applet의 합성어로, 자바 코드 내부에 html 문서를 품고 있는 형태를 보인다!

  • 서블릿 : HttpServlet클래스(javax.servlet.http 패키지에서 제공하는 클래스)를 상속 받아 만든 서브 클래스
  1. 서블릿을 요청하기 위한 URL

https://github.com/hy6219/TIL-Today-I-Learned-/blob/main/JSP%20Servlet/Basic/%EC%84%9C%EB%B8%94%EB%A6%BF%EC%9D%84%20%EC%9A%94%EC%B2%AD%ED%95%98%EA%B8%B0%20%EC%9C%84%ED%95%9C%20url.png?raw=true

서블릿을 요청하기 위한 URL

서블릿을 요청하기 위한 url(우리가 서블릿 파일을 작성해서 실행하면 뜨는 주소)는 위와 같은 형식을 지닌다. 각각 어떤 의미를 지니는지 조목조목 뜯어보자

🍑 서블릿 요청 url 패턴은 jsp파일에 대한 요청이 있을 경우, hello.jsp 등으로 표시된다!(jsp 요청)

1) http://localhost - 웹 서버에 접속하기 위한 IP주소 [localhost의 ip 주소는 127.0.0.1]

2) : 8181 - 톰캣을 설치하면서 설정한 포트번호

  • /myProject : 컨텍스트 패스(Context Path)

*웹 서버에서 제공하는 다양한 웹 어플리케이션 중 어떤 어플리케이션을 수행할 것인지를 구분하기 위해 사용되는 개념

*컨텍스트 패스 == 프로젝트 이름 == 소스가 있는 경로 == context root에서 입력한 값!

*톰캣 서버에 웹 어플리케이션 등록하기[server.xml 파일]

(이클립스에서는 자동으로 작성되는데, ctrl+shift+F 혹은 source-Format을 이용하여 들여쓰기 처리하여 한 줄로 작성된 부분을 구조화해서 확인 가능)

<Context docBase="프로젝트명" path="/프로젝트명" reloadable="true" 
source="org.eclipse.jst.jee.server:컨텍스트패스명" />

위의 한 줄에서 path에 /프로젝트명 으로 기록을 해둠으로써 톰캣서버입장에서 컨텍스트 패스를 인식할 수 있게 된다!

  • Content directory : 웹 프로그래밍을 하면서 새롭게 만들어지는 jsp 페이지나 이미지와 같은 자원(content)를 저장해두는 경로
  1. URL 매핑(@WebServlet 어노테이션) && 직렬화를 통한 클래스 버전에 따른 고유 번호 포함 &&

    public + HttpServlet

package unit01;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

**📌@WebServlet("/hello")📌**
⚠️**public class HelloServlet extends HttpServlet**⚠️ {
	🌟**private static final long serialVersionUID = 1L;//클래스 버전 고유번호**🌟
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public HelloServlet() {
        super();
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		response.getWriter().append("Served at: ").append(request.getContextPath());

	
	}

}

a) URL 매핑(필수)!

  • 서블릿을 동작시키기 위해서 실제 자바 클래스명을 사용하는 대신 서블릿을 요청하기 위한 문자열을 서블릿 클래스와 매핑시키는 것
  • 쉽게 말하면, 서블릿 클래스의 별칭!
  • 사용 목적 :

    -실제 서블릿 클래스를 공개하지 않기 위함(보안)

    -실제 물리적 위치 정보가 아니기 때문에 사용자가 실제 경로와 파일명을 직접 입력할 필요가 없음

    -개발자가 서블릿 이름을 바꾸더라도 사용자는 동일 url로 접근 가능

  • 사용 방법 : @WebServlet 어노테이션으로 매핑 가능(servlet 3.0~)
  • 서블릿 3.0 이전에는 web.xml에서 매핑하였는데, 이로 인한 불편함이 존재했음
  • 이클립스에서는 서블릿을 생성할 때, URL Mapping 탭에서 수정하여 적용 가능

🌟어노테이션 : 컴파일할 때 환경 설정을 변경해줄 것을 알려주는 주석 형태🌟

b) 직렬화

🌟로 표시된 부분을 보면,

private static final long serialVersionUID =1L;

로 되어 있는데, 이 부분을 통해서 프로그램 간의 동기화 등 문제를 해결해줄 수 있다

c) HttpServlet 클래스를 구현한 서브 클래스를 public으로 제한자 설정

  • ⚠️로 된 부분을 참고하면, public으로 HttpServlet 클래스를 구현한 서브클래스에 대한 접근을 제한시켜두었는데, 그 이유는 브라우저를 통해 외부에서 실행되기 때문!
  1. 요청 메서드 doGet(), doPost()
  • 요청 방식에 따라서 doGet(), doPost()가 수행되기 때문에 적절하게 오버라이딩해주어야 함

각각의 메서드는 모두 각각 매개변수로 요청과 응답을 의미하는

HttpServletRequest 객체와 HttpServletResponse 객체를 전달받는다

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		response.getWriter().append("Served at: ").append(request.getContextPath());
		
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
	}
  • HttpServletRequest: 클라이언트의 요청을 처리 - ServletException, IOException에 대한 예외처리를 해주어야 함(일반적으로 throws를 이용)

  • HttpServletResponse: 요청 처리 결과를 클라이언트에게 되돌리기(응답하기) 위해 사용됨

⚠️ 하나의 서블릿 내에 get 방식, post 방식에 따라 서로 다른 기능을 제공해야 하는 경우는, doGet 메서드와 doPost 메서드 모두 오버라이딩해야 함!

  1. 응답 객체콘텐트 타입 지정하기
HttpServletResponse 객체.setContentType("콘텐트 타입(text/html)");

) response.setContentType("text/html");
  • 서블릿에서는 setContentType()메서드를 이용해서 클라이언트에게 응답할 페이지에 대한 환경설정을 해주어야 하는데,

위의 코드에서는 “text/html” 로 설정해둠으로써, text나 html로 부여주겠다는 의미를 나타냄

  • 서블릿에는 main 메서드가 있는 클래스에서 실행하지 않고, 웹 서버가 실행을 해주는 방식

  • Event-Driven Programming으로 실행됨

사용자 요청 ➡️ 톰캣 서버: 서블릿 객체 생성 ➡️ init() ➡️ 요청 메서드 호출

4-1. 한글 인코딩이 깨지지 않도록 콘텐트 타입을 지정할 때 charset 설정해주기

HttpServletResponse 객체.setContentType("콘텐트 타입; 📌**charset=UTF-8**📌");

) response.setContentType("text/html; charset= UTF-8");
  • 한글이나 한자는 UTF-8 형식을 사용하도록 지정해주어서, 다른 국가에서도 호환이 될 수 있도록 인코딩을 설정해주기
  1. 출력 스트림 얻어오기
  • HttpServletResponse 객체의 인코딩을 설정 하기 전 출력 스트림을 얻어올 경우, 인코딩이 깨진 상태에서 결과를 출력할 수 있기 때문에, 📌꼭! HttpServletResponse 객체의 인코딩을 설정한 후 출력 스트림을 얻어오도록 하자!📌

  • 서블릿에서는 출력스트림인 PrintWriter 객체를 아래와 같이 사용하여 HttpServletResponse 객체로부터 얻어냄[java.io 패키지]

📌

PrintWriter 객체명 = HttpServletResponse인스턴스명(매개면수로 전달된  이름).getWriter();

예: PrintWriter out = response.getWriter();
  1. 클라이언트에게 HTML 문서 형태로 결과 출력하기
  • PrintWriter의 메서드인 print() 및 println() 를 이용하여 태그 형태로 출력

예)

package unit01;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/hello")
public class HelloServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;//클래스 버전 고유번호
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public HelloServlet() {
        super();
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		//response.getWriter().append("Served at: ").append(request.getContextPath());

		//클라이언트에게 응답할 페이지 정보 셋팅
		response.setContentType("text/html;charset= UTF-8");
		
		PrintWriter out = response.getWriter();
		out.println("<!DOCTYPE html><html><head><title>hello</title></head>");
		out.println("<body><h1>");
		out.println("HelloServlet");
		out.println("</h1>");
		out.println("</body>");
		out.println("</html>");
		out.close();
	}

}
  1. 출력 스트림 닫기

위에서 본 예시 중 최하단에 있는 것과 같이 PrintWriter 객체.close()로 닫아주면 됨

예)

PrintWriter인스턴스명.close();
➡️ out.close();

Updated: