지난 글에서는 maven 프로젝트 폴더를 만들었고 기본적인 라이브러리들을 추가해보았습니다.

이번 글에서는 나머지 설정을 해보고 Hello World를 출력해보겠습니다.




1. DispatcherServlet

우선 톰캣 설정 파일인 web.xml에서 아래의 코드를 작성하여 URL과 Servlet을 매핑 하겠습니다.

<!-- Dispatcher Servlet(Front controller) -->

<servlet>

        <servlet-name>spring</servlet-name>

        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>

</servlet>


<servlet-mapping>

        <servlet-name>spring</servlet-name>

        <url-pattern>/</url-pattern>

</servlet-mapping>

설정의 의미는 다음과 같습니다.


/ 경로, 즉 모든 요청에 대하여 DispatcherServlet 객체의 어떤 메서드가 실행됩니다.

Servlet의 라이프 사이클에 따라, 해당 요청이 처음이라면 init() 메서드가 실행될 것이고,

그것이 아니라면 service() 메서드부터 실행되어 doGet() 또는 doPost() 메서드가 실행될 것입니다.


DispatcherServlet은 모든 요청을 받아들이는 Servlet입니다.

즉 앞단에서 모든 요청을 스프링이 받아들인 후에 URL에 대응되는 컨트롤러를 찾아가 특정 메서드를 실행합니다.

컨트롤러를 어떻게 찾아가는지, 어떤 메서드를 실행하는지는 어노테이션으로 명시하는데, 이 부분은 뒤에서 말씀드리겠습니다.

여기서는 DispatcherServlet이 모든 요청을 받아들여 적절한 메서드가 실행될 수 있도록 분기시킨다는 것만 알고 가시면 됩니다.





2. 스프링 환경설정 ( spring.servlet.xml )

이전 글에 이어서 환경 설정이 계속되고 있습니다.

정리하면 이전 글에서는 maven과 관련된 설정을, 이 글에서는 톰캣과 관련된 설정을 했습니다.


이제 스프링 컨테이너에 대한 환경설정을 하려고 합니다.

스프링 컨테이너는 객체들을 관리하는 bean Factory라고 했었는데, 컨테이너가 어떻게 객체들을 관리를 할 수 있는지 설정을 해보면서 알아보도록 하겠습니다.


우선 web.xml을 열어서 DispatcherServlet을 매핑한 <servlet-name>을 알아야 하는데, 기본 값인 spring으로 되어있을 것입니다.

그러면 webapp/WEB-INF 폴더 아래에 spring-servlet.xml 파일을 만들어서 아래의 코드를 작성하겠습니다.

<?xml version="1.0" encoding="UTF-8"?>

<beans

        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

        xmlns:aop="http://www.springframework.org/schema/aop"

        xmlns="http://www.springframework.org/schema/beans"

        xmlns:p="http://www.springframework.org/schema/p"

        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.xsd    http://www.springframework.org/schema/aop

http://www.springframework.org/schema/aop/spring-aop.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">


        <context:annotation-config />

        <context:component-scan base-package="com.victolee.springTest.controller"/>

</beans>

1. <context:annotation-config />

이 코드는 어딘가( Application Context )에 이미 등록된 bean들의 어노테이션 활성화를 위해 사용됩니다. 

즉 어딘가에서 미리 만들어 놓은 객체를 가져다 쓰기 위한 @Autowired 와 @Qualifier 같은 어노테이션을 해석할 것이라는 의미입니다.


스프링 컨테이너는 객체들을 관리한다고 했었는데, 관리하는 방식은 어딘가에서 생성된 객체를 가져다 쓰는 방식입니다.

즉 미리 생성된 객체를 가져다 쓰기 위해서는 @Autowired라는 어노테이션을 사용하는데,

<context:annotation-config />는 이 어노테이션을 활성화 하겠다는 의미가 됩니다.

스프링의 특징 중에 의존성 주입( DI )라는 것이 있었죠?
DI는 이 과정을 통해 일어나는 것입니다.



2. <context:component-scan>

이 코드 또한 어노테이션을 활성화 하는 일을 수행하는데,

@Component, @Repository, @Service, @Controller, @RestController, @ControllerAdvice, @Configuration 과 같은 어노테이션을 스캔 하겠다는 의미입니다.


추가적인 설정을 통해 사용자가 직접 작성한 어노테이션을 추가, 제거 할 수 있습니다.

또한 스캔할 영역( base-package )을 지정해 두는 것이 바람직한데, 이는 스프링의 동작 과정을 이해해야 설명이 가능한 부분이므로 잠시 미루도록 하겠습니다.



여기서 궁금한 점은 두 가지일 것입니다.

1) 어디서 어떻게 객체를 미리 만들어 두는 것인가 ?

2) 스프링은 어떻게 동작하는가 ?

이 부분에 대해서는 다음 글에서 알아보도록 하겠습니다.





3. Hello World !

이제 hello world를 출력하기 위한 환경 설정이 끝났습니다.


Java Resources/src/main/java 폴더에서 com.victolee.springTest.controller 패키지를 만들겠습니다.

왜냐하면 spring-servlet.xml 파일에서 scan 범위( base-package )를 위의 이름으로 작성했기 때문입니다.

어노테이션 스캔은 base-package 로 작성한 패키지 내에서만 이루어지기 때문에 패키지 이름이 다르면 스캔을 하지 않습니다.



다음으로 컨트롤러 역할을 하는 HelloController 클래스를 만들고 아래와 같이 작성하겠습니다.

/src/main/java/HelloController.java
package com.victolee.springTest.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class HelloController {
	@RequestMapping("/hello")
	public String hello() {
		return "/WEB-INF/views/hello.jsp";
	}
}

spring-servlet.xml의 설정 코드를 말씀드릴 때 " @Controller 어노테이션을 스캔한다 "는 내용이 있었죠?

이와 같이 클래스 선언부 위에 @Controller를 작성하면 스프링은 이 클래스를 컨트롤러로 인식하여 다음의 과정을 수행합니다.


1) 모든 요청을 받아들이는 DispatcherServlet이 특정 요청을 처리할 수 있도록 @Controller 어노테이션이 작성된 클래스를 읽어들입니다.

2) 그 클래스의 많은 어노테이션 중 @RequestMapping 어노테이션을 읽어들입니다.

3) 어떤 URL이 왔을 때 어떤 메서드를 실행한 것인지를 Mapping 합니다.


즉 위 예제의 내용은 /hello라는 요청이 오면 hello.jsp 페이지를 렌더링 하겠다는 의미입니다.


이 부분에 대해서는 다음 글에서 더욱 자세히 다루도록 하겠습니다.

지금은 @Controller을 작성하면 스프링이 해당 클래스를 컨트롤러라고 인식을 하고,

@RequestMapping을 작성하면 URL과 메서드가 매핑이 이루어진다고 이해하시면 됩니다.





마지막으로 /WEB-INF/views 폴더에 hello.jsp 파일을 만들겠습니다.

그 이유는 HelloController 클래스에서 hello() 메서드의 return으로 view 페이지 경로를 문자열로 반환했기 때문입니다.

이것이 가능한 이유는 ViewResolver라는 객체 덕분인데, 간단한 내용이므로 궁금하시다면 여기를 참고해주세요.


/WEB-INF/views/hello.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<title>Insert title here</title>

</head>

<body>

         <h1>Hello World</h1>

</body>

</html>

이제 톰캣에 스프링 프로젝트를 추가한 뒤,

http://localhost:8080/springTest/hello 으로 요청을 보내면 브라우저에 Hello Wolrd가 출력이 될 것입니다.




이상으로 웹 페이지에 Hello World를 출력하면서 기본적인 스프링 환경 설정을 설정을 해보았습니다.

다음 글에서는 이 글의 중간에서 언급했던 내용들을 이해하는데 필요한 스프링의 전체적인 동작 과정을 알아보겠습니다.


댓글 펼치기 👇
  1. Favicon of https://employerukss.tistory.com 고용인 2018.11.22 15:32 신고

    혹시 jsp 파일의 파일명이 hello.jsp 로 설정되어야 하는거 아닐까요?
    /WEB-INF/views/ViewResolover.jsp -> /WEB-INF/views/hello.jsp

  2. 호로관메뚜기 2019.07.23 15:52

    그대로 따라서 해봤는데
    No mapping found for HTTP request with URI [/springTest/hello] in DispatcherServlet with name 'spring' 란 에러가 뜨네요...
    servlet mapping이 제대로 안되면 이렇게 나온다는데 web.xml이랑 spring-servlet.xml 혹시나 싶어 그대로 복붙해도 똑같네요...

  3. 안녕하세요 2020.05.21 11:57

    잘보고 있습니다 ㅜㅜ 이렇게 자세하게 잘 설명해주셔서 너무 감사해요 ㅠㅠ