1.  스프링 Web MVC의 특징

출처 : https://www.logicbig.com/tutorials/spring-framework/spring-web-mvc/spring-mvc-intro.html
출처 : https://tvd12.com/posts/spring-mvc-request-lifecycle

 

스프링 Web MVC는 기본적으로 서블릿 API를 좀 더 추상화된 형태로 작성된 라이브러리지만, 서블릿 / JSP를 사용할 때 필요한 많은 기능들을 기본적으로 제공해서 개발의 생산성과 안정성을 높여줌

 

  📍 스프링 Web MVC는 이름에서 알 수 있듯이 Web MVC 패턴으로 구현된 구조
  📍 스프링 Web MVC가 기존 구조에 약간의 변화를 주는 부분

Front-Contoller 패턴을 이용해 모든 흐름의 사전 / 사후 처리를 가능하도록 설계된 점
어노테이션을 적극적으로 활용해서 최소한의 코드로 많은 처리가 가능하도록 설계된 점
HttpServletRequest / HttpServletResponse를 이용하지 않아도 될 만큼 추상화된 방식으로 개발 가능

 

구성요소 설명
DispatcherServlet 클라이언트 요청을 전달받아 요청에 맞는 컨트롤러가 리턴한 결과값을 View에 전달하여 알맞은 응답을 생성
HandlerMapping 클라이언트의 요청 URL을 어떤 Controller가 처리할 지 결정
Controller 클라이언트의 요청을 처리한 뒤, 결과를 DispatcherServlet에게 리턴
ModelAndView Controller가 처리한 결과 정보 및 View 선택에 필요한 정보를 담음
ViewResolver Controller의 처리 결과를 생성할 View를 결정
View Controller의 처리 결과 화면을 생성

 

출처 : https://velog.io/@codemcd/


1)  DispatcherServlet 과 FrontController

스프링 MVC에서 가장 주요한 사실은 모든 요청 Request이 반드시 DispatcherServlet이라는 존재를 통해서 실행
  ✓ 
객체지향에서 이렇게 모든 흐름을 하나의 객체를 통해서 진행되는 패턴을 퍼사드 facade 패턴이라 하는데  구조에서는 Front-Controller 패턴 이라도 부름
  ✓ 
Front-Controller 패턴을 이용하면 모든 요청이 반드시 하나의 객체를 지나서 처리되기 때문에 모든 공통적인 처리를 프론트 컨트롤러에서 처리할 수 있게 됨

 

 

 

👾  스프링 MVC에서는 DispatcherServlet이라는 객체가 프론트 컨트롤러의 역할을 수행
👾  프론트 컨트롤러가 사전 / 사후에 대한 처리를 하게 되면 중간에 매번 다른 처리를 하는 부분만 별도로 처리하는 구조를 만들게 됨 

     ➡️  스프링 MVC 에서는 이를 컨트롤러라고 하는데 @Controller를 이용해서 처리

 

 

 


2)  스프링 MVC 사용하기

👻  spring-webmvc 라이브러리는 미리 추가되었으므로 스프링 MVC관련 설정을 추가 

 

㉮  스프링 MVC관련 설정을 추가하기 위해 WEB-INF 폴더에 servlet-context.xml 파일을 생성
  ✓  root-context.xml을 이용할 수도 있지만, 일반적으로는 구조를 분리하듯이 웹을 다루는 영역이라 별도의 설정 파일을 이용하는 것이 일반적이다.

 

㉯  프로젝트 내부의 webapp 폴더 아래에 'resources'라는 폴더를 하나 더 생성해 둠

  ✓  나중에 정적 파일들(html, css, js, 이미지등)을 서비스하기 위한 경로

 

 servlet-context.xml  설정 코드
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/mvc
        https://www.springframework.org/schema/mvc/spring-mvc.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd">
        
    <mvc:annotation-driven/>
    <mvc:resources mapping="/resources/**" location="/resources/"/>
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/view/"/>
        <property name="suffix" value=".jsp"/>
    </bean>
</beans>

 

  ⚡️  <mvc:annotation-driven> 설정 : 스프링 MVC 설정을 어노테이션 기반으로 처리한다는 의미와 스프링 MVC의 여러 객체들을 자동으로 스프링의 빈으로 등록하게 하는 기능을 의미
  ⚡️  <mvc:resources> 설정 : 이미지나 html 파일과 같이 정적인 파일의 경로를 지정
        ✓  /resources 경로로 들어오는 요청은 정적 파일을 요구하는 것이라고 생각하고 스프링 MVC에서 처리하지 않는다는 의미
        ✓  location 속성 값은 webapp 폴더에서 만들어둔 폴더를 의미
        ✓  InternalResourceViewResolver라는 이름의 클래스로 빈이 설정되어 있는데,
             InternalResourceViewResolver는 스프링 MVC에서 제공하는 뷰(view)를 어떻게 결정하는지에 대한 설정을 담당
        ✓  prefix와 suffix는 뷰를 이용할때 파일명만 주어지면 조합해서 '/WEB-INF/view/파일명.jsp' 같은 형식을 만들 수 있음

 

 

web.xml의 DispatcherServlet 설정

 

스프링 MVC를 실행하려면 front controller 역할을 하는 DispatcherServlet을 설정해야하는데,  web.xml을 이용해서 처리

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/root-context.xml</param-value>
    </context-param>
    
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <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/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>

 

  ⚡️  <servlet> 설정과 <servlet-mapping> 설정이 추가
        ✓  <servlet> 설정은 DispatcherServlet을 등록하는데 DispatcherServlet이 로딩할 때 servlet-context.xml을 이용하도록 설정
        ✓  load-on-startup 설정의 경우 톰캣 로딩 시에 클래스를 미리 로딩해 두기 위한 설정
        ✓  <servlet-mapping> 설정모든 경로의 요청에 대한 처리를 담당하기 때문에 '/'로 지정

 


3)  스프링 MVC 컨트롤러 

스프링 MVC 컨트롤러는 전통적인 자바의 클래스 구현 방식과 다름

스프링 MVC의 컨트롤러 특징

 

  ✓  상속이나 인터페이스를 구현하는 방식을 사용하지 않고 어노테이션만으로 처리가 가능
  ✓  오버라이드 없이 필요한 메소드들을 정의
  ✓  메소드의 파라미터를 기본 자료형이나 객체 자료형을 마음대로 지정
  ✓  메소드의 리턴타입도 void, String, 객체 등 다양한 타입을 사용할 수 있음

 

㉮  controller 패키지를 추가하고 SampleController 클래스를 추가

@Log4j2
@Controller
public class SampleController {

    @GetMapping("/hello")
    public void hello() {
        log.info("hello(_)...");
    }
}

 

  ⚡️  몇 가지 특이한 어노테이션들이 사용
      ✓  @Controller는 해당 클래스가 스프링 MVC에서 컨트롤러 역할을 한다는 것을 의미하고 스프링의 빈으로 처리되기 위해서 사용
      ✓  @GetMapping은 GET 방식으로 들어오는 요청을 위해 사용

 


 

A) servlet-context.xml의 component-scan


controller 패키지에 존재하는 컨트롤러 클래스들을 스프링으로 인식하기 위해서는 해당 패키지를 스캔해서 @Controller 어노테이션이 추가된 클래스들의 객체들을 스프링이 빈으로 설정되게 만들어야 함

servlet-context.xml에 component-scan을 적용
<context:component-scan base-package="com.example.spring.controller"/>

 

WEB-INF에 view 폴더 생성후 hello.jsp 작성
<html>
<head>
    <title>Title</title>
</head>
<body>
  <h1>Hello JSP</h1>
</body>
</html>


 

B) @RequestMapping과 파생 어노테이션들


스프링 컨트롤러에서 가장 많이 사용하는 어노테이션은 @RequestMapping
  ⚡️  @RequestMapping은 말 그대로 '특정한 경로의 요청 Request을 지정'하기 위해서 사용
  ⚡️  컨트롤러 클래스의 선언부에도 사용할 수 있고, 컨트롤러의 메서드에도 사용할 수 있음

 

controller 패키지에 TodoController 클래스 추가
@Log4j2
@Controller
@RequestMapping("/todo")
public class TodoController {
    @RequestMapping("/list")
    public void list() {
        log.info("todo list...");
    }

    @RequestMapping(value = "/register", method = RequestMethod.GET)
    public void register() {
        log.info("todo register...");
    }
}

 

  ⚡️  TodoController의 @RequestMapping의 value 값은 '/todo'이고 list()는 '/list'이므로 최종경로는 '/todo/list' 
  ⚡️  JSP 파일이 없어서 에러가 나지만 로그 출력은 확인

 

  ⚡️  @RequestMapping을 이용하는 것만으로도 여러 개의 컨트롤러를 하나의 클래스로 묶을 수 있고, 각 기능을 메소드 단위로 설계할 수 있게 되므로 실제 개발에서 많은 양의 코드를 줄일 수 있음

  ⚡️  @RequestMapping에는 method 속성을 이용해서 GET / POST 방식을 구분해서 처리했지만, 스프링 4버전 이후에는 @GetMapping, @PostMapping 어노테이션이 추가되면서 GET / POST 방식을 구분해서 처리할 수 있게 됨
      ➡️  예를 들어 Todo 등록의 경우 GET 방식으로 '/todo/register'를 이용하면 입력 가능한 화면을 보여주고, POST방식은 처리를 해야 함

@Log4j2
@Controller
@RequestMapping("/todo")
public class TodoController {
    @RequestMapping("/list")
    public void list() {
        log.info("todo list...");
    }

//    @RequestMapping(value = "/register", method = RequestMethod.GET)
    @GetMapping("/register")
    public void register() {
        log.info("todo register...");
    }

    @PostMapping("/register")
    public void registerPOST(TodoDTO todoDTO) {
        log.info("POST todo register...");
        log.info(todoDTO);
    }
}

 


C)  파라미터 자동 수집과 변환


👩🏻‍💻  스프링 MVC가 인기를 끌게 된 여러 이유 중에는 개발 시간을 단축할 수 있는 편리한 기능들이 많기 때문
👩🏻‍💻  개발자들에게 가장 필요한 파라미터 자동 수집 기능

 

  ⚡️  파라미터 자동 수집 기능은 간단히 말해서 DTO나 VO등을 메서드의 파라미터로 설정하면 자동으로 전달되는

         HttpServletRequest의 파라미터들을 수집해 주는 기능
  ⚡️  단순히 문자열만이 아니라 숫자도 가능하고, 배열이나 리스트, 첨부 파일도 가능

 

파라미터 수집은 다음과 같은 기준으로 동작


  ✓  기본 자료형의 경우는 자동으로 형 변환처리가 가능
  ✓  객체 자료형의 경우는 setXXX()의 동작을 통해서 처리
  ✓  객체 자료형의 경우 생성자가 없거나 파라미터가 없는 생성자가 필요

 

단순 파라미터의 자동 수집

 

  📍 SampleController에 ex1() 추가

    @GetMapping("/ex1")
    public void ex1(String name, int age) {
        log.info("ex1() ...");
        log.info("name: " + name);
        log.info("age: " + age);
    }

 

  ✓  문자열 name과 int 타입의 age 선언
  ✓  브라우저를 이용해서 name과 age를 지정하면 'ex1?name=aaa&age=16'와 같이 호출 되었을 때 자동으로 처리되는 것 확인

 

 

  

 

 

[ 내용 참고 : IT 학원 강의 ]

+ Recent posts