본문 바로가기
Back-End/🌱 Spring Boot (java)

[Spring Boot 입문] MVC패턴과 템플릿엔진의 동작과 구현

by 코딩하는 동현😎 2023. 1. 14.

MVC 패턴 (Model-View-Controller)

MVC 는 Model, View, Controller의 약자 입니다. 하나의 애플리케이션, 프로젝트를 구성할 때 그 구성요소를 세가지의 역할로 구분한 패턴입니다.


사실 스프링은 아래와 같이 구조가 단순하지 않고 복잡하지만, 아직 데이터베이스도 다루기 전이고, 입문이기 때문에 이렇게 간소하게 표현 하겠습니다.

위의 그림처럼 사용자가 Controller를 조작하면 컨트롤러에서는 model을 통해서 데이터를 가져오고 그 정보를 바탕으로 표현을 담당하는 View를 제어해서 사용자에게 전달하게 됩니다.

라우터로 GET, POST 요청등을 받을때 어떤 동작을 적용시킬지는 컨트롤러라고 지정할 자바파일에다가 작성을 할 것이고,

그 자바파일에서는 모델에다가 데이터를 넣고, 템플릿엔진 등을 띄워서 사용자에게 보여줍니다.

템플릿엔진은 모델에다가 넣은 데이터를 받아서 html로 표현하게 되는 데, 실습을 통해서 보는것이 빠릅니다.


파일 구조

컨트롤러를 만들기 위해서 자바 폴더 안에 controller 패키지를 만들어 줍니다.

패키지는 만드는 법은 간단합니다. 그냥 폴더를 만들어주고 자바 파일을 안에 넣어주면 그것이 패키지 인데,

그 자바파일 맨윗줄에 package <패키지경로/이름>; 라고 명시해야 합니다.


템플릿 엔진 이용하기 (Thymeleaf 필요)

그 안에 HelloController 클래스를 만들어주고 아래와 같이 작성합니다.

패키지를 설정해주고, @Controller 어노테이션을 해줘야지 컨트롤러 파일이라고 스프링이 인식합니다.

import 문들은 엔터치면서 자동완성하면 자동으로 선언될 것입니다.

라우터를 인식하기 위해선 GetMapping(루트이름)을 해주고 바로 밑에 실행할 함수들을 작성 해주면 됩니다.

 

controller/HelloController.java

package example.boot.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){
        model.addAttribute("data", "동현의 코딩여행");
        return "hello";
        // templates/hello.html에 자동으로 매핑돼서 model을 전달함
    }

}

보다싶히 컨트롤러가 모델에다가 data = 동현의 코딩여행 이라는 정보를 넣어주고 hello를 반환하는데, hello라고하면 templates 폴더에 hello라는 이름을 가진 html이 자동으로 매핑돼서 디스플레이 됩니다.

 

보다싶히 마우스가 가리키는 스프링에 관련한 Model을 자동완성해야겠죠?ㅎㅎ

 

templates/hello.html

<!Doctype html>

<html xmlns:th="http://www.thymeleaf.org"> <!-- thymeleaf 문법을 사용하기 위해 선언 -> th 로 www.thyleaf.org 를 연결-->
<head>
    <title>Hello Spring</title>
    <meta http-equiv="Content-Type" content="text/html"; charset="utf-8" />
</head>
<body>
    <h1>
        <p th:text="'안녕하세요 '+ ${data}"></p> <!-- th 를 사용해서 thymeleaf 문법을 사용함 -->
    </h1>
</body>
<footer>동현의 코딩여행</footer>
</html>

모델에 넣어준 data = 동현의 코딩여행 정보는 <p th:text> 태그에 전달되고 아래와 같이 출력하게 됩니다.

/hello 라우터로 접속했을때. (혼자 실습할땐 localhost:8080으로 하셔도 됩니다.)


Parameter를 이용해 이름 받고 출력하기

 

아래와 같이 hello-template 라우터에 대한 함수를 작성해줍니다.

@RequestParam("파라미터이름") String 변수이름

위와 같이 인수에 작성해주면 파라미터의 값을 인수로 받을 수 있습니다.

 

여기서 주의할 점은 파라미터로 받는 값은 무조건 문자열 객체라는 것입니다.

적어도 인수에는 형식을 String으로 해야됩니다.

 

controller/HelloController.java

package example.boot.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;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class HelloController{

    @GetMapping("hello")
    public String hello(Model model){
        model.addAttribute("data", "동현의 코딩여행");
        return "hello";
        // templates/hello.html에 자동으로 매핑돼서 model을 전달함
    }
	
    //추가
    @GetMapping("hello-template")
    public String hello_template(@RequestParam("name") String name,  Model model) {
        // /hello-template?name= 형식으로 받으면 name에 파라미터가 저장됩니다.
        model.addAttribute("data", name);
        return "hello";
        // templates/hello-template.html에 자동으로 매핑돼서 model을 전달함
    }

}

/hello-template?name=<이름> 라우터로 접속했을때


정적 파일에 접근하기

static에다가 넣은 파일들은 별로도 컨트롤러를 지정하지 않아도다 자동으로 라우터로 접근할수 있습니다.

 

static/hello-static.html

<!Doctype html>
<head>
    <title>Hello Spring</title>
    <meta http-equiv="Content-Type" content="text/html"; charset="utf-8" />
</head>
<body>
    <h1>
        <p>Hello Static File!!</p> <!-- th 를 사용해서 thymeleaf 문법을 사용함 -->
    </h1>
</body>
<footer>동현의 코딩여행</footer>
</html>

 

/hello-static.html 라우터로 접속했을때 자동으로 html파일을 접속할 수 있습니다.


Responce에 API 객체 보내기(JSON)

@ResponseBody 어노테이션을 추가하면 반환되는 값이 템플릿 엔진 등을 통하지 않고, HTTP객체에 JSON파일로 보내게 됩니다.

JSON은 js객체 파일로, 자바 객체를 보내도, js객체로 자동으로 변환이 돼서 보내게됩니다.

 

객체를 만들기 위해서 Hello 객체를 만들어주고, 필드들을 다 private로 설정합니다.

Hello 객체를 return 시켜주면 json객체로 반환하는데, 무조건 getter를 만들어줘야 출력할 수 있습니다.

 

hello 객체안에 getter, setter 전부 설정한 모습입니다.

 

controller/HelloController.java

package example.boot.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;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class HelloController{

    @GetMapping("hello-api")
    @ResponseBody
    public Hello hello_api(@RequestParam("age") String age){
        Hello hello = new Hello();
        try {
            hello.setAge(Integer.parseInt(age));
        } catch (Exception e) {
            hello.setAge(22);
        }
        return hello;
        
    }
    

    static class Hello {
        private String name;
        private int age;
        public Hello(){
            this.name = "동현의 코딩여행";
        }

        public void setAge(int age){
            this.age = age;
        }

        public int getAge(){
            return this.age;
        }

        public void setName(String name){
            this.name = name;
        }
        
        public String getName(){
            return this.name;
        }
    }
}

/hello-api?age=21 로 접근한 모습입니다.

반응형

댓글