[java, #18] MVC 기초1

1. 목적

MVC를 이용해서 front-end에 현시 정보와 데이터 정보를 동시에 전달하고 표시할 수 있다.

2. 개념

MVC는 Model, View, Controller의 약자다. 단어를 보면 함께 붙어다니며 무언가를 하는 것 같은 느낌이 든다. 과연 무엇을 할까?

위에서 언급했듯이 현시 정보와 데이터 정보를 함께 앞단(front-end)에 전달한다. 3개의 단어를 구체적으로 알아보자.
첫 번째, Controller는 front-end에서 요청 정보 또는 대응 정보를 응답해주는 역할을 한다. 일종의 자동응답기라고나 할까? 요청 정보가 들어오면 Model 또는 View에 전달하고, 최종 정보를 받아 front-end에 전달한다.
두 번째, Model은 데이터를 가공하는 역할을 한다. controller에서 받은 데이터를 이용해서 내부에서 가공한 후 view로 보낸다.
View는 Model에서 받은 데이터 또는 결과를 현시정보와 함께 Controller로 전송한다. Controller는 이 정보를 받아 다시 front-end로 전송하는 것이다.

'백문이 불여일타'다. 실제로 어떻게 구현되는지 예시로 알아보자.

3. 예시

아래 코드는 MVC를 활용한 앞단과 뒷단의 데이터 교환을 나타내고 있다. thymeleaf라는 MVC를 활용했다. '중점적으로 보아야 할 것은 HTTP 상에서 response header와 response body가 어떻게 표시되는가' 이다.


@Controller   # HelloResponseController는 Controller 입니다. Json 형식으로 데이터가 오가지 않습니다.
@RequestMapping("/hello/response") # 기본 api는 /hello/response 이다.
public class HelloResponseController {
   
   
  
    @GetMapping("/html/redirect")
    public String htmlFile() {
        return "redirect:/hello.html";
    }
    // 결과: /hello/response/html/redirect 로 접속해도 hello.html로 이동한다. response head에는 아래와 같이 반환값은 relocated 되었다고 표시된다.
    // [Response header]
    //   Location: http://localhost:8080/hello.html
    
    

    
    @GetMapping("/html/templates")  # /html/redirect/html/templates에 get방식으로 접속하면
    public String htmlTemplates() {
        return "hello"; # template/hello.html 을 읽는다.
    }
    // [Response header]
    //   Content-Type: text/html # text 형식으로 된 html 파일
    // [Response body]
    // * resources/templates/hello.html 의 text 내용
    //   <!DOCTYPE html>
    //   <html>
    //     <head><meta charset="UTF-8"><title>By Templates engine</title></head>
    //      <body>Hello, Spring 정적 웹 페이지!!</body>
    //   </html>
    
    
    
    

    
    @GetMapping("/body/html") # /html/redirect/body/html 로 get방식으로 접속하고,
    
    @ResponseBody # body에 return을 객체로 입력하겠다는 표시. 
    public String helloStringHTML() {
        return "<!DOCTYPE html>" +
                "<html>" +
                "<head><meta charset=\"UTF-8\"><title>By @ResponseBody</title></head>" +
                "<body> Hello, 정적 웹 페이지!!</body>" +
                "</html>";
    }
    // [Response header]
    //   Content-Type: text/html # text로 구성된 html 파일
    // [Response body]
    //   <!DOCTYPE html>
    //   <html>
    //     <head><meta charset="UTF-8"><title>By @ResponseBody</title></head>
    //      <body>Hello, Spring 정적 웹 페이지!!</body>
    //   </html>
    
    
    
    # MVC의 Model에 값을 전송하는 방법: Model을 불러온다.
    @GetMapping("/html/dynamic")  # /html/redirect/html/dynamic 으로 get방식으로 접속하면
    public String helloHtmlFile(Model model) {  # thymeleaf의 모델을 불러오고
        visitCount++; # count를 증가시킨다.
        model.addAttribute("visits", visitCount);  # 증가시킨 값을 model에 전송한다. front-end에 visits라는 변수가 있다. visits라는 변수에 visitCount를 입력하여 현시하라는 뜻이다.
        // resources/templates/hello-visit.html
        return "hello-visit";  #hello-visit.html로 전송한다.
    }

    private static long visitCount = 0;
    
    // [Response header]
    //   Content-Type: text/html 
    // [Response body]
    // * resources/templates/hello-visit.html 의 text 내용
    
    
    


    @GetMapping("/json/string") 
    @ResponseBody   # 반환값을 객체로 변환하여 body에 입력시킨다는 의미이다.
    public String helloStringJson() {
        return "{\"name\":\"BTS\",\"age\":28}";
    }
        // [Response header]
    //   Content-Type: text/html
    // [Response body]
    //   {"name":"BTS","age":28}
    
    
    

    // [Response header]
    //   Content-Type: application/json
    // [Response body]
    //   {"name":"BTS","age":28}
    @GetMapping("/json/class")
    @ResponseBody # 객체로 변환 후 body에 입력하겠다는 의미. 맨 위 Controller이기 때문에 사용하는 듯 하다. 만약 RestController 였다면 사용하지 않아도 된다.
    public Star helloJson() {
        return new Star("BTS", 28);
    }
}

4. 인지한 사실

4.1 이동 대상이 존재한다.

request와 response 사이에 보이지 않는 무언가가 이동한다는 것이 밝혀졌다. 그것의 명칭을 정확히 알지 못하지만 3개로 세부화 할 수 있다.
첫 번째, request Head이다. front-end에서 back-end로 각종 정보가 넘어가는데, 그러한 정보들이 현시된다.
두 번째, response head이다. 첫 번째와는 반대로 back-end에서 front-end로 넘어가는 정보이다. 데이터 형식이 중요하다. response 데이터 또한 볼 수 있다.
세 번째, 일반 정보이다. 데이터를 가져오는 활동에 대하여 성공 여부를 알려주며, 주소 정보 등을 보여준다. 에러를 잡는데 요긴한 힌트를 주곤 한다.

4.2 responseBody

@responseBody는 back-end에서 front-end로 데이터를 보낼 때 사용한다. 보내고자 하는 값을 객체 형식으로 body에 맵핑(mapping), 쉽게 말해서 객체 형식으로 입력해서 보내고 싶다면 사용한다. @Controller가 사용된다면(즉, json 형식의 데이터를 response 하지 않는다면) .html을 제외하고 거의 모든 api에 사용하는 것 같다. 위 코드에서도 html을 제외하고 모든 api에 사용하지 않았는가!

5. 내일 여정

내일은 MVC에 대해서 추가적으로 알아볼 것이다. 중점적으로 알아볼 HTTP, MVC 동작 원리에 대하여 구체적으로 알아볼 것이다. 추가적으로 @RequestMapping과 @Getmapping, @PostMapping 등의 차이에 대해서도 핵심적인 내용만 알아본다.

좋은 웹페이지 즐겨찾기