본문 바로가기
웹 프로그래밍/Servlet & JSP

서블릿 구현 및 실행 (web.xml, @WebServlet 설정)

by kgvovc 2021. 3. 11.
반응형

서블릿 구현 및 실행

 

서블릿 작성

 

<이클립스 디렉토리 구조>

 

FirstServlet.java

package com.edu.test;

import java.io.IOException;

import javax.servlet.*;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;


public class FirstServlet extends HttpServlet {
	
	public void init(ServletConfig config) throws ServletException {
		System.out.println("init() 실행됨!");
	}

	public void service(ServletRequest arg0, ServletResponse arg1) throws ServletException, IOException {
		System.out.println("service() 실행됨!");
	}
}

 

  • HttpServlet은 서블릿이 웹상에서 HTTP 프로토콜을 이용해 서비스를 처리하기 위해 반드시 상속받아야 하는 클래스입니다. 즉, 모든 서블릿 클래스의 상위 클래스는 HttpServlet이어야 합니다.
  • init() 메소드는 서블릿이 최초로 호출되었을 때 서블릿 컨테이너가 자동으로 실행합니다. 서블릿 객체가 생성된 후, 한 번만 실행되므로 서블릿의 초기화 작업을 담당합니다.
  • service() 메소드는 클라이언트의 요청이 있을 때마다 매번 서블릿 컨테이너가 자동으로 실행합니다. 따라서 서블릿 실행 요청이 있을 때마다 실행되어야 하는 내용을 구현합니다.

 

자세한 서블릿의 실행 순서 : https://kgvovc.tistory.com/26 참고

 

 


 

서블릿 실행

앞에서 우리가 작성한 FirstServlet.java 소스는 /WEB-INF/classes 디렉토리에 컴파일되었습니다.

WEB-INF 디렉토리에 있는 web.xml 파일은 웹 애플리케이션에 관한 환경설정 파일로서 웹서버가 시작할 때 web.xml 파일에 설정된 내용대로 서비스를 올려줍니다. /WEB-INF/classes나 /WEB-INF/lib 디렉토리에 있는 파일들도 애플리케이션 서버가 사용합니다. 이처럼 /WEB-INF는 웹서버가 사용하는 파일이 들어있는 중요한 디렉토리입니다. 따라서 외부에서 클라이언트가 곧바로 접근할 수 없도록 막아놓았습니다.

 

정말 접근할 수 없는지 확인해보겠습니다.

프로젝트의 /WEB-INF 디렉토리 안에 test2.jsp 파일을 아래와 같이 만듭니다.

<%@ page language="java" contentType="text/html; charset=EUC-KR"
    pageEncoding="EUC-KR"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="EUC-KR">
<title>Insert title here</title>
</head>
<body>
test2!
</body>
</html>

 

그리고 이 test2.jsp 파일을 서버에서 돌려보면,

이렇게 '404 Not Found'라는 응답을 받습니다. /WEB-INF 디렉토리 자체가 서버에서 서비스되고 있지 않기 때문입니다.

 

여기서 서블릿 파일은 /WEB-INF/classes에 있어야 한다는 사실과 /WEB-INF 디렉토리는 클라이언트가 접근할 수 없다는 사실이 서로 어긋납니다. 서블릿은 클라이언트에 서비스하려고 만들었는데 클라이언트가 접근할 수 없는 것입니다. 이를 어떻게 해결할까요?

 

일단 분명한 사실은 클라이언트가 곧바로 /WEB-INF에 접근하면 안 된다는 것입니다. 클라이언트가 서블릿에 접근할 수 있게 하려면 서버 쪽에서 설정을 해주어야 합니다. web.xml과 annotation을 이용하여 서블릿 접근 경로를 지정할 수 있습니다.

 

 

web.xml 설정을 통해 접근

먼저, web.xml 설정을 통해 클라이언트가 서블릿에 접근할 수 있도록 설정하는 방법을 알아보겠습니다. 프로젝트 탐색 창에서 /WebContent/WEB-INF/web.xml 파일을 열어 아래와 같이 작성합니다.

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" id="WebApp_ID" version="4.0">
  <display-name>edu</display-name>
    
  <servlet>
  	<servlet-name>first</servlet-name>
  	<servlet-class>com.edu.test.FirstServlet</servlet-class>
  </servlet>
  
  <servlet-mapping>
  	<servlet-name>first</servlet-name>
  	<url-pattern>/hello</url-pattern>
  </servlet-mapping> 
</web-app>

 

위와 같이 파일을 저장한 후 FirstServlet 서블릿을 실행합니다.(http://localhost:8080/edu/hello로 접속) 웹 브라우저가 실행되며 콘솔 창에는 init()와 service() 메소드가 실행된 결과가 보입니다.

 

 

웹 브라우저에서 새로고침 버튼을 눌러 요청을 다시 보내면 위와 같이 init() 메소드는 실행되지 않고 service() 메소드만 실행되는 것을 확인할 수 있습니다.

 

 

그럼, 우리가 작성한 web.xml 소스 파일에 사용된 각 태그의 의미도 함께 살펴보겠습니다. web.xml 파일에 다음 순서로 서블릿을 등록하고 매핑합니다.

 

1) 실행할 서블릿을 웹서버에 등록

<servlet>
  <servlet-name> </servlet-name>
  <servlet-class> </servlet-class>
<servlet>

 

  • <servlet> 태그는 HttpServlet을 상속받고 있는 클래스를 web.xml에 등록할 때 사용합니다. <servlet> 태그를 사용하면 반드시 하위에 <servlet-name>과 <servlet-class> 태그를 가져야 합니다.

     

  • <servlet-name> 태그는 등록하는 서블릿의 이름을 부여합니다. 서블릿의 이름은 실제 존재하는 이름이 아니라 개발자가 지정하는 이름입니다. 서블릿 이름으로 지정한 이후에는 클래스 이름을 사용하면 안 됩니다. 즉, <servlet-name> 등록 후에는 서블릿 클래스 이름이 아닌 등록된 서블릿 이름으로 사용해야 올바르게 동작합니다.

    web.xml 파일 내에서 서블릿 클래스를 지칭하는 별명을 지어준다고 생각하면 됩니다.

 

  • <servlet-class> 태그는 등록하는 서블릿의 실제 클래스 이름을 지정합니다. <servlet-class>에 지정된 정보로 웹서버가 서블릿 객체를 찾아 올바르게 서블릿에 관한 설정을 할 수 있습니다. 즉, <servlet-class> 정보는 웹서버가 서블릿을 찾아갈 때 사용하는 정보로서 패키지명과 함께 대소문자를 구분하여 정확하게 이름을 지정해야 합니다.

 

 

2) <servlet>으로 등록한 서블릿을 실행할 URI 지정

<servlet-mapping>
  <servlet-name> </servlet-name>
  <url-pattern> </url-pattern>
<servlet-mapping>

 

  • <servlet-mapping> 태그는 web.xml에서 <servlet> 태그로 등록한 서블릿을 실행 요청할 때 사용할 URI을 지정하기 위해 사용합니다. 이 태그는 <servlet> 태그를 사용했을 때만 부가적으로 사용할 수 있고, <servlet>으로 등록된 서블릿이 아니면 사용할 수 없습니다.

 

  • <servlet-name> 태그는 실행할 서블릿 이름을 지정합니다. 이때 지정하는 이름은 반드시 <servlet> 태그에서 등록한 서블릿 이름으로 지정해야 합니다. 만약 <servlet> 태그에서 등록하지 않은 이름으로 <servlet-name>을 설정하면 web.xml 오류가 발생하여 웹 애플리케이션 서비스가 웹서버에 올라가지 않습니다. 이 정보를 가지고 <servlet> 태그를 찾아 매핑한 다음 실제 서블릿 클래스와 연결됩니다.

 

  • <url-pattern> 태그는 서블릿을 실행할 때 사용할 URL을 지정합니다. 그런데 URL을 지정할 때 전체 URL 정보를 모두 지정하는 것이 아니고 'http://서버주소:포트번호/웹 애플리케이션 이름'까지는 생략하고, 그 다음부터만 지정하면 됩니다. 어차피 현재 웹 애플리케이션을 찾아오기까지의 정보는 고정되어 있으므로 생략할 수 있는 것입니다. 경로를 지정할 때는 /를 구분자로 하여 개발자 마음대로 정하면 됩니다. <url-pattern> 태그에 경로를 지정하면 이 다음부터는 지정된 경로로 접근하면 서블릿이 실행됩니다.

 

 

@WebServlet을 통해 접근

어노테이션은 자바 주석문처럼 소스 안에 @ 기호와 함께 사용됩니다. 자바 실행문은 아니고 주석문처럼 컴파일러에 정보를 알려주는 기능, 도는 자바 프로그램 실행에 관한 내용을 설정하는 용도로 사용됩니다.

 

어노테이션을 통해 접근하려면 서블릿의 클래스 선언부 앞에 @WebServlet(접근시 사용할 URI)를 지정하면 됩니다.

package com.edu.test;

import java.io.IOException;

import javax.servlet.*;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;


@WebServlet("/hello2")
public class FirstServlet extends HttpServlet {
	
	public void init(ServletConfig config) throws ServletException {
		System.out.println("init() 실행됨!");
	}

	public void service(ServletRequest arg0, ServletResponse arg1) throws ServletException, IOException {
		System.out.println("service() 실행됨!");
	}
}

 

web.xml 파일을 열어서 <servlet>과 <servlet-mapping> 태그 사이의 소스는 @WebServlet 설정과 중복이므로 주석으로 처리합니다.

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" id="WebApp_ID" version="4.0">
  <display-name>edu</display-name>
    
    <!-- 
  <servlet>
  	<servlet-name>first</servlet-name>
  	<servlet-class>com.edu.test.FirstServlet</servlet-class>
  </servlet>
  
  <servlet-mapping>
  	<servlet-name>first</servlet-name>
  	<url-pattern>/hello</url-pattern>
  </servlet-mapping>  -->
</web-app>

 

FirstServlet.java 소스를 실행하면(http://localhost:8080/edu/hello2로 접속),

 

 

위와 같이 잘 접속되는 것을 확인할 수 있습니다.

반응형

댓글