IT/Spring

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

ʕ민지ʔ 2023. 7. 24. 14:25

웹 개발 방식 3가지

  1. 정적 컨텐츠
  2. MVC와 템플릿 엔진
  3. API

📝 정적 컨텐츠

정적 컨텐츠

스프링 부트는 정적 컨텐츠 기능을 자동으로 제공한다. Spring Boot Features

 

정적 컨텐츠 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>

resources/static/hello-static.html

 

정적 컨텐츠 동작 원리

  1. 스프링은 가장 먼저 controller에서 hello-static이 있는지 찾는다. 이때, controller가 먼저 우선순위를 갖는다
  2. 없으면 resources/static에서 hello-static을 찾는다. <정적 컨텐츠>

📝 MVC와 템플릿 엔진

MVC

  • Model, View, Controller
  • 관심사 분리가 목적!
  • 사용자가 controller를 조작하면 controller는 model을 통해서 데이터를 가져온다. 그리고 이 정보를 바탕으로 시각적인 표현을 담당하는 View를 제어해서 사용자에게 전달하게 된다.

 

HelloController.java

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

java/hello/hellospring/controller/HelloController.java

 

  • @RequestParam("name") 로 외부(웹)에서 파라미터를 받아온다. 이전에는 문자열 “hello!!” 을 직접 넘겨줬는데, 이번에는 외부에서 파라미터를 받아온다는 점에서 다르다.
  • model.addAttribute("name", name); 파라미터로 넘어온 name을 넘긴다.
  • 이때 "name" 이 key이고, name이 String name 의 name이다.

 

hello-template.html

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

resources/templates/hello-template.html

 

  • 타임리프 템플릿의 장점은 서버 없이 html 정적 파일을 열어봐도 구조를 알 수 있다는 점이다.
  • 즉, hello! empty 는 서버가 동작하지 않을 때 보여지는 내용이다.

 

서버가 동작하는 경우 (템플릿 엔진 동작) → ${name} 내용이 전달받은 값으로 치환됨

서버가 동작하지 않는 경우 (파일 경로로 직접 들어가는 경우)

에러가 남! 에러가 나면 일단 로그를 확인해야 한다.

2023-07-14 15:30:45.915  WARN 888 --- [nio-8080-exec-4] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.bind.MissingServletRequestParameterException: Required request parameter 'name' for method parameter type String is not present]

WARN warning이 뜬 것을 확인할 수 있다.

Required request parameter 'name' for method parameter type String is not present 기본으로 name 파라미터를 넘겨야 하는데, http://localhost:8080/hello-mvc 로 name을 넘기지 않았기 때문에 발생한 에러이다.

잘 동작하는 것을 확인할 수 있다.

 

MVC, 템플릿 엔진 동작 원리


📝 API

정적 컨텐츠를 제외하면 2가지만 기억하면 된다.

  1. HTML로 내리는지
  2. API 방식으로 데이터를 바로 내리는지

HelloController.java

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

java/hello/hellospring/controller/HelloController.java

 

@ResponseBody 의 의미

  • html의 body 태그 아님
  • http의 head부와 body부 중 응답 body부에 "hello " + name 데이터를 직접 넣어주겠다는 의미이다. 이 문자가 요청한 client에 그대로 넘어감!
  • 웹 템플릿 엔진과의 차이는 view가 없다는 것이다.

웹 템플릿 엔진과 API의 차이

웹 템플릿 엔진 (MVC)
API

hello-string 즉, API의 페이지 소스를 보면 html 태그 전혀 없이 그냥 적은 문자열만 있음

  • 템플릿 엔진 : 화면을 가지고 view라는 템플릿을 조작하는 방식
  • API : 데이터를 그대로 내려주는 방식

→ 하지만 문자만 사용하는 이 예시는 사실 잘 쓰지 않음. 문자 대신 데이터를 사용하는 경우가 중요!

HelloController.java

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

    static class Hello {
        private String name;
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
    }

java/hello/hellospring/controller/HelloController.java

return hello; 으로 문자가 아닌 데이터를 넘기는 경우

→ {"name":"spring"} JSON 방식으로 표현된다!

 

@ResponseBody 문자 반환

@ResponseBody 를 사용하면 뷰 리졸버( viewResolver )를 사용하지 않음

대신에 HTTP의 BODY에 문자 내용을 직접 반환(HTML BODY TAG를 말하는 것이 아님)

 

@ResponseBody 객체 반환

ResponseBody 를 사용하고, 객체를 반환하면 객체가 JSON으로 변환됨

 

@ResponseBody 동작 원리

@ResponseBody 를 사용하는 경우

  1. HTTP의 BODY에 문자 내용을 직접 반환
  2. viewResolver 대신에 HttpMessageConverter가 동작
  3. 반환된 것에 따라 다르게 처리
    • 기본 문자 처리: StringHttpMessageConverter
    • 기본 객체 처리: MappingJackson2HttpMessageConverter
      → JSON 방식으로 만들어서 HTTP 응답에 반환하는 게 기본 정책이다.
      → 객체를 JSON으로 바꾸는 유명한 라이브러리에 Jackson 과 GSON 이 있는데, 스프링은 이 중 Jackson 을 기본으로 탑재하도록 했다.
    • byte 처리 등등 기타 여러 HttpMessageConverter가 기본으로 등록되어 있음