Servlet의 개념은
이전 포스팅에서 다루어 보았다.
그럼 이 Servlet을 어떻게 사용해야
하는지 알아보자.
어떤 프로그램이든 특정 파일에 접근하려면 '경로'가 필요하다. 웹브라우저가 웹서버에게 요청(Request)을 할 때, Servlet이 필요하다면 해당 Servlet이 위치한 경로를 이용하면 된다. 그리고 이 경로는 '가짜 경로'(가상경로)이어야 한다.
왜냐하면 Servlet은 서버의 내부 로직이기 때문이다. 내부의 로직은 외부로부터 안전하게 보호받아야 한다.
위 사진의 경로로 ROOT 폴더로 들어가보자. ROOT 폴더는 홈디렉터리이다. 홈디렉터리는 웹서버에서 가장 기본이 되는 웹앱(Web Application)이다. 웹앱이란 웹브라우저를 통해 이용 가능한 응용프로그램을 의미한다. 홈디렉터리는 경로가 '/' 슬래쉬이다.
주소 : localhost:8080
홈디렉터리 경로 : /
접근할 파일 : index.jsp
홈디렉터리의 index.jsp에 접근하려면 위와 같이 하면 된다. 이와 같이 JSP파일은 단순 경로로 접근이 가능하다. 하지만 서블릿(Servlet)은 내부로직이므로 접근할 수가 없다.
WEB-INF폴더는 서버만이 접근 가능한 영역이다. 이 안에 저장되어 있는 파일은 일반적인 경로로 접근이 불가능하도록 '약속'되어 있다. Servlet 파일은 WEB-INF안 classes 폴더 안에 저장되기로 '예약'되어 있다. WEB-INF 안에 Test.txt 파일을 만들고 접근을 시도해보자.
접근이 불가능함을 알 수 있다. Test.txt 를 WEB-INF 폴더 밖으로 내놓고 접근을 시도해보자.
WEB-INF 폴더 밖으로 나오면 이렇게 접근 가능함을 알 수 있다. 그러므로 WEB-INF 폴더 안의 Servlet에 접근하려면 가짜경로를 만들어주어야 한다. 진짜 경로는 숨기고 가짜 경로를 만들어, 오로지 서버만이 진짜 경로에 접근 가능하도록 만들어 외부 접근으로부터 서버의 로직을 보호하는 것이다.
가짜 경로(가상 경로)를 설정하는 방법은 2 가지가 있다.
web.xml
WEB-INF에 들어가면 web.xml이라는 파일이 있다. web.xml 파일에서 서블릿 클래스와 가상경로를 매핑해주면 된다. 그 전에 우선 WEB-INF안에 classes 폴더를 생성하여 그 안에 서블릿 클래스 파일을 넣어줄 것이다.
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
//서블릿 클래스
public class Test extends HttpServlet{
public void service(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
{
OutputStream os = response.getOutputStream(); //출력스트림을 받는다.
PrintStream out = new PrintStream(os,true); // 출력 스트림을 조작하는 객체를 생성 (true : 스트림의 버퍼가 가득 차지 않아도 출력)
out.println("Hello Servlet"); // 문자열 브라우저로 출력
}
}
먼저 메모장에 Servlet 클래스를 하나 만들어준다. Test.java 파일을 만든 후, cmd 창을 열어 컴파일 해준다.
클래스 패스를 톰캣의 servlet-api.jar 경로로 설정해주고 컴파일을 시작한다.
클래스 파일이 생성되었다. 이를 WEB-INF 폴더안 classes 폴더 안으로 넣어주면 끝이다.
이제 해당 서블릿에 접근하기 위한 가상경로를 설정해주자. web.xml을 메모장으로 열어준다.
web.xml에 빨간 상자안 의 코드를 추가하여 저장한다.
<servlet-class>에 서블릿 명을 넣어준다.
<url-pattern>을 통해 원하는 가상경로를 지정해준다.
<servlet-name>은 닉네임으로 이를 통해, xml 안에서 소통이 이루어진다.
이렇게 서블릿에 접근하기 위한 가상경로가 지정되었다. web.xml 파일은 서버가 시작될 때 같이 로딩되기 때문에, 서버를 껐다켜야 수정된 부분이 적용된다. 서버를 껐다 킨 후 해당 경로로 Servlet에 접근해보자.
이와 같이, WEB-INF 안에 있음에도 접근이 가능해짐을 알 수 있다. 원하는 서블릿을 사용하려면 해당 서블릿의 가상경로를 통해 접근해야한다.
@ 어노테이션
어노테이션은 '주석'이다.
일반적으로 '주석'은 개발자가 프로그램에 대해 이해할 수 있도록 달아놓은 프로그램에 대한 정보이다. 하지만 개발자뿐만 아니라 컴파일러도 프로그램에 대한 정보를 알아야 하는데, 이때 주석처리를 하는 방식이 '@ 어노테이션'이다.
가장 잘 알려진 어노테이션으로는 @Override가 있다.
메소드 위에 @Override 로 주석처리가 되어 있다면 컴파일러는 Overriding(재정의) 체크를 하여 오버라이딩 간의 오류가 없었는지 검사한다.
이런 원리를 활용하여 서블릿 클래스를 매핑할 수 있다.
import javax.servlet.*;
import javax.servlet.annotation.WebServlet; // 어노테이션 패키지 추가
import javax.servlet.http.*;
import java.io.*;
@WebServlet("/hi") // 어노테이션을 이용한 매핑
public class Test extends HttpServlet{
public void service(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
{
OutputStream os = response.getOutputStream();
PrintStream out = new PrintStream(os,true);
out.println("Hello Servlet");
}
}
@WebServlet("/hi")
앞에서 만든 Test.java 파일의 클래스 선언부 위에 어노테이션을 달고 컴파일을 다시하여 클래스를 새로 만들어 보았다.
이렇게 어노테이션을 통해, 매핑이 되어 /hi 경로로 servlet에 접근이 되었음을 알 수 있다. 웹서버의 deployment tool은 프로젝트들을 서버의 적당한 곳에 배치(deploy)해야한다. 그 과정에서 경로를 설정하는데, 툴은 어노테이션을 스캐닝하여 서블릿의 가상경로를 검사한다.
매핑 뿐만 아니라 web.xml의 다른 많은 기능이 어노테이션으로 대체 가능하다. 그래서 이클립스의 경우, WEB-INF에 web.xml 파일이 없다. 그리고 어노테이션으로 작업하면 여러 사람이 web.xml이라는 한 가지 파일을 공유하며 작업할 필요가 사라진다. 한 가지 파일을 여러사람이 같이 작업하면 파일이 뒤죽박죽되고 손상될 위험이 커진다.
그래서 대부분의 경우, web.xml 보다는 어노테이션을 많이 사용한다. 하지만 어노테이션 스캔 시간이 길어지면 서블릿 구동까지 시간이 오래 걸린다. 그래서 서블릿의 구동되는 시간을 줄이기 위해서, web.xml의 metadata-complete 속성을 true로 설정해주는 경우도 있다.
metadata-complete 속성을 true로 설정해주면 어노테이션을 스캐닝하지 않고 web.xml만 스캐닝하여 메타데이터 정보를 얻는다. 정말 true로 바꾸어 주었을 때, 실행이 안되는지 확인해보자. web.xml에서도 <servlet> 태그 부분을 주석처리 해주었다. web.xml에서도 매핑정보를 얻지 못하면 404에러가 날것이다.
이와 같이, 404 에러가 났다. 그러므로 @ 어노테이션을 이용한 매핑을 진행하려면 web.xml 파일의 metadata-complete 속성을 false 값으로 바꾸어 주어야 한다. 이클립스에서는 어노테이션을 통해 매핑을 하는 것이 일반적이므로 딱히 신경 쓸 필요는 없다.
정리
1. Servlet은 서버의 내부로직으로 외부로부터 보호받아야한다.
2. Servlet에 접근하려면 가상경로(가짜경로)로 매핑되어야 한다.
3. 매핑하는 방법에는 web.xml 방식과 어노테이션이 있다.
4. 어노테이션을 사용하면 한 파일을 여러사람이 같이 일하여 생기는 부작용을 피할 수 있다.
참고자료
1. 뉴렉처 JSP 강의
2. 열혈강의 웹프로그래밍 도서
'Web언어 > JSP' 카테고리의 다른 글
[ JSP ] 인코딩(Encoding)을 하는 이유 (3) | 2021.06.21 |
---|---|
[ JSP ] HttpServlet이란? (0) | 2021.06.21 |
[ JSP ] Servlet 과 ServletConfig (0) | 2021.06.20 |
[ JSP ] JSP의 역할 (0) | 2021.06.20 |
[ JSP ] Servlet 이란? (0) | 2021.06.20 |