스프링 입문 - 02. 스프링 웹 개발 기초

2023. 4. 16. 21:01Spring/Java

thymeleaf 템플릿 엔진 작동 확인

// java/hello/hellospring/controller/HelloController.java

@Controller
public class HelloController {
    @GetMapping("hello")
    public String hello(Model model){
        model.addAttribute("data", "hello!!");
        return "hello";
    }
<!-- resources/templates/hello.html -->

<!doctype html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
<p th:text = "'안녕하세요. ' + ${data}"> 안녕하세요. 손님</p>
</body>
</html>

@Controller

Controller class 에는 @Controller 어노테이션을 적어 준다. 이는 Spring Bean으로 등록시켜 주고 Controller 클래스라고 쉽게 알 수 있게 해 준다.

 

@GetMapping

Controller 내 HTTP GET reqeust를 메소드와 mapping 시키기 위함이다. @GetMapping("hello)는 localhost:8080/hello의 url로 들어갈 때 동작한다.

 

Model

parameter로 들어가 있는 Model은 Spring Model에 추가하고, 검색하기 위한 인터페이스이다.

model.addAttribute("data", "hello!!");

는 model의 data라는 key에 hello라는 값을 추가한다는 의미이다.

html에서 ${data}로 value를 받아올 수 있다.

 

return "hello"

"hello"라는 이름을 가진 view를 호출한다. (여기선 templates 폴더 안의 hello.html)

 

템플릿 엔진 작동원리

  1. client가 url에 접속하여 request를 보냄.
  2. 내장 tomcat 웹서버에서 스프링 컨테이너로 전달
  3. 스프링 컨테이너가 해당 controller의 함수 실행
  4. controller에서 viewResolver로 데이터 전달
  5. viewResolver는 받은 데이터를 템플릿 엔진에서 처리
  6. 처리된 html 파일을 다시 tomcat 웹서버를 통해 client로 전달.

 

정적 콘텐츠

resources/static/hello-static.html 

정적콘텐츠는 서버에서 직접 클라이언트에 파일 채로 보내주는 것인데, 여기서는 html 을 하나 만들고 controller도 없이 접근하는 것을 보여준다.

정적 컨텐츠 작동원리

  1. client가 url에 접속하여 request를 보냄.
  2. 내장 tomcat 웹서버에서 스프링 컨테이너로 전달
  3. 스프링 컨테이너가 해당 controller의 함수 찾아봄
  4. 함수가 없으므로 static 파일 중 hello-static.html을 찾아봄
  5. 다시 tomcat 웹서버를 통해 client로 전달.

 

MVC와 템플릿 엔진

    @GetMapping("hello-mvc")
    public String helloMVC(@RequestParam("name") String name, Model model){
        model.addAttribute("name", name);
        return "hello-template";
    }
<!-- resources/templates/hello-template.html -->

<!doctype html>
<html lang="en" xmlns:th = "http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
<p th:text = "'hello' + ${name}">hello! empty!</p>
</body>
</html>

@RequestParam

해당 url에서 "name"이라는 query 값을 찾아서 name이라는 parameter에 넣어준다.

required가 true가 기본이므로 query가 없으면 에러가 난다. required를 false로 지정해 주면 query가 없을 때 에러가 나지 않게 해 줄 수도 있다.

API

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

@ResponseBody

이 annotation을 사용하면 위에서 사용한 ViewResolver를 사용하지 않고 String을 직접 HTTP Body (html body 아님) 반환한다.

 

@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;
    }
}

위와 같이 String이 아닌 객체로 호출도 가능하다.

정말 신기하게도 객체를 호출하면 json형태로 반환이 된다.

 

ResponseBody 작동원리

  1. client가 url에 접속하여 request를 보냄.
  2. 내장 tomcat 웹서버에서 스프링 컨테이너로 전달
  3. 스프링 컨테이너가 해당 controller의 함수 실행
  4. controller에서 HttpMessageConverter로 전달
  5. JsonConverter 혹은 StringConverter가 작동
    기본 문자 처리 : StringHttpMessageConverter
    기본 객체 처리 : MappingJackson2HttpMessageConverter
  6. 그대로 client에 전달 (string -> string, object -> json)