01. 웹애플리케이션 아키텍쳐
컨테이너, 넌 누구냐?
서블릿에는 main() 메소드가 없다는데.
서블릿은 컨테이너라 부르는 자바 애플리케이션의 지배를 받습니다.
아파치와 같은 웹 서버가 사용자로 부터 서블릿에 대한 요청을 받으면 서블릿을 바로 후출하는것이 아니라, 서블릿을 관리하고 있는 컨터네이너에게 이 요청을 넘깁니다. 여기서 컨테이너란 물론 서블잇이 배포된 컨테이너를 말하겠죠. 요청을 넘겨받은 컨테이너는 HTTP Request와 HTTP Response 객체를 만들어, 이를 인자로 서블릿 doPost()나 doGet() 메소드 중 하나를 호출합니다.
클라이언트->요청->웹서버->컨텐이너->서블릿->컨테이너->우베서버->응답->클라이언트
컨테이너가 주는 혜택?
컨테이너가 서블릿을 실해아고 관리한다는 것은 이미 말했다. 하지만 컨테이너가 꼭 필요한가요?
1. 통신 지원 : 서버와 대화하기 위해 개발자가 직접 ServerSocket을 만들고, 특정 포트에 리스닝하고, 연결 요청이 들어오면 스트림을 생성하는등 이러한 복잡한 인련의 일을 할 필요가 없다는 것이죠 컨테이너는 어떻게 웹서버와 통신해야 하는지 잘 알고 있으며, 이러한 통신 기능을 API로 제공합니다. 따라서 우베서버와 서블릿이 서로 통신하기 위한 통로인 통신API에 대해 개발자가 고민할 피룡가 없다는 것이죠
2. 생명주기 관리 : 컨테이너는 서블릿의 탄생과 죽음을 관리하빈다. 개발자 관점에서 보자면, 서블릿 클래스를 로딩하여 인스턴스호 하고, 초기화 메소드를 호출하고, 요청이 들어오면 적적한 서블릿 메소드를 호출하는 작업을 컨테이너가 한다는 말이죠
3. 멀티스레딩 지원 : 컨테이너는 요청이 들어올때마다 새로운 자바 스레드를 하나 만듭니다. 클라이언트의 요청에 따라 적절한 HTTP 서비스 메소드를 실행하면 그걸 스레딩 작업은 끝나죠
4. 선언적인 보안 관리 : 컨테이너를 사용하면, 보안에 관련된 내용을 서블릿 또는 자바 클레스 코드안에 하드코딩 할 필요가 없습니다.
5. JSP지원
컨테이너는 요청을 어떻게 다룰가요?
1. 사용자가 서블릿에 대한 링크를 클릭합니다.
2. 컨테이너는 들어온 요청이 서블릿이라는 것을 간파하곤 다음 두 객체를 생성합니다.
1) httpServertResponse
2) httpServerRequest
3. 사용자가 날린 URL을 분석하여 어떤 서블릿에대한 요청인지 알아냅니다. 그다음ㅂ 해당 서블릿 스레드를 생성하여 Request/Response 객체를 인자로 넘깁니다.
4. 컨테이너는 서블릿 service() 메소드를 호출합니다. 요청에 지정한 방식에 따라 doGet()호출할지, doPos()를 호출할지 결정합니다. 여기서는 일단 HTTP GET방식이라고 가정합니다.
5. doGet() 메소드는 동적인 페이지를 생성한 다음, 이를 Response 객체에 실어 보냅니다. 보니고 난후에도 컨테이너는 Response 객체에 대한 참조를 가지고 있다는 것을 잊지마세요
6. 스레드 잡업이 끝나며, 컨테이너는 Response 객체를 HTTP Response로 전환하여 클라이언트로 내려보냅니다. 이제 마지막으로 Request 와 Response 객체를 소멸시킵니다.
하나의 서블릿이 세개의 이름을 가질수 있다는데…
서블릿은 파일의 위치를 알려주는 이름인 파일 위치명이 함께 들어가있습니다. 서블릿 개발자 입장에선 특히 클래스 이름이 아주 중요하죠 디렉토리 궂과 바로 패키지에 대한 정보를 담고있으니까요 두번째 이름으로 서블릿을 배포하본적이 있는 개발자라면, 서블릿에는 배포명이 있다는 것을 압니다. 이 이름은 내부적으로만 사용되서 배포명을 적을수도 있습니다.
마지막으로 서블릿은 공공의 이름, 누구나 다 알아도되는 이름인 URL 이름이란것이 있습니다. 이 이름은 HTMl 코드안에 코딩하는 이름이며, 사용자가 클릭해서 서블릿을 호출할때 사용하는 이름입니다. 이 URL 이름이 HTTP 요청안에 포함되어 서버로 전송되는 녀석입니다.
1. 클리언트가 아는 URL 이름 : 클라이언트는 사실 HTML안에 존재하는 서블릿 이름만 알고 있으면 됩니다. 서버상의 실제 어느 디렉토리에 어떤 파일명으로 존재하는지 관심 없죠. 사실 URL 이름은 클라이언트를 위한 애칭이라고 표현해도 되겠네요.
2. 배포자가 만든 내부적인 이름 : 배포자는 실제 애플리케이션을 운영을 위하여 배포명이라는것을 만들어 이를 개발자에게 알려주빈다. 배포명도 사실 URL 이름과 같이 가공의 이름이라고 말할수 있습니다. 이 이름은 URL이름과 같을 필요가 없으며, 실제 서블릿 파일 위치 이름과 일치하지 않아도 욉니다.
3. 실제 파일명 : 개발자가 만든 서블릿 클래스 안에는 클래스명과 패키지명이 들어있습니다. 마찬가지로 서블릿 클래스 파일도 또한 파일 시스템 상의 경로와 파일명이 있습니다. 이는 패키지 디렉토리 구조에 따라 서버마다 다를수 있습니다.
서블릿 이름을 다른 이름으로 매핑하면 애플리케이션의 유연성, 보안성이 좋아집니다.
가령 JSP나 HTML 안에 서블릿의 실제 경로와 팡리이름을 직접 하드코딩 한다고 해봅시다. 그러다가 만약 디렉토리 구조를 바꿔야 하는 상황이 벌어졌다면 개발자는 어떻게 할까요? 매핑은 이와 같은 문제를 해결합니다. 매핑은 실제 파일명을 하드코딩하는 것이 아니기 때문에 이런 문제가 발생하지 않습니다. 서블릿 파일의 위치나 이름이 바뀌었다고 해서 수정해야 할 부분을 일일이 찾아 다닐 필요도 없으며, 이런일로 해서 코드를 수정할 필요도 없죠
배포서술자에서 URL을 서블릿에 매핑하기
웹 컨테이너도 서블릿을 배포하려명면, 배포 서술자라는 XML 파일을 먼저 만들어야 합니다. DD 파일에는 서블릿과 JSP를 어떻게 실행하느냐에 관한 많은 정보들이 들어있습니다.
URL 미핑을 위한 두가지 항목
1. <servlet> : 내부에서만 사용하는 이름과 완전한 클래스명과 서로 매핑합니다.
2. <servlet-mapping> : 내부에서 사용하는 이름과 URL 이름을 서로 매핑합니다.
<web-app..>
<servlet>
<servlet-name> Internal name1</servlet-name>
<servlet-calss>foo.Servlet1</servlet-calss>
</servlet>
<servlet>
<servlet-name> Internal name2</servlet-name>
<servlet-calss>foo.Servlet2</servlet-calss>
</servlet>
<servlet-mapping>
<servlet-name> Internal name1</servlet-mapping>
<url-pattern>/Pulibc1</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name> Internal name2</servlet-mapping>
<url-pattern>/Pulibc2</url-pattern>
</servlet-mapping>
잠깐! DD를 가지고 할수 있는 일은 무척 많습니다.
URL과 실제 서블릿과 서로 매핑하는 일 말고도 DD에서 할수있는 일은 많습니다. 보안 역할 설정, 오류페이지 설정, 항목 라이브러리, 초기화 구성 및 관련 정보설정등 한두가지가 아니죠 그리고 서버가 JSEE의 모든 규겨을 구현한 서버라면 EJB 선언 및 접근에 관련된 내용도 여기서 설정합니다.
*MVC패턴 : MVC 패턴을 사용하면, 단순히 비즈니스 로직과 프리젠테이션 로직을 분라하는 것 뿐만아니라. 비즈니스 로직이 프리젠 테이션로직과 별개로 존재할수 있다는 것을 의미합니다.
MVC모델에 따라 서블릿에 비즈니스 로직을 불리해야 합니다. 그 다음 모델은 재사용 가능한 일반적인 자바 클래스로 작성합니다. 여기서 모델이라고 하는 것은 비즈니스데이터와 비즈니스 메소드의 콤비네이션이라고 할수있습니다.
서블릿, JSP환경에서 MVC
1. 컨트롤러 : request객체에서 사용자가 입력한 정보를 뽑아내어, 모델에 대해 어떤 작업을 해야 하는지 알아냅니다. 모델정보를 수정한다든지, 뷰에게 넘겨줄 새로운 모델을 만든다든지 등과 같은 작업말이죠
2. 뷰 : 프리젠테이션에 대한 책임을 지죠. 뷰는 컨트롤러로 부터 모델 정보를 읽어옵니다. 뷰는 또한 사용자가 입력한 정보를 컨트롤러에게 넘겨 주어야 합니다.
3.모델: 비즈니스 로직이 바로 여기에 들어갑니다. 모델정보를 읽어오가너 수정하는 로직이 여기 포함됩니다.MVC 패턴에서 모델은 데이터베이스와 통신하는 유일한 곳입니다.