| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | |
| 7 | 8 | 9 | 10 | 11 | 12 | 13 |
| 14 | 15 | 16 | 17 | 18 | 19 | 20 |
| 21 | 22 | 23 | 24 | 25 | 26 | 27 |
| 28 | 29 | 30 | 31 |
- 공유기 서버
- 서버운영
- reactive
- reactor
- Spring Framework
- ipTIME
- 웹 스터디
- reactor core
- 웹앱
- spring reactive
- Spring Batch
- 웹 커리큘럼
- Today
- Total
Hello World
[펌]Spring MVC 시작하기 본문

SpringMVC Getting Started
나는 이전까지 Spring 이 웹 애플리케이션에만 사용되는 줄 알았는데, 그게 아니고 Console 이나 GUI 등 다양한 곳에 쓰일 수 있는 경량 컨테이너 라고 한다.
여러 곳을 찾아보니 Spring 은 AOP와 DI가 핵심이라는데, 이것들 보다는 Spring MVC 자체에 대해 사용법을 먼저 알아보고자 한다. 프로그래밍의 재미는, 만드는 것 이지 개념 학습이 아니기 때문이다.
1. Architecture
View - Controller - Service - Dao - Model - DB 이런 구조로 데이터가 흘러다닌다. DAO(Data Access Object) 와 Service 의 차이점은 여기에 의하면,
DAO : 단일 데이터 접근 / 갱신만 처리
Service : 여러 DAO를 호출하여 여러번의 데이터 접근/갱신을 하며 이렇게 읽은 데이터에 대해 비즈니스 로직을 수행하고 하나의 트랜잭션으로 묶는다. Service 와 DAO 가 동일해지는 경우도 있는데, 이때는 비즈니스 로직이 단일 DB접근으로 끝나기 때문이다.
2. Spring MVC
Spring MVC 에 대해 알아야 할 사항은 모든 요청을 Dispatcher Servlet 이 받는 다는 것. 그래서 적절하게 처리할 Controller 를 URL 에 따라 선택하기 위해 Hanlder Mapping 을 이용하고, 선택된 Controller 는 요청을 처리하고 ModelAndView 를 돌려준다. Dispatcher Servlet 은 돌아오는View Name 을 바탕으로 View Resolver 를 호출해 View 를 얻고 여기에 Model 을 적용해 Response 를 만들어 Request 를 보냈던 Client 에게 돌려준다. 일단 그림을 먼저 보자. 
(출처 - http://www.mkyong.com/spring-mvc/spring-mvc-hello-world-example/) Node.js 나 Backbone.js 를 하셨던 분이라면 무리 없이 이해가 가능할거다. Controller 나 View 는 역할도 비슷하고, Backbone 이나 Node 의Router 가 Handler Mapping 인 것도 비스무리 하다. 이름만 다를 뿐. 조금 다른점은 View 를 묶어 View Resolver 가 관리 한다는 것이다. 하지만 사실 Backbone 에서도 수 많은 View 를 배열이나 기타 등등을 통해 관리한다는 점을 보면, 프로그래머가 구현했어야 하는 걸 Spring MVC가 해준다는 정도의 차이만 존재한다. 기능상으로는 별 차이가 없다. (아! 드디어 MVC 입문했다!)
3. Sample Code
Spring Tool Suite 로 SpringMVC 프로젝트 생성하면 나오는 샘플의 코드를 분석해 보자. import 구문은 제외한다.
@Controller
public class HomeController {
private static final Logger logger = LoggerFactory.getLogger(HomeController.class);
@RequestMapping(value = "/", method = RequestMethod.GET)
public String home(Locale locale, Model model) {
logger.info("Welcome home! The client locale is {}.", locale);
Date date = new Date();
DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale);
String formattedDate = dateFormat.format(date);
model.addAttribute("serverTime", formattedDate );
return "home";
}
}
중요한 부분은 @Controller 다. 원래는 XML 에 기술해야 하는것으로 아는데, 스프링 버전이 올라가면서 Annotation 만으로 해결이 가능해졌다. Controller 클래스 내부에는 각 URL 요청을 담당하는 메소드가 존재한다. @RequestMapping 어노테이션을 통해 등록하며, value 는 URL 경로를,method 는 HTTP Method 를 등록하면 된다. Home Controller 는 / 에 대한 요청밖에 없지만, User Controller 라면 /users, /users/51041 등을 처리할 수 있는 여러 메소드가 있을 수 있다. Controller 의 @RequestMapping 메소드는 Model 이라는 파라미터를 받는데, 이건 return 문에서 지정한 Home 이라는 이름의 View 에 적용할Model Attribute 다. 이 serverTime 이란 값은, Backbone.js 를 사용하신 분이라면, Underscore Template 에 지정되는 <%= serverTime %> 정도로 이해하면 되실거다. 실제로 그러한가 View 를 보자.
// src/main/webapp/WEB-INF/views/home.jsp
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ page session="false" %>
<html>
<head>
<title>Home</title>
</head>
<body>
<h1>
Hello world!
</h1>
<P> The time on the server is ${serverTime}. </P>
</body>
</html>
그러하다. 그런데 만약, @RequestMapping 메소드에서 파라미터를 받는다면 어떻게 추출할까? Spring 에서 관리하는 예제인 Pet-Clinic 샘플을 보자.
@RequestMapping(value = "/owners/{ownerId}/edit", method = RequestMethod.GET)
public String initUpdateOwnerForm(@PathVariable("ownerId") int ownerId, Model model) {
Owner owner = this.clinicService.findOwnerById(ownerId);
model.addAttribute(owner);
return "owners/createOrUpdateOwnerForm";
}
이것도 별거 없다. @RequestMapping 에서 받은 {ownerId} 를 @PathVariable("onwerId") 로 처리하고 있다.
스프링은 위의 예처럼 String 으로 리턴값을 통해 View 를 지정하는 것이 아니라, ModelAndView 를 리턴하여 View 를 지정할 수 있다.
@RequestMapping("/owners/{ownerId}")
public ModelAndView showOwner(@PathVariable("ownerId") int ownerId) {
ModelAndView mav = new ModelAndView("owners/ownerDetails");
mav.addObject(this.clinicService.findOwnerById(ownerId));
return mav;
}String 을 리턴하는 형태와 똑같은 일을 한다. 두 가지 종류의 방법이 있을 뿐이다. 여기에 대해서 천조국 형님들도 똑같다 고 답변했다.
마지막으로 @ModelAttribute 를 살펴보려 했으나 좀 복잡한것 같다. 누구는 생략가능하다고 하고, 누구는 @ModelAttribute 를 붙여야 할 경우가 따로 있다고 설명하기도 한다. 그래서 마지막으로 SpringMVC Sample의 디렉토리 구조에서 XML들을 좀 살펴보고 가자. 
web.xml 은 root-context.xml 을 Root Spring Container로 지정해 모든 필터와 서블렛들이 공유하도록 한다. 또한 servlet-context 를 이용해DispatcherServlet 클래스가 Front-end Controller 로 동작할 수 있도록 해 준다. 다시 말해 요청을 처리할 수 있도록 해 준다는 뜻이다. 코드를 보자.
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<!-- The definition of the Root Spring Container shared by all Servlets and Filters -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/root-context.xml</param-value>
</context-param>
<!-- Creates the Spring Container shared by all Servlets and Filters -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- Processes application requests -->
<servlet>
<servlet-name>appServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>appServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>root-context.xml의 내용은 아래와 같다. 옛날에는 무슨 역할을 했을지 모르겠지만, 내가 공부하는 이 시점(2014.02-03) 에는 별 내용이 없다. 아니면 샘플이 심플해서 별 내용이 없는 거겠지.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- Root Context: defines shared resources visible to all other web components -->
</beans>
마지막으로 servlet-context.xml 에는 CSS나 Image 등 각종 리소스가 있는 statis 폴더를 지정하고. View 의 파일 타입과 폴더를 지정한다. 역시 코드를 보자.
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->
<!-- Enables the Spring MVC @Controller programming model -->
<annotation-driven />
<!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->
<resources mapping="/resources/**" location="/resources/" />
<!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory -->
<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<beans:property name="prefix" value="/WEB-INF/views/" />
<beans:property name="suffix" value=".jsp" />
</beans:bean>
<context:component-scan base-package="com.sample.sample" />
</beans:beans>4. Summary
@Controller: 컨트롤러 클래스 어노테이션@RequestMapping(value = "/", method = RequestMethod.GET): HTTP Request 핸들러 메소드 어노테이션model.addAttribute("serverTime", formattedDate );:View에 적용할Model Attribute추가return "home";: 돌려줄View이름 지정,ModelAndView를 리턴해줄 수도 있다.@PathVariable: URL 요청에서 받은 파라미터 값을 추출할때 사용
References
출처: http://anster.tistory.com/142
'Spring > 3.x' 카테고리의 다른 글
| [펌]Spring Batch Tutorial (0) | 2016.01.20 |
|---|---|
| [펌]쉽게 이해하면 좋을 스프링 프레임워크 (0) | 2016.01.19 |
| [펌]JSP 와 Servlet, 왜 같이 쓸까? (0) | 2016.01.14 |
| [펌]Getting started with annotation based Spring MVC web application (0) | 2016.01.10 |
| [펌]파일 업로드 & 다운로드 (3/3) (0) | 2016.01.10 |