3 분 소요

본 포스트는 인프런 김영한 강사님의 <스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 기술> 강의를 보고 정리한 것이다.

자세한 강의와 설명이 필요한 사람은 아래 링크를 접속하면 된다.

스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 기술



웹 개발을 하는 데 있어서 콘텐츠, 웹 페이지를 개발 하는 방법은 여러가지가 있다.


정적 컨텐츠

말 그대로 정적이다.

어떠한 기능도 없이 그냥 페이지를 보여주기만 하는 정적 컨텐츠.

정적 컨텐츠는 resources/static 에 생성된다.

아래와 같은 파일을 생성했다고 하자.


resources/static/static-content.html

<!DOCTYPE HTML>
<html>
<head>
    <title>static content</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
static content
</body>
</html>


위 파일의 웹 진입 경로는 localhost:8080/static-content.html 가 된다.

image


resources/static 에 컨텐츠를 생성하면 해당 파일을 그대로 웹 브라우저에 전송하여 화면을 볼 수 있는 정적 컨텐츠가 생성되는 것이다.

위에서는 static-content.html 가 정적 컨텐츠이다.



MVC와 템플릿 엔진

MVC 패턴

MVC 패턴이란, 대화형 애플리케이션을 모델, 뷰, 컨트롤러 3개의 서브 시스템으로 구조화하는 패턴을 말한다.


모델(Model) 은 핵심 기능과 데이터를 보관하며,

뷰(View) 는 사용자에게 정보를 표시하는 역할을 한다.

컨트롤러(Controller) 는 사용자로부터 요청을 입력받아 처리하고, 모델과 뷰 사이에서 전달자 역할을 수행한다.


MVC

뷰는 웹 브라우저 상 화면을 그리고, 모델과 컨트롤러는 내부 비즈니스 로직과 서버를 처리하는 역할이라고 생각하면 된다.


MVC 와 템플릿 엔진을 통해 HTML을 동적으로 프로그래밍 할 수 있다.


Controller

HelloController.java

@Controller
public class HelloController{

    @GetMapping("hello-mvc")
    public String helloMvc(@RequestParam("name") String name, Model model) {
        model.addAtrribute("name", name);
        return "hello-template";
    }
}
  • @Controller : 웹 어플리케이션에서 첫번째 진입점
  • @GetMapping("") : localhost:8080/hello-mvc 로 맵핑
  • @RequestParam("name") String name
    외부에서 key값이 “name”이고 value 값이 name인 데이터를 받아온다.
  • addAtrribute("name", name) : key값이 name이고 value값이 name인 데이터를 전달
  • return "hello-template" : template/hello-template.html 을 찾아 리턴한다.


View

뷰는 사용자에게 정보를 표시하는 역할을 한다.

화면을 그려주는 것이다.

resources/templates/hello-template.html

<html xmlns:th="http://www.thymeleaf.org">
<body>
<p th:text="'hello ' + ${name}">hello! empty</p>
</body>
</html>

HelloController.java helloMvc 메소드의 addAtrribute을 통해 전달받은 name을 ${name}에 치환한다.


localhos:8080/hello-mvc

Error

놀랍게도 에러가 난다.


에러의 이유를 살펴보려면 스프링부트 로그를 보면 된다.

WARN 28328 --- [nio-8080-exec-7] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.bind.MissingServletRequestParameterException: Required request parameter 'name' for method parameter type String is not present]

파라미터인 name이 전달되지 않았다는 뜻이다.


왜 이런 오류가 났을까?

HelloController.java 의 helloMvc 메소드에서 @RequestParam을 통해 데이터를 전달받도록 했기 때문이다.

전달받은 데이터가 없기 때문에 오류가 난것인데, 이를 해결하기 위해서는 localhost:8080/hello-mvc에 데이터값을 붙여준다.


이는 HTML의 GET 방식으로, 클라이언트에서 서버로 데이터를 전송할 때 ? 연산자 뒤에 변수이름과 값을 넣어 보낸다.


localhost:8080/hello-mvc?name=스프링

image

성공


MVC와 템플릿 엔진의 작동원리

image 출처 : 인프런 ; 스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 기술


  1. 웹 브라우저는 스프링부트의 내장 톰캣 서버로 해당 URL을 보낸다.
  2. 스프링 컨테이너에서는 웹 애플리케이션의 진입점 @ControllerhelloController를 확인하여 hello-mvc의 맵핑을 확인한다.
  3. 맵핑된 메소드를 통해 전달값과 리턴값을 확인하여 viewResolver로 보낸다.
    • 전달받은 값 name:spring
    • model(name:spring)
    • 리턴값 hello-template
  4. viewResolver에서는 helloController의 리턴 값을 확인하고 resources/templates 파일에서 hello-template.html을 찾아 웹 브라우저에 전달한다.
    • 이 과정에서 hello-template.html 은 Thymeleaf 탬플릿 엔진을 통해 랜더링 후 HTML로 변환되어 웹 브라우저에 전달된다.



API

데이터 포맷을 통해 데이터를 전달하는 컨텐츠이다.

데이터 포맷에는 XML, JSON 등이 있지만 최근은 JSON을 많이 사용한다.

@ResponseBody

API를 통해 개발을 하고자 할때는 @ResponseBody 어노테이션을 붙여준다.

Http Body에 데이터를 직접 넣어주겠다는 뜻이다.

이 어노테이션을 사용하여 컨텐츠를 생성한 후 웹 페이지의 소스보기를 클릭하면 문자 내용만 나올 뿐 컨텐츠의 소스(HTML)는 표현되지 않는다.

@ResponseBody 를 추가하지 않은 경우

image


@ResponseBody 를 추가한 경우

image


Controller

정적 컨텐츠와 MVC 패턴은 문자열을 리턴하지만, API 를 통해 객체를 리턴할 수 있다.

HelloController.java

@Controller
public class HelloController {
    @GetMapping("hello-api")
    @ResponseBody
    public Hello helloApi(@RequestParam("name") String name) {
        Hello hello = new Hello();
        hello.setName(name);
        return hello;
    }
}

위의 helloApi 는 Hello 객체를 생성해 리턴한다.

이 경우 html 파일이 따로 필요가 없다.

반환된 객체를 통해 또 다른 웹 컨텐츠를 생성할 수 있다.


localhost:8080/hello-api

image

JSON 형태인 {키 : 값} 으로 나타난다.


@ResponseBody 사용 원리

API 출처 : 인프런 ; 스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 기술


  1. 웹 브라우저는 스프링부트의 내장 톰캣 서버로 해당 URL을 보낸다.
  2. 스프링 컨테이너에서는 웹 애플리케이션의 진입점 @ControllerhelloController를 확인하여 hello-api의 맵핑을 확인한다.
  3. 맵핑된 메소드를 통해 전달값과 리턴값을 확인한다.
    • 전달받은 값 name:spring
    • 리턴값 hello(name:spring)
  4. helloController@ResponseBody에 의해 리턴된 객체가 HttpMessageConverter를 통해 JSON 방식으로 변환되어 웹 브라우저에 전달된다.
    • 여기서 JsonConverter는 객체를 JSON으로 변환할때 동작한다.

댓글남기기