[스프링 입문] Section 2. 스프링 웹 개발 기초

 

본 포스팅의 내용은

인프런 김영한님의 스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술 강의 기반으로 작성했습니다.

 

📜 개요

웹을 개발하는 것은 크게 세 가지 방법이 있음

정적 컨텐츠, MVC와 템플릿 엔진, API

 

🌱 정적 컨텐츠

서버에서 별도의 처리 없이 웹브라우저로 파일을 그대로 내려주는 것.

 

resources/static/hello-static.html

<!DOCTYPE HTML>
<html>
<head>
    <title>static content</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
정적 컨텐츠 입니다.
</body>
</html>

 

Spring은 기본적으로 정적 컨텐츠 기능을 제공함. resources/static 산하에 있는 파일은 정적 컨텐츠로 분류된다. 가령 /hello-static.html 요청이 들어오면 톰캣 서버는 이를 받아서 스프링에 넘긴다. 스프링은 해당 요청에 매핑되는 컨트롤러가 없음을 확인하고 resources/static에서 컨텐츠를 찾아서 랜더링한다.

 

🍃 MVC와 템플릿 엔진

웹브라우저로 html 파일을 그대로 내려주는 것이 아니라 서버에서 프로그래밍한 결과에 따라 html을 동적으로 바꿔준 뒤 내려주는 것으로 html을 동적으로 바꾸는 기능을 템플릿 엔진이 제공한다. 앞서 작성한 정적 컨텐츠와 대조적으로 동적 컨텐츠를 생성하며 여기에 Model, View, Controller 패턴이 사용됨.

 

Controller

 실행 http://localhost:8080/hello-mvc?name=spring

@GetMapping("hello-mvc")
public String helloMvc(@RequestParam(value = "name") String name, Model model){
    model.addAttribute("name", name);

    return "hello-template";
}

 

resources/template/hello-template.html

<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>Hello</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<p th:text="'안녕하세요. ' + ${name}" >안녕하세요. 손님</p>
</body>
</html>

 

웹브라우저에서 /hello-mvc?name=spring을 넘기면 스프링 부트에 내장된 톰캣 서버를 먼저 거친다. 톰캣 서버는 hello-mvc 요청이 왔다고 스프링에게 던지면, Spring은 hello-mvc가 helloController의 helloMvc 메서드에 매핑이 되어있음을 확인하고 메서드를 실행한다.

 

메서드에선 Model에 key(name)와 value(spring)를 세팅하고 "hello-template"을 반환한다. viewResolver는 templates/hello-template.html을 찾아서 동적으로 html을 꾸리고 렌더링 해서 웹 브라우저에 전달한다.

 

 

🖥️ API

웹 브라우저로 html을 내리는 게 아닌 데이터를 바로 내리는 방식으로 컨트롤러의 메서드에 @ResponseBody 어노테이션을 사용한다. 문자(열)을 반환하면 http body에 문자가 직접 들어가고 객체를 반환하면 json으로 변환된다.

 

@ResponseBody : http에서 header와 body가 있는데 body에 메서드의 반환값을 직접 넣어줄 때 사용하는 어노테이션으로 메서드가 종료되고 viewResolver가 아닌 HttpMessageConverter가 동작한다.

 

 

@ResponseBody 문자 반환

실행 http://localhost:8080/hello-string?name=spring

@GetMapping("hello-string")
@ResponseBody
public String helloString(@RequestParam("name") String name){
    return "hello" + name;
}

 

@ResponseBody 객체 반환

실행 http://localhost:8080/hello-api?name=spring

@GetMapping("hello-api")
@ResponseBody
public Hello helloApi(@RequestParam("name") String name){
    Hello hello = new Hello(name);

    return hello;
}

@Getter
@AllArgsConstructor
static class Hello{
    private String name;
}

 

정리해 보자. 웹 브라우저로부터 /hello-api?name=spring 요청이 오면 톰캣 내장 서버는 스프링에 hello-api를 던진다. 스프링은 컨트롤러에서 hello-api에 매핑된 메서드를 찾는다.

메서드에 @ResponseBody 어노테이션이 붙은 걸 확인하고 반환 값을 HTTP Body에 넣을 것으로 인식한다.

 

여기서 두 가지로 갈리는데 문자열을 반환했다면 문자열 자체를 body에 넣을 값으로 인식하고, 객체를 반환하면 JsonConverter로 객체를 직렬화해서 body에 넣어준다.