DispathcerServlet
- spring에서 DispatcherServlet을 제공해준다.
- DispatcherServlet이라는 클래스는 클라이언트의 요청을 접수받는다.
- HTTP 요청 접수
- Controller 객체를 검색하고, 요청핸들러 메소드를 실행
- 요청핸들러 메소드의 반환값을 분석해서 내부이동/재요청URL 전송
- Controller는 스프링 컨테이너 안에 있으며, 이 스프링 컨테이너는 DispatcherServlet이 생성한다.
- HTTP 요청을 처리할 Controller 객체는 스프링 컨테이너에 포함되어 있따.
- DispathcerServlet은 HTTP 요청을 분석해서 해당 요청을 처리할 Controller 객체를 스프링 컨테이너에서 가져온다.(getBean() 사용)
- DispatcherServlet은 자식 스프링 컨테이너를 생성한다.
Controller
- Controller는 클라이언트 요청을 처리하고, Service를 통해 업무로직 메소드를 실행한다. (Controller가 Service를 의존하고 있다. = Service를 Controller에 주입하고 있다.)
- 스프링 컨테이너 안에 있다. (스프링 컨테이너가 관리한다.)
- HTTP 요청 처리
- 요청 파라미터값 처리
- 폼 입력값 유효성 검증
- 업무로직 메소드 실행
- 뷰에 표현할 데이터 담기
- 뷰이름/재요청 URL 반환
Service
- Service는 다양한 Mapper 인스턴스를 실행하여 DB엑세스를 호출한다.(Service가 Mapper 인스턴스를 의존하고 있다. = Mapper 인스턴스를 Service에 주입하고 있다.)
- 스프링 컨테이너 안에 있다. (스프링 컨테이너가 관리한다.)
- 핵심 업무 로직 수행
- 업무로직 수행에 필요한 DB 엑세스 메소드 호출
- 뷰에 표현할 데이터 반환
Mapper 인스턴스
- 데이터베이스 엑세스 작업 정의/구현
JSP 페이지
- DispatcherServlet에서 내부이동 한다.
- HTML 컨텐츠로 HTTP 응답을 보낸다.
- 혹은 JSP 없이 DispatcherServlet에서 바로 재요청URL로 HTTP 응답을 보내기도 한다.
- EL, JSTL로 데이터 표현
- JSP는 스프링 컨테이너 밖에 있으므로 스프링이 관리하지 않는다.
ContextLoadListener
- 루트 스프링 컨테이너를 생성한다.
JSP나 DispatcherServlet은 TomCat이 관리하고 실행한다.
스프링 컨테이너를 두 개로 사용하기도 하고, 하나로 통합해서 사용하기도 한다.
개발자가 관리할 항목은 Controller, Service, Mapper 인스턴스, JSP다.
루트 스프링 컨테이너와 자식 스프링 컨테이너
- 스프링 컨테이너에는 계층이 존재한다. (루트가 부모계층)
- DispatcherServlet은 자식 스프링 컨테이너를 생성한다. (웹과 관련된 기능)
- ContextLoadListener는 루트 스프링 컨테이너를 생성한다. ()
- 자식 스프링 컨테이너는 의존성 주입에 필요한 객체가 자식 스프링 컨테이너에 존재하지 않으면, 루트 스프링 컨테이너에서 찾아서 의존성 주입을 수행한다.
- 자식 스프링 컨테이너는 루트 스프링 컨테이너에 접근할 수 있고, 필요한 객체를 찾아와서 의존성 주입 작업을 수행할 수 있다.
webapp/WEB-INF/home.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>애플리케이션</title>
</head>
<body>
<h1>애플리케이션 홈</h1>
<p>${msg }</p>
</body>
</html>
HomeController
package com.sample.web.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class HomeController {
@GetMapping("/home")
public String home(Model model) {
// 뷰에 전달한 데이터를 Model 객체 추가하기
model.addAttribute("msg", "웹 페이지 방문을 환영합니다.");
// 내부이동할 뷰페이지 이름을 반환한다.
return "home";
}
}
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<!--
DispathcerServlet은 spring mvc가 제공하는 FrontController이다.
* 모든 URL 요청에 대해서(<url-pattern>/</url-pattern>) DispatcherServlet이 실행되도록 설정함
* 아래의 설정정보에 지정된 web-context.xml 파일을 읽어서 DispatcherServlet이 스프링 컨테이너를 생성하게 한다.
스프링 컨테이너에는 web-context.xml에 설정된 클래스들이 스프링 컨테이너의 빈으로 등록된다.
스프링 컨테이너의 빈으로 등록된 객체들 중에는 HomeController, UserController, PostController 등 다양한 컨트롤러 객체가 포함되어 있다.
DispathcerServlet은 요청이 접수되면 요청 URI에 해당하는 매핑정보가 포함된 컨트롤러 객체를 스프링 컨테이너에서 가져와서 실행시킨다.
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/web-context.xml</param-value>
</init-param>
-->
<servlet>
<servlet-name>app</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/web-context.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>app</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
web-context.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.3.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-4.3.xsd">
<!--
<mvc:annotation-driven> 태그는
spring mvc 관련 어노테이션을 감지/분석해서 적절한 작업을 수행하는 객체를 스프링의 빈으로 등록시킨다.
driven = 어노테이션 주도 개발
-->
<mvc:annotation-driven></mvc:annotation-driven>
<!--
<mvc:view-resolvers/> 내그는
spring mvc가 지원하는 다양한 뷰 템플릿 기술(모델의 데이터를 표현하는 기술)에 대한 설정을 지원하는 태그다.
-->
<mvc:view-resolvers>
<!--
<mvc:jsp /> 태그는
Controller의 요청핸들러 메소드가 반환하는 뷰 이름("home")을 실제 JSP 경로에 맞게 맞추도록
prefix="/WEB-INF/views/"와 suffix=".jsp"를 지정한다.
-->
<mvc:jsp prefix="/WEB-INF/views/" suffix=".jsp"/>
</mvc:view-resolvers>
<!--
<context:component-scan /> 태그는
com.sample.web 패키지에서 클래스를 스캔해서 스프링 컨테이너의 빈으로 등록시킨다.
이 애플리케이션에서 com.sample.web.controller 패키지에 모든 Controller 클래스를 스캔해서 컨테이너의 빈으로 등록시킨다.
-->
<context:component-scan base-package="com.sample.web" />
</beans>
실행결과
뷰
- Model
- 컨트롤러가 비즈니스 로직 수행결과로 획득한 데이터는 다양한 형식의 컨텐츠로 변환되어 전달된다.
- 다양한 형식 만큼 다양한 뷰 객체들이 존재한다.
- 뷰 객체는 컨텐츠 형식이나 뷰 템플릿의 종류에 상관없이 일관되게 Model 객체에서 필요한 정보를 획득할 수 있게 한다.
- 데이터를 어떤 기술을 사용하냐에 따라서 뷰가 필요하다.
- 뷰 템플릿 : HTML 형식의 데이터에만 존재하는 것으로 화면을 보여주기 위해 필요하다.
- 뷰 : 모델의 데이터를 특정 컨텐츠 타입으로 변환하는 객체
모델의 데이터를 요청객체의 속성에 저장한다.- 처음부터 request에 값을 담으면 JSP는 편하지만 다른 형식의 데이터들은 힘들다.
- 엑세스 대상이 언제나 Model이 된다.
- 그러나 JSP는 request에 데이터가 담기고 다른 형식의 데이터는 또 다른 변환이 필요해서 뷰를 사용하면 편리하게 사용할 수 있다.
spring mvc의 주요 어노테이션
@Controller
- 클래스가 HTTP 요청을 처리하는 Controller 클래스임을 나타낸다.
- <context:component-scan />으로 자동 스캔되어서 스프링 컨테이너의 빈으로 등록된다.
@GetMapping
- 요청URL을
- 모든 요청 핸들러 메소드는 매핑 정보가 저장되어 있다.