본문 바로가기

Backend/Spring

[Spring] 웹개발 기초(정적,MVC,API)

728x90

Spring web개발 기초

3가지 방식

  • 정적 컨탠츠 : 별다른 서버 작업 없이 파일을 그대로 보여주는 것 
  • MVC와 템플릿 엔진 : 서버에서 html을 동적으로 바꾸어 보여주는 것 (예, php jsp) 
    • 템플릿 엔진을 M V C 방식으로 쪼개어 뷰를 템플릿 엔진으로 html을 프로그래밍하여 전달해줌 
  • API : json이라는 format을 이용하여 client에게 데이터를 전달하는 방식 ( 서버 끼리 통신 , react(client)단에서 화면을 그릴 때 )
    • 주로 객체를 json형식으로 view없이 반환해 주는 것 

 

정적 컨탠츠

 

default로 Spring에서는 resources/static 폴더 내에서 정적 컨탠츠에 대한 내용을 찾는다.

 

즉, 정적 컨탠츠를 생성하려면,

단순하게 resources/static폴더 내에 html파일을 작성해주면 된다. (어떠한 프로그래밍을 할 수는 없고 그대로 반환된다)

 

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>

 

이 역시 그대로 파일명으로 접근하면, 확인해 볼 수 있다.

localhost:8080/hello-static.html 로 접속하면, 다음과 같은 화면을 확인할 수 있다.

 

 

정적 컨텐츠 이미지 반환 원리

브라우저에서 localhost:8080/hello-static.html을 입력받는다.

그러면 내장된 Tomcat 서버에서 스프링으로 해당 요청을 넘긴다. 

스프링은 일단 먼저 controller에 hello-static와 mapping된 컨트롤러가 존재하는지 확인한다. 

존재하지 않으면, resource/static에서 hello-static.html을 찾는다. 

존재하므로 브라우저에게 반환한다.

 

 

MVC와 템플릿 엔진

 

MVC : Model, View, Controller를 의미한다. 

이전에는 view와 controller를 나누지 않고, view에서 모든 것을 전부 처리했다. (jsp) : Model1 방식 

 

하지만, View는 화면을 그리는데 모든 것을 초점을 두어야하며,

Controller와 Mode(화면에서 필요한 것들을 담아 뷰에   넘겨준다)l은 내부적 로직을 관리하는데 집중해야한다. 

그렇기에 모델, 뷰, 컨트롤러를 쪼개 MVC 패턴방식의 개발 방식이 등장하였다. 

 

예제를 위해, 

HelloController클래스에 다음과 같이 추가해 보도록한다.

package hello.hellospring.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-mvc")
    public String helloMvc(@RequestParam("name") String name, Model model){
        //parameter를 요청 , 정보를 담아서 view로델 보낼 모델

        model.addAttribute("name",name);// 받은 파라미터를 이용해서 name키의 값으로 지정
        return "hello-template"; //hello-template.html로
    }


}

이전 게시글과 다르게, 파라미터를 입력받아 모델에 값으로 넣는다.

또한, 값을 가진 모델을 뷰로 전달한다.

return "hello-template"이므로, resources/templates 의 하위에서 hello-template이라는 파일을 찾아 전달받은 모델을 기반으로 뷰를 랜더링한다

 

hello-template.html

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

여기서 hello! empty는 default로 보여지는 값이며, 서버에서 name을 받은 경우 empty대신 name이 출력된다.

 

localhost:8080/hello-mvc 로 접속하면 에러 페이지가 뜬다. 

name이라는 parameter를 받기로 했는데, 입력하지 않았기 때문. url에 입력해주면 뜬다.

localhost:8080/hello-mvc?name=YJ

 

동작 원리는 이전 게시글에서 설명한 것과 같다.

클라이언트에 넘어갈 때는 다음과 같이 변환되어 넘어가진다.

<html>
<body>
<p>hello! YJ</p>
</body>
</html>

 

API

API방식은 view없이 data가 직접 바로 전달된다.

 

일단 무엇이 다른지 보기위해 다음과 같은 방식으로 직관적으로 보여주면 다음과 같다. 

 

Controller에 다음과 같이 추가해준다.

다른점은 ResponseBody라는 것을 이용한다. 이것은 http 메세지 body부분에 아래 데이터를 직접 넣어줄 것을 의미한다.

@Controller
public class HelloController {


    @GetMapping("hello-string")
    @ResponseBody // http의 body부분에 이 데이터를 직접 넣어 주겠다는 의미
    public String helloString(@RequestParam("name") String name){
        return "hello" + name; //viewResolver가 아니고 data가 그대로 전달됨 
    }


}

viewResolver가 아니가 data가 직접 전달된다.

 

이를 확인할 수 있는 방법

template아래에 html을 만들지 않아도, 다음과 같이 출력되며,

소스보기를 이용해서 본 경우 <html>태그 등이 사용되지 않고 데이터만이 존재하는 것을 볼 수 있다.

 

template엔진은 화면을 가지고 뷰라는 템플릿이 있는 상황에서 이를 조작하는 방식이고, 

API방식은 데이터를 그대로 전하는 방식이다.

 

 

사실 API방식은 이렇게 사용되지 않고, 이 방식의 강점은 다음과 같은 방식으로 사용될 때 효과가 크다.

Controller에 다음과 같이 추가한다. 

@Controller
public class HelloController {


	//생략


    @GetMapping("hello-api")
    @ResponseBody
    public Hello helloApi(@RequestParam("name") String name){
        Hello hello = new Hello(); //Hello객체 생성

        hello.setName(name); //파라미터로 넘어온 name을 이용하여 데이터를 넣음
        return hello; //객체 반환
    }


    static class Hello { //class내에 class를 정의할 수 있음 HelloController.Hello
        private String name;


        //getter -> getName함수로 데이터를 꺼내 사용
        public String getName(){
            return name;
        }

        //setter -> setName함수로 데이터를 입력
        public void setName(String name){
            this.name = name;
        }
    }

}

 

더보기

Getter & Setter 단축키 : cmd + N 

 

private 변수에 접근하기 위한 method (javabean 표준방식 , property접근 방식 )

 

이제 이를 확인해보면,

이와 같이 json 형식으로 반환되는 것을 알 수 있다. 

key : value 형식으로 데이터를 간단하게 전달하여 사용할 수 있다. 

 

동작 방식

 

웹 브라우저에서 localhost:8080/hello-api를 입력받는다. 톰캣서버는 이를 스프링에 전달하여 hello-api가 있는지 확인한다.

hello-api는 ResponseBody라는 annotation이 붙어있다. 

(붙어 있지 않으면, viewResolver에게 전달하지만 붙어있으므로) HTTP응답에 이 body를 그대로 넘겨주는 방식으로 동작한다.

(→ HTTP의 BODY에 문자 내용을 직접 반환)

HttpMessageConverter를 동작시키는데(json형식으로 변경), 무엇이 오냐에 따라 다른 컨버터가 동작된다. 

1. (기본)문자인 경우 (전자의 예제) 이를 그냥 HTTP response에 넣어서 전달 : StringHttpMessageConverter

2. 객체인 경우, 스프링에서는 디폴트로 json방식으로 데이터를 가공하여 HTTP응답에 반환한다. : MappingJackson2HttpMessageConverter (json으로 변경하는 유명 라이브러리 중 하나 v2라 2임)

json을 요청한 웹브라우저/서버 등등으로 전달한다. 

*참고 : 클라이언트의 HTTP Accept헤더와 서버의 컨트롤러 반환 타입 등의 정보가 조합되어 'HttpMessageConverter'가 선택된다.

 

*복잡한 내용은 추후에 설명! 

728x90