[SpringBoot]/[Spring 강의]

[Spring 강의 작성] 스프링 웹 개발 방식 3가지 실습

Hevton 2023. 1. 4. 11:19
반응형

 

스프링으로 웹개발을 하는 방식은 크게 세 가지가 있다.

 

  1. 정적 컨텐츠
    -> 이미 정해진 html 그냥 그대로 보여주기
    localhost:8080/good.html로 이동할 경우, 스프링부트 내에서 good에 매핑된 controller가 있는지 확인하고,
    없으면 resources/static/good.html을 찾아서 보여준다고 보면 된다.

  2. MVC와 템플릿 엔진
    -> html을 동적으로 수정하여 보여주기
    템플릿 엔진 : php, jsp, 타임리프

    Model, View, Controller
    View보여지는 것에 모두 집중. Controller와 그를 이용하는 Model비즈니스 로직을 담당한다.


  3. API
    -> 모바일 등 프론트엔드를 구분하여, 다양한 프론트와 통신할 때, 등 데이터 기반으로 통신. 주로 json 포맷을 이용.
    -> RESTful 방식을 적용 권장

    @Controller + @ResponseBody = @RestController

 

2, 3번 모두 동적 방식이라고 볼 수 있는데

웹페이지 자체를 보여주게 하느냐, 아니면 데이터를 넘기냐의 차이가 있다.

 

 

 

본격적으로 진행할때에는

RESTful 기반의 웹서버를 구현할 것이지만

그 전에 간단하게 웹뷰를 뿌려주는 방식으로, 템플릿 엔진 타임리프를 이용해 동적인 웹페이지를 생성하여 프론트 단에서 보여주는 방법을 간단하게 다룬다.

 

타임리프에 대해서 자세히 알고 싶다면 : https://hevton.tistory.com/821

 

 


 

 

SpringBoot가 제공하는 Welcome page 위치는 

src -> resources -> static -> index.html 이다.

static 패키지나 index.html 파일이 없으면 생성해주면 된다.

여기에 이렇게 파일을 만들어주면 스프링부트가 Welcome page의 위치를 이곳으로 인식해서 뿌려준다.

 

Welcome page란 주소만 입력했을 때 이동하는 곳이다. 기본적으로 주소만 입력할 경우

스프링 부트 내에서 index.html 파일을 찾아서 보여주고, 이것은 웹 서버들의 공통된 약속? 이라고 볼 수 있다.

 

static 패키지 내의 다양한 파일 (ex. good.html)을 넣고

localhost:8080/good.html 로 이동하면 해당 파일로도 이동할 수 있다.

 

index.html

<!DOCTYPE HTML>
<html>
<head>
    <title>Hello</title>
</head>
<body>
Hi
</body>
</html>

 

하지만 이러한 방식은, 정적인 웹 사이트 방식이다.

이미 만들어진, 변함없는 html을 매번 똑같이 뿌려주는 방식이다.

 

 

그럼 동적인 웹 사이트는 어떻게 만드는가?

바로 템플릿 엔진을 사용한다. 템플릿 엔진에는 타임리프가 있다.

 

 

우선, Controller를 만들어준다.

Controller는, 유저의 입력을 어떻게 처리해줄지를 결정하는 공간이라고 생각하면 된다.

package io.spring.hevton.Hello.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class HelloController {

    @GetMapping("hello")
    public String hello(Model model) { // mvc 중에 model
        model.addAttribute("data", "Good Morning"); // key가 'data', 값은 'Good Morning'
        return "hello"; // templates 의 hello.html로 가라는 것. 이 작업은 viewResolver가 찾아서 랜더링을 해준다.
    }
}

GetMapping("hello") 이렇게 하게 되면

localhost:8080/hello 로 이동하게 되면 아래 hello 함수가 실행된다.

 

스프링부트가 Model을 생성해서 함수 인자로 넘겨주게 되고, 우리는 그 model에 attribute를 추가해준다.

key는 "data" 이며, value는 "Good Morning" 으로 넣어주었고

return으로는 "hello"를 넘겨주었다.

 

여기서 hello의 의미는, resources/templates/hello.html 파일을 찾아서 보여주라는 뜻이다.

따라서 우리는 이 경로에 파일을 생성해준다. ViewResolver가 이런 View를 찾고, 템플릿 엔진을 연결시켜준다.

 

hello.html

<!DOCTYPE html>
<html xmlns:th="http//www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Hello</title>
    <meta http-equiv="Content-Type" content="text.html"; charset="UTF-8"/>
</head>
<body>

<p th:text="'안녕하세요. ' + ${data}">템플릿 엔진으로 동작 안할 땐 이게 보여짐</p>

</body>
</html>

${data} 라고 작성하면, 우리가 model.addAttribute로 넘겨주었던 

key : data

value : Good Morning

를 통해, value 값인 Good Morning이 들어가게 된다.

 

타임리프 템플릿 엔진을 이용해 코드를 작성할 때 장점이 뭐냐면,

템플릿 엔진을 이용해서 보여질 땐 '안녕하세요.  ~' 저 부분이 보여지고,

그냥 html 자체를 열 때에는 태그 내의 글자가 보여지게 된다.

 

 

이렇게 하고 서버를 재시작한다.

 

그리고 브라우저에

localhost:8080/hello 로 이동하면

이렇게 페이지를 받아볼 수 있다.

 

 

HelloController에 코드를 조금 더 추가해보자.

package io.spring.hevton.Hello.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;

@Controller
public class HelloController {

    @GetMapping("hello")
    public String hello(Model model) { // mvc 중에 model
        model.addAttribute("data", "Good Morning"); // key가 'data', 값은 'Good Morning'
        return "hello"; // templates 의 hello.html로 가라는 것. 이 작업은 viewResolver가 찾아서 랜더링을 해준다.
    }

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

GetMapping으로 hello-mvc를 추가했다.

우리가 동적으로 페이지를 수정한다고 했는데, data의 value가 계속 Good Morning으로 고정시켜놓았으니

사실상 데이터가 변경되지 않고 있다.

 

그렇기 때문에 입력에 따라 정말 완벽히 동적으로 하기 위해서, 이 부분을 동적으로 변경해주기 위해

이번엔 @RequestParam을 추가했다. 사용자로부터 name 을 입력받아서 사용하려는 목적이다.

 

resources/templates/hello-template.html을 만들어준다.

 

<html xmlns:th="http://www.thymeleaf.org">
<body>
<p th:text="'hello, ' + ${name}">템플릿 엔진으로 동작 안할 땐 이게 보여짐</p>
</body>
</html>

 

이제 서버를 키고, 웹브라우저에 이렇게 입력해보자.

name을 변경함에 따라 동적으로 변경됨을 확인할 수 있다.

 

+

html 파일을 변경하면, 매번 서버를 재시작해주어야하는데

spring-boot-devtools 라이브러리를 추가하면, 'html' 파일을 컴파일만 해주면 서버 재시작 없이 View 파일 변경이 가능하다.

 

 

 

 

이번엔 세 번째인 Api방식으로 진행해본다.

이번엔 @GetMapping에 이어서 @ResponseBody를 추가하여, 이렇게 코드를 작성해본다.

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

@ResponseBody는 데이터 그대로 넘겨준다는 특징이 있다. 그래서 이대로 실행해서 웹브라우저에서 소스를 보면

 html 태그도 없이 그냥 이 문자, 글자 그대로가 보여지게 된다. Raw하게.

근데 이렇게 사용하려고 @ResponseBody를 사용하진 않는다.

 

 

 

그럼 어떤 이유로 사용할까?

이번엔 코드를 이렇게 작성해본다.

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

        return hello;
    }

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

 

그리고 서버를 실행해서, 브라우저에 다음과 같이 입력해본다.

@ResponseBody 하고 객체를 반환해주면, json 형태로 리턴되는 것을 확인할 수 있다. 

@ResponseBody가 사용되면, viewResolver 대신에 HttpMessageConverter가 동작하는데

기본 문자는 StringHttpMessageConverter, 객체는 MappingJackson2HttpMessageConverter가 동작하는데

후자는 객체를 Json 형태로 변환해준다.

 

 

요즘에는 이렇게 하기 보다는,

아예 Controller 자체를 @Controller 대신에 @RestController로 하고, 객체를 리턴해주면 동일한 효과를 볼 수 있다.

 

@Controller + @ResponseBody = @RestController 라서, RESTful 기반 서비스를 구축할 때에는 아예 @RestController를 사용하면 된다.

 

반응형