1. 스프링(Spring) MVC 프레임워크(Model View Controller Framework)
- 스프링이 제공하는 트랜잭션 처리, DI, AOP를 손쉽게 사용
- 스트럿츠2와 같은 프레임워크와 연동이 쉬움
2. 스프링 MVC 주요 구성 요소 및 처리 흐름
- 다른 MVC 프레임워크와 마찬가지로 컨트롤러를 사용하여 요청을 처리
- 스프링에서는 DispatcherServlet이 MVC에서의 컨트롤러(Controller) 부분을 처리
구성 요소 | 설명 |
DispatcherServlet | 클라이언트의 요청을 전달받아 요청에 맞는 컨트롤러가 리턴한 결과값을 View에 전달하여 알맞은 응답을 생성 |
HandlerMapping | 클라이언트의 요청 URL을 어떤 컨트롤러가 처리할지 결정 |
Controller | 클라이언트의 요청을 처리한 뒤, 결과를 DispatcherServlet에게 리턴 |
ModelAndView | 컨트롤러가 처리한 결과 정보 및 뷰 선택에 필요한 정보를 담음 |
ViewResolver | 컨트롤러의 처리 결과를 생성할 뷰를 결정 |
View | 컨트롤러의 처리 결과 화면을 생성, JSP 또는 Velocity 템플릿 파일 등을 뷰로 사용 |
3. 스프링 MVC 개발
- 클라이언트에 요청을 받을 DispatcherServlet을 web.xml 파일에 설정
- 클라이언트의 요청을 처리할 컨트롤러 작성
- ViewResolver 설정 (컨트롤러가 전달한 값을 이용해서 응답 화면을 생성할 뷰를 결정)
- JSP나 Velocity 등을 이용하여 뷰영역의 코드를 작성
3.1. DispatcherServlet 설정 및 스프링 컨텍스트 설정
- web.xml(자바 웹 어플리케이션 설정 파일)에 DipathcerServlet 설정 및 공통으로 사용할 어플리케이션 컨텍스트 설정
- <servlet> 태그를 이용하여 DispatcherServlet 설정
- <servlet-mapping> 태그를 이용하여 요청 URL 패턴 설정
3.2. 컨트롤러 구현 및 설정 추가
- @Controller 애노테이션을 클래스에 적용
- @RequestMapping 애노테이션을 이용해서 클라이언트의 요청을 처리할 메서드를 지정
- ModelAndView는 컨트롤러의 처리 결과를 보여줄 뷰와 뷰에서 출력할 모델을 지정
- DispatcherServlet은 스프링 컨테이너에서 컨트롤러 객체를 검색하기 때문에 스프링 설정 파일에 컨트롤러를 빈으로 등록해야 함
3.3. 설정 파일 View Resolver 설정 추가
- 컨트롤러에서 ModelAndView.setViewName() 메서드로 뷰이름을 지정
- 이 뷰이름과 매칭되는 뷰 구현체를 찾기 위해 ViewResolver를 사용
- prefix 프로퍼티와 suffix 프로퍼티를 지정
3.4. 뷰 코드 구현
- ModelAndView.addObject() 메서드로 모델을 추가할 때 사용한 이름을 이용해서 모델의 값을 사용
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>${ message }</title>
</head>
<body>
${ message }
</body>
</html>
4. DispatcherServlet 설정과 ApplicationContext의 관계
- web.xml 파일에 한 개 이상의 DispatcherServlet 설정할 수 있으며, 각각 한 개의 WebApplicationContext를 갖음
4.1. DispatcherServlet 설정
- DipatcherServlet는 기본적으로 /WEB-INF/ 디렉터리에 위치한 [서블릿이름]-servlet.xml 파일로부터 스프링 설정 정보를 읽어 옴
- 한개 이상의 설정 파일, 또는 설정 다른 이름의 설정 파일을 사용할 경우 contextConfigLocation 초기화 파라미터에 설정 파일 목록을 지정
- 설정 파일 구분은 콤마(","), 공백 문자(" "), 탭(\t), 줄 바꿈(\n), 세미콜론(";")을 이용
4.2. ApplicationContext 설정
- 한 개 이상의 DispatcheerServlet을 사용할 때 별도의 WebApplicationContext를 생성
- 이 경우 공통 빈을 필요로 할 때 ContextLoaderListener를 사용하여 사용될 빈을 설정
- ServletListener로 등록, contextConfigLocation 컨텍스트 파라미터를 이용, 공통으로 사용될 빈 정보를 담고 있는 설정 파일 목록을 지정
- ContextLoaderListener가 생성하는 WebApplicationContext는 웹 어플리케이션의 루트 컨텍스트
- DispatcherServlet이 생성하는 WebApplicationContext는 루트 컨텍스트를 부모로 사용하는 자식 컨텍스트
- ContextLoaderListener는 contextConfigLocation 컨텍스트 파라미터를 명시하지 않으면 /WEB-INF/applicationContext.xml을 설정 파일로 사용
5. 캐릭터 인코딩 처리 필터 설정
- 모든 컨트롤러에서 response.setCharacterEncoding() 코드를 실행하는 번거로움을 해소하기 위해 서블릿 필터를 이용 처리
- 서블릿 필터에서 캐틱터 인코딩을 설정할 수 있는 CharacterEncodingFilter 클래스를 제공
- web.xml 파일에 설정
6. 컨트롤러 구현
- 스프링 3.0 버전 부터는 @Controller 애노테이션을 이용해서 컨트롤러 클래스를 구현하도록 권장
6.1. @Controller 애노테이션, @RequestMapping 애노테이션
- 컨트롤러 클래스에 @Controller 애노테이션 적용
- 클라이언트의 요청을 처리할 메서드에 @RequestMapping 애노테이션 적용
- 설정 파일에 컨트롤러 클래스를 빈으로 등록
- @RequestMapping 애노테이션은 해당 메서드에서 처리할 URI를 값으로 갖음
- @RequestMapping 애노테이션의 메서드의 리턴 타입은 상황에 따라 알맞은 타입을 선택
6.2. 컨트롤러 메서드 HTTP 전송 방식(method) 한정
- 하나의 요청 URL에 대해 HTTP GET 요청과 POST 요청을 한 개의 컨트롤러에서 처리할 경우
- @RequestMapping 애노테이션의 method 속성을 이용해서 메서드가 처리할 HTTP 메서드를 제한
- 두 메서드가 동일한 URI를 처리하는 경우 @RequestMapping 애노테이션을 클래스에 적용해서 해당 클래스가 처리할 기본 URI를 지정가능
- @RequestMapping 애노테이션에 method 속성을 설정하지 않을 경우 모든 HTTP 전송방식(GET, POST, DELETE 등)을 처리
6.3. HTML 폼, 커맨드 객체
- HTML 폼에 입력한 데이터를 자바빈 객체를 이용해서 전달 받음
- HTML 폼의 항목 이름과 자바빈 클래스의 프로퍼티 이름이 일치할 경우 폼에 입력한 값을 프로퍼티 값으로 설정
- @RequestMapping 애노테이션이 적용된 메서드의 파라미터로 자바빈 타입을 추가
- 폼에 입력한 값은 모두 문자열이지만 스프링은 자바빈의 타입 변환 처리 기능으로 프로퍼티의 타입으로 알맞게 변환
<!-- writeForm.jsp -->
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>WriteForm</title>
</head>
<body>
<form action="write.do" method="post">
<input type="text" name="name" placeholder="폰 이름" required="required" size="50"><br>
<input type="text" name="manufacturer" placeholder="폰 제조사" required="required" size="50"><br>
<input type="text" name="price" placeholder="폰 가격" required="required" size="50"><br>
<input type="submit" value="작성"><input type="reset" value="취소">
</form>
</body>
</html>
6.3.1. 뷰에서 커맨드 객체 접근
- 뷰에서 @RequestMapping 애노테이션 메서드에서 전달받은 커맨드 객체(자바빈 객체)의 클래스명을 이용해서 접근 가능(단 첫글자는 소문자)
<!-- writeSubmit.jsp -->
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>WriteSubmit</title>
</head>
<body>
<input type="text" name="name" placeholder="폰 이름" required="required" readonly="readonly" size="50" value="${ phoneDTO.name }"><br>
<input type="text" name="manufacturer" placeholder="폰 제조사" required="required" readonly="readonly" size="50" value="${ phoneDTO.manufacturer }"><br>
<input type="text" name="price" placeholder="폰 가격" required="required" readonly="readonly" size="50" value="${ phoneDTO.price }"><br>
</body>
</html>
- 뷰에서 사용할 모델의 이름을 변경할 때는 @ModelAttribute 애노테이션을 이용, 커맨드 객체의 모델 이름을 지정
<!-- writeSubmit.jsp -->
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>WriteSubmit</title>
</head>
<body>
<input type="text" placeholder="폰 이름" required="required" readonly="readonly" size="50" value="${ p.name }"><br>
<input type="text" placeholder="폰 제조사" required="required" readonly="readonly" size="50" value="${ p.manufacturer }"><br>
<input type="text" placeholder="폰 가격" required="required" readonly="readonly" size="50" value="${ p.price }"><br>
</body>
</html>
6.3.2. 커맨드 객체로 List 받기
- 폼에서 "프로퍼티명[인덱스].프로퍼티" 같이 입력 폼의 이름을 구성
<!-- writeListForm.jsp -->
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>WriteListForm</title>
</head>
<body>
<form action="writeList.do" method="post">
<input type="text" name="phoneItems[0].name" placeholder="폰 이름1" required="required" size="50"><br>
<input type="text" name="phoneItems[0].manufacturer" placeholder="폰 제조사1" required="required" size="50"><br>
<input type="text" name="phoneItems[0].price" placeholder="폰 가격1" required="required" size="50"><br>
<hr>
<input type="text" name="phoneItems[1].name" placeholder="폰 이름2" required="required" size="50"><br>
<input type="text" name="phoneItems[1].manufacturer" placeholder="폰 제조사2" required="required" size="50"><br>
<input type="text" name="phoneItems[1].price" placeholder="폰 가격2" required="required" size="50"><br>
<hr>
<input type="submit" value="작성"><input type="reset" value="취소">
</form>
</body>
</html>
'Program > Spring Framework' 카테고리의 다른 글
[Web개발] MyBatis(마이바티스)란? (0) | 2015.11.21 |
---|---|
Spring 스프링 3일차 - MyBatis 는 무엇인가? (0) | 2015.07.30 |
Spring 스프링 2일차 - JUnit을 이용한 단위 테스트 (0) | 2015.07.28 |
Spring 스프링 2일차 - AplicationContext 객체생성 (0) | 2015.07.28 |
Spring 스프링 2일차 - beanFactory 생성 (0) | 2015.07.28 |