2021. 6. 9. 19:37ㆍ개발/Spring
Spring MVC 프레임워크는 Model-View-Controller 아키텍처를 제공한다. 사용자는 MVC 모델을 통해서 각 모듈간 느슨한 결합을 가지는 웹 어플리케이션 개발이 가능하게된다.
Model은 일반적으로 데이터 접근을 담당하며, POJO 클래스로 이뤄져있다.
View는 Model의 데이터를 렌더링하는 작업을 주로 수행한다. 사용자가 브라우저에서 조회가 가능하도록 HTML 형태로 제공한다.
Controller는 사용자 요청에 대해 적절한 모델을 호출하고 필요시 비즈니스 로직처리도 수행한다. 그 다음 결과를 View로 보낸다.
MVC 모델을 정리하면 사용자는 브라우저를 통해 요청(request)을 Controller에 보내고 Controller는 비즈니스 로직처리와 필요한 데이터를 Model에서 가져온다. 이렇게 조합된 정보는 다시 View로 보내져서 사용자에게 HTML형태로 브라우저에 제공된다.
Spring MVC는 이름에서 알수 있듯이 MVC 모델을 사용해서 웹 어플리케이션을 만들기 위해 만들어 졌다. Spring MVC는 모든 HTTP 요청(request)과 응답(response)을 처리하는 DispatcherServlet이란 개념을 기반으로 설계되었다. 아래는 DispatcherServlet과 DispatcherServlet이 관리하는 컴포넌트들이다.
HTTP 요청이 DispatcherServlet으로 들어오면 먼저 Handler Mapping을 확인한다. Handler Mapping에선 HTTP 요청에 대한 적절한 Controller를 찾는 작업을 수행한다.
Controller에선 HTTP 요청에 맞는 적절한 Service메소드를 호출한다.(간단한 로직인 경우 Service이 없기도 함.) Service에서는 Model에 접근해 적절한 데이터를 가져오거나 비즈니스 로직 등을 처리한다.
DispatcherServlet은 View Resolver의 도움을 받아 HTTP 요청의 응답에 대한 적절한 View를 선택하게 된다.
View가 선택되고 나면 DispatcherServlet은 View에 data를 보내고 사용자에게 보여줄 HTML을 View로 부터받아서 사용자의 브라우저에 띄워준다.
위에서 살펴봤던 Handler Mapping,Controller, View Resolver 컴포넌트들은 WebApplicationContext의 일부분이다. ( WebApplicationContext는 ApplicationContext를 웹을 위해 몇가지 추가적인 셋팅을한 것이다. )
실습
웹 어플리케이션을 구축해야하는 프로젝트이기때문에 WAS로 Tomcat을 사용한다. 아래 사이트에 접속해서 Tomcat 9버전을 다운로드한다.
Maven 프로젝트를 하나 생성한다.
프로젝트 이름은 webApp으로 작성한다. Web Application을 구축할 예정이니 Packaging은 war로 변경한다.
웹 배포와 관련된 정보를 관리하는 web.xml이 없기때문에 pom.xml의 packaging 태그에서 에러가 발생한다.
다운받은 Tomcat 폴더의 WEB-INF 아래에 web.xml 파일이 있다. 아래는 web.xml의 기능에 대한 설명이다. 설명에서 말하는 배포설명자가 web.xml파일을 뜻한다. web.xml파일에서 앞서 언급했던 WebApplicationContext도 생성한다.
웹 애플리케이션의 배포 설명자는 애플리케이션의 클래스, 리소스, 구성 및 웹 서버가 이를 사용해서 웹 요청을 처리하는 방법을 기술합니다. 웹 서버는 애플리케이션에 대한 요청이 수신되면 배포 설명자를 사용하여 요청의 URL을 해당 요청을 처리해야 하는 코드에 매핑합니다.
(출처 : 배포 설명자: web.xml | 자바 8용 App Engine 표준 환경 | Google Cloud )
Tomcat을 다운받으면 샘플 프로젝트인 webapps가 있다. 해당 프로젝트 하위에 web.xml파일을 포함하고 있는 WEB-INF폴더가 있는데 복사해서 신규 생성한 프로젝트에 붙여넣기 한다. ( 에러를 해결하기 위해 복사할뿐 내용은 손대지 않았다. )
test라는 이름으로 JSP파일하나를 생성해본다. JSP 파일을 생성하면 <%@ 태그쪽에 에러가 발생한다. <%@ 태그는 JSP의 지시자 역할을 수행하는 태그인데 현재 페이지의 기본적인 속성 또는 import에 대한 정보를 셋팅할때 사용한다. ( 태그내의 내용을 잘보면 compile시 어떤 언어를 사용하는지, 캐릭터셋은 무엇인지 설정하는 부분을 볼 수 있다. )
에러 로그에서 java.servlet.http.HttpServlet이 없다는 문구를 볼수 있다. JSP인데 왜 Servlet과 관련된 에러가 발생할까?? 사실 JSP는 Servlet으로 변경된 뒤에 Servlet이 HTML 형태로 해석해서 사용자에게 제공하는 형태이기때문이다.
위 에러를 해결하기 위해 pom.xml에 tomcat-api 9.0.45버전 dependency를 추가한다.
tomcat-api의 jar를 열어보면 위 에러에서 필요하다고 했던 class 파일이 존재하는것을 확인할 수 있다. jsp파일들이 servlet으로 변환되어 Tomcat이 가지고 있는 Servlet Container에서 관리될수 있다.
서버를 실행하기전 compiler를 Java 8 버전으로 변경하고 실행한다.
Tomcat 버전과 일치하는 항목을 찾아 Next클릭
구동할 Tomcat이 있는 경로를 지정해준다.
Tomcat에서 관리할 프로젝트를 지정해준다.
정상적으로 실행되는지 확인한다.
이제 여기에다 DispatcherServlet을 사용하는 Spring MVC를 추가해보자. spring-webmvc 5.3.5을 pom.xml에 추가한다
Dependency Hierarchy로 살펴보면 spring-webmvc가 필요로 하는 jar파일들이 함께 다운로드 된것을 확인할 수 있다. maven을 사용하는 이유중 하나다.
배포 설명자인 web.xml에 어떤 DispatcherServlet을 사용할 것인지 셋팅한다.
Spring MVC에서 제공하는 DispatcherServlet를 사용하기 위해 spring-webmvc의 jar파일에서 제공하는 DispatcherServlet.class의 경로를 web.xml에 셋팅한다.
web.xml에 아래 붉은색 박스처럼 작성한다. DispatcherServlet의 이름은 TestDispatcher이고, / URL에 매핑되어 있다.
이제 / URL Pattern에 대한 요청이 들어온다면 TestDispatcher가 해당 요청을 받아 적절한 Controller를 선택하게 된다.
어떤 Dispatcher를 사용할지 지정했으니 이제 Web Application Context를 생성해보자.
TestDispatcher-servlet XML파일을 하나 만든다. web.xml에서 작성한 Dispatcher명에 [ -servlet ] 을 붙여주면 된다.
<context:component-scan> 태그를 통해서 Bean 컨테이너에 등록할 Bean들을 스캔할 수있도록 패키지 경로를 지정해준다. 그리고 ViewResolver를 Bean컨테이너에 등록한다. ViewResolver에 property를 통해서 view 파일 검색을 위한 패턴을 지정한다.
bean 태그 하위에 작성한 property 태그를 보면 prefix와 suffix가 있다. Controller에서 반환하는 문자열에 접두사와 접미사를 value값으로 자동으로 붙여주고 해당 경로에 있는 jsp파일을 사용자에게 제공한다.
위 xml의 beans 태그의 XML namespace부분을 일일이 타이핑하는건 힘드니 아래 가이드 사이트랑 구글링을 통해 복사해왔다.
jsp파일을 아래 경로에 위치시키고 간단한 내용을 작성한다.
Controller를 작성한다. GET방식으로 /hello에 대한 요청이 들어온 경우 sayhello 메소드를 실행한다.
반환은 문자열인데 앞서 TestDispatcher-servlet.xml에서 작성한 prefix와 suffix를 붙여서 jsp파일을 탐색한다.
서버를 다시 실행해서 /hello 요청을 해보자.
여기까지 Spring MVC 환경셋팅이 완료되었다. 셋팅하는 과정에서 구글링을 통해 Tomcat이라던지 Spring MVC의 구조에 대해 많이 배워볼 수 있었다. 그리고 Spring Boot의 위대함(?)을 느낄수 있었다.
Spring Boot의 경우 아래처럼 starter dependency를 추가함으로써 Tomcat을 내장할 뿐만아니라 Spring Web 개발에 필요한 대부분의 의존성을 알아서 추가해준다. 사람들이 Spring Boot가 편리하다고 하는데 그 이유를 모르겠다면 고전적인(?) 방식으로 환경셋팅을 한번 해보는걸 추천한다.
참고 사이트
'개발 > Spring' 카테고리의 다른 글
[Spring Security] Servlet Authentication Architecture (0) | 2022.08.16 |
---|---|
[Spring Security] Architecture (0) | 2022.08.15 |
[Resilience4j] Circuit Breaker With Spring Boot 2 (0) | 2022.07.10 |