스프링 프레임워크는 DI나 AOP와 같은 기능 뿐 아니라 기본적으로 웹 개발을 위한 MVC 프레임워크도 함께 제공하고 있다. 스프링 MVC 프레임워크는 스프링을 기반으로 하고 있기 때문에 스프링이 제공하는 트랜잭션 처리나 DI 및 AOP 적용 등을 손쉽게 사용할 수 있다는 장점을 갖는다.
또한 스트럿츠와 같은 프레임워크와 스프링 프레임워크를 연동하기 위해 추가적인 설정을 하지 않아도된다는 장점을 가지고 있다
1. 스프링 MVC의 주요 구성요소
DispatcherServlet
클라이언트의 요청을 전달받는다. 컨트롤러에게 클라이언트의 요청을 전달하고 컨트롤러가 리턴한 결과 값을 View에 전달하여 알맞은 응답을 생성하도록 한다.
HandlerMapping
클라이언트의 요청 URL을 어떤 컨트롤러가 처리할지 결정한다
컨트롤러(Controller)
클라이언트의 요청을 처리한 뒤 그 결과를 DispatcherServlet에 알려준다. 스트럿츠의 Action과 동일한 역할을 수행한다.(ModelAndView 리턴)
ModelAndView
컨트롤러가 처리한 결과 정보 및 뷰 선택에 필요한 정보를 담는다
ViewResolver
컨트롤러의 처리 결과를 생성할 뷰를 선택한다
View
컨트롤러의 처리 결과 화면을 생성한다
구성요소간 프로세스 흐름
1. 클라이언트의 요청이 DispatcherServlet에 전달된다
2. DispatcherServlet은 HandlerMapping을 사용하여 클라이언트의 요청을 처리할 컨트롤러 객체를 구한다
3. DispatcherServlet은 컨트롤러 객체의 HandleRequest() 메서드를 호출하여 클라이언트의 요청을 처리한다.
4. 컨트롤러의 handleRequest() 메서드는 처리 결과 정보를 담은 ModelAndView 객체를 리턴한다
5. DispatcherServlet은 ViewResolver로부터 응답결과를 생성할 뷰 객체를 구한다
6. 뷰는 클라이언트에 전송할 응답을 생성한다
2. 스프링 MVC를 사용하여 Hello World 출력
1. 클라이언트의 요청을 받을 DispatcherServlet을 web.xml 파일에 설정한다.
2. HandlerMapping을 이용하여 요청 URL과 컨트롤러의 매핑방식을 결정한다.
3. 클라이언트의 요청을 처리할 컨트롤러를 작성한다.
4. 어떤 뷰를 이용하여 컨트롤러의 처리 결과 응답 화면을 생성할지 결정하는 ViewResolver를 설정한다
5. JSP나 Velocity 등을 이용하여 뷰 영역의 코드를 작성한다
2.1 단계 1, DispatcherServlet 설정 및 스프링컨텍스트 설정
스프링 MVC를 사용하기에 앞서 가정 먼저 해야 할 작업은 자바 웹 어플리케이션의 설정 파일인 web.xml 파일에 다음의 두 가지 정보를 추가하는 것이다
(1) 클라이언트의 요청을 전달받을 DispatcherServlet 설정
(2) 공통으로 사용할 어플리케이션 컨텍스트 설정
DispatcherServlet 은 클라이언트의 요청을 전달받는 서블릿으로서 컨트롤러나 뷰와 같은 스프링 MVC의 구성요소를 이용하여 클라이언트에게 서비스를 제공하게 된다. DispatcherServlet의 설정은 웹 어플리케이션의 /WEB-INF/web.xml 파일에 추가하며 다음과 같이 서블릿과 서블릿 매핑 정보를 추가하면 된다.
<?xml version="1.0" encoding="UTF-8"?> <web-app ...> <servlet> <servlet-name>dispatcher</servlet-name> <servlet-class> org.springframework.weg.servlet.DispatcherServlet </servlet-class> </servlet> <servlet-mapping> <servlet-name>dispatcher</servlet-name> <url-pattern>*.htm</url-pattern> </servlet-mapping> </weg-app> |
위 코드에서는 *.htm으로 들어오는 클라이언트의 요청을 DispatcherServlet이 처리하도록 설정하였다.
DispatcherServlet은 WEB-INF/ 디렉터리에 위치한 [서블릿이름]-servlet.xml 파일을 스프링 설정 파일로 사용한다. 예를 들어 위 코드의 경우 dispatcher-servlet.xml 파일을 설정 파일로 사용하게 된다. 이 파일에서 스프링 MVC의 구성요소인 HandlerMapping, Controller, ViewResolver, View등의 빈을 설정하게 된다.
2.2 단계2, 설정 파일에 HandlerMapping 설정 추가
HandlerMapping은 클라이언트의 요청을 어떤 컨트롤러가 처리할지에 대한 정보를 제공한다. 스프링은 기본적으로 몇 가지 HandlerMapping을 제공하고 있는데, 여기서는 BeanNameUrlHandlerMapping을 사용할 것이다.
DispatcherServlet이 사용하는 스프링 설정 파일에(예를 들어, 이번 예제에서는 dispatcher-servlet.xml) 다음과 같이 사용할 HandlerMapping을 빈으로 등록한다
<bean id="beanNameUrlMapping" class = "org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/> |
BeanNameUrlHandlerMapping은 간단하게 설명하면 클라이언트의 요청 URL과 동일한 이름을 갖는 빈을 컨트롤러로 사용하도록 매핑한다.
2.3 단계3, 컨트롤러 구현 및 설정
스프링은 Controller 인터페이스를 제공하고 있으며, 컨트롤러 클래스는 Controller 인터페이스를 구현하면 된다. 실제로는 Controller 인터페이스를 직접 구현하는 경우는 드물며, 스프링이 제공하는 몇 가지 기본 컨트롤러 클래스 중에서 알맞은 클래스를 상속받아 구현하게 된다
간단한 컨트롤러(HelloController.java)
package xxx.xxx.xxx.xxx import java.util.Calendar; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.mvc.AbstractController; public class HelloController extends AbstractController { @Override protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception { ModelAndView mav = new ModelAndView(); mav.setViewName("hello"); mav.addObject("greeting",getGreeting()); return mav; } private String getGreeting(){ int hour = Calandar.getInstance().get(Calendar.HOUR_OF_DAY); if(hour >= 6 && hour <= 10){ return "좋은 아침입니다."; }else if(hour >=12 && hour <= 15){ return "점심 식사는 하셨나요?"; }else if(hour >=18 && hour <= 22){ return "좋은 밤 되세요"; } return "안녕하세요"; } |
컨트롤러는 처리 결과를 ModelAndView에 담아 DispatcherServlet에 전달한다. ModelAndView는 컨트롤러의 처리 결과에 대한 응답 화면을 생성할 뷰 정보와 응답 화면을 생성할 때 필요한 정보를 저장한다.
<bean id="handlerMapping" class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/> <bean name="/hello.htm" class="xxx.xxx.xxx.xxx.HelloController"/> |
위 코드에서 BeanNameUrlHandlerMapping은 URL과 일치하는 이름을 갖는 컨트롤러를 사용하므로http://somehost[/servletContextPath]/hello.htm으로 요청이 들어올 경우 이름이 "/hello.htm"인 컨트롤러를 이용하여 클라이언트의 요청을 처리하게 된다
2.4 단계4, 설정 파일에 ViewResolver 설정 추가
컨트롤러가 리턴하는 ModelAndView는 뷰 정보를 담고 있다 위 코드에서는 아래 코드를 이용하여 뷰를 설정하였다
ModelAndView mav = new ModelAndView(); mav.setViewName("hello"); |
위 코드에서 뷰 이름을 "hello"로 지정했는데, ViewResolver는 이 뷰 이름을 이용하여 알맞은 View 객체를 선택하게 된다. 아래 코드는 이번 예제에서 사용하는 InternalResourceViewResolver의 설정 예이다
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/view/" /> <property name="suffix" value=".jsp" /> </bean> |
InternalResourceViewResolver는 JSP를 이용하여 뷰를 구현할 때 사용되는 ViewResolver이다.
위 코드는 컨트롤러가 리턴한 ModelAndView객체의 뷰 이름이 "hello"인 경우 /WEB-INF/view/hello.jsp를 뷰로 사용하는 View 객체를 생성하도록 설정하고 있다. 스프링은 이외에도 다양한 ViewResolver를 제공하고 있다
2.5 단계5, 뷰 코드 구현
InternalResourceViewResolver는 JSP를 이용하여 뷰를 생성하는 InternalResourceView를 View객체로 사용하며, InternalResourceView는 JSP와 같은 웹 어플리케이션의 자원을 이용하여 뷰를 생성하게 된다.
InternalResourceViewResolver를 통해 JSP를 뷰로 사용할 경우 다음 예제와 같이 JSP로 표현언어를 사용하여 ModelAndView객체에 저장한 값에 접근할 수 있다.
<%@ page language="java" contentType="text/html; charset=EUC-KR" %> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=EUC-KR"> <title>인사</title> </head> <body> 인사말:<strong>${greeting}</strong> </body> </html> |
앞 예제에서 ModelAndView 객체에 "greeting"이라는 이름으로 값을 저장하였다
InternalResourceView는 ModelAndView에 저장된 객체를 HttpServletRequest 객체의 속성(attribute)에 그대로 저장한다. 따라서 JSP에서는 ${greeting}과 같은 표현언어를 이용하여 ModelAndView에 저장된 값에 접근할 수 있다 또는 다음과 같이 저장된 객체를 구할 수도 있다
<% String greetingValue = (String)request.getAttribute("greeting"); %> |
출처 - http://blog.naver.com/koola78?Redirect=Log&logNo=20112431417