4 분 소요


1. 스프링 웹 개발 방법

웹을 개발하는 3가지 방법이 존재한다.

개발 방법 설명
정적 콘텐츠 - HTML, CSS, JavaScript 파일과 같은 고정된 컨텐츠를 제공하는 방식이다. (이전 포스팅의 Welcome Page와 같음)

- 서버에서 파일을 클라이언트에게 그대로 전달하며, 데이터나 페이지 내용이 변경되지 않는 경우에 주로 사용한다.

간단히 파일을 그대로 내려주는 방식
MVC와 템플릿 엔진 서버에서 프로그래밍을 통해 HTML을 동적으로 바꿔서 내려주는 것을 말한다. 그렇게 하기위해 MVC(Model-View-Controller) 방식의 패턴으로 개발하는 경우가 많다.

- Model: 데이터와 비즈니스 로직을 처리
- View: 사용자에게 데이터를 표시하는 역할
- Controller: 사용자 입력을 처리하고 모델과 뷰를 업데이트

즉, 템플릿 엔진은 미리 정의된 템플릿 파일과 데이터 소스를 결합하여 HTML, XML, 또는 다른 문서 형식을 생성한다.
API XML이나 JSON과 같은 데이터 구조 포맷으로 클라이언트에 데이터를 전달하는 방식을 말한다. (서버끼리 통신할 때 등)



2. 정적 컨텐츠

2.1 정적 컨텐츠 제공

스프링 부트 정적 컨텐츠 기능은 [여기↗] 에서 자세히 확인할 수 있다.


기본 설정으로 스프링 부트는 정적 폴더를 /static에서 제공한다.

resources/static/hello-static.html을 만들어보자.

그 후, 아래 코드를 실행하고 http://localhost:8080/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>


즉, 정적 컨텐츠는 서버에서 파일을 클라이언트에게 그대로 전달하는 것을 볼 수 있다.


2.2 정적 컨텐츠 동작 방식

① URL 요청

사용자가 웹 브라우저에서 http://localhost:8080/hello-static.html로 접속한다.


② 내장 톰캣 서버 처리

스프링 부트는 내장된 톰캣 서버를 사용하므로, 해당 URL 요청은 톰캣 서버로 전달된다.


③ 컨트롤러 우선 처리

스프링 부트는 요청을 먼저 컨트롤러에서 찾는다.

하지만 hello-static.html을 처리할 수 있는 컨트롤러가 없다면, 해당 요청을 처리할 수 없다고 판단한다.


④ 정적 리소스 처리

컨트롤러에서 해당 요청을 처리할 수 없을 때, 스프링 부트는 resources/static/ hello.static.html 파일을 찾아 반환한다.

즉, static 폴더에 있는 정적 HTML 파일을 자동으로 제공하게 된다.


⑤ 브라우저에 반환

스프링 부트는 hello-static.html 파일을 웹 브라우저에 반환하여 사용자가 HTML 내용을 볼 수 있도록 한다.



3. MVC와 템플릿 엔진📌

3.1 MVC란?

MVC는 Model, View, Controller가 분리 되어있는 방법이다.

  • 관심사 분리를 위해 View는 화면을 그리는데 집중, Model와 Controller는 비즈니스 로직과 관련되어 있도록 한다.
    • 모델(Model): 데이터와 로직 처리
    • 뷰(View): 사용자에게 보여주는 화면
    • 컨트롤러(Controller): 사용자의 입력을 처리하고 모델과 뷰를 연결


3.2 Controller

controller/HelloController

package hello.hello_project.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")
    public String hello(Model model){
        model.addAttribute("data","hello!!!");
        return "hello";
    }

    // MVC 방식
    @GetMapping("hello-mvc")
    // 윈도우 파라미터 옵션 단축키(Ctrl + p)
    public String helloMvc(@RequestParam(name = "name") String name, Model model){
        // 파라미터로 들어온 name을 넘겨줌
        model.addAttribute("name",name);
        return "hello-template";
    }
}


3.3 View

resources/templates/hello-template.html

타임리프(thymeleaf)는 뷰 템플릿 엔진으로 컨트롤러가 전달하는 데이터를 이용하여 동적으로 화면을 구성할 수 있게 해준다.

<html xmlns:th="http://www.thymeleaf.org">
  <body>
    /* $표시 : modle 키 값 name으로 치환*/
    <p th:text="'hello ' + ${name}">hello! empty</p>
  </body>
</html>


3.4 MVC 동작 방식

① 웹 브라우저 요청

사용자가 http://localhost:8080/hello-mvc?name=Spring 로 요청을 보낸다.


② 내장 톰캣 서버

요청을 받으면, 내장 톰캣 서버는 이를 스프링 부트 애플리케이션에 전달한다.


③ 컨트롤러 처리

스프링 부트는 HelloController 클래스에서 @GetMapping("hello-mvc")와 매핑된 메서드를 호출한다.

이때, name=Spring이라는 요청 파라미터를 모델(Model)로 넘겨준다. (model.addAttribute("name", name))


④ 뷰 템플릿 렌더링

컨트롤러는 “hello-template”이라는 뷰 이름을 리턴한다.

스프링은 이 이름에 맞는 템플릿 파일을 찾기 위해 resources/templates/hello-template.html을 검색한다.


⑤ 템플릿 엔진 처리

타임리프(Thymeleaf) 템플릿 엔진이 HTML 파일을 렌더링한다.

템플릿 내에서 ${name}은 모델에 담긴 "name" 키를 참조하여 "Spring"으로 치환한다.


⑥ 결과 반환

변환된 HTML 파일이 웹 브라우저로 반환되어 사용자에게 보여진다.



4. API

정적 컨텐츠를 제외하면 사실 두 가지로 볼 수 있다.

  • 서버에서 View를 찾아서 템플릿 엔진을 통해 화면을 렌더링해서 html을 웹브라우저에 내려주는 방법이 있고 (= MVC와 템플릿 엔진),
  • 데이터를 (일반적으로 JSON 형태로) 바로 내리는 방법이 있다. (= API)


@ResponseBody에 문자를 반환하는 예시

@Controller
public class HelloController {
    // API 방식
    @GetMapping("hello-string")
    @ResponseBody
    public String helloString(@RequestParam("name") String name){
        return "hello " + name;
    }
}
  • @ResponseBody는 뷰 리졸버(viewResolver) 를 사용하지 않고, HTTP 응답 본문(body)에 데이터를 직접 반환한다.
  • 이를 통해 템플릿 엔진을 사용하지 않고, 요청에 대한 응답을 동적으로 생성하여 클라이언트에게 전달할 수 있다.
  • 이 방식은 주로 RESTful API에서 JSON, XML, 텍스트 등을 반환할 때 사용된다.


http://localhost:8080/hello-string?name=String!!!로 실행

API는 문자가 그대로 출력되는 것을 확인할 수 있다.

  1. 사용자가 http://localhost:8080/hello-string?name=Spring!!! 와 같은 요청을 보내면, name=Spring!!!이라는 파라미터가 helloString 메서드로 전달된다.
  2. helloString 메서드는 @ResponseBody 어노테이션을 사용하여 반환 값을 HTTP 응답 본문에 담아 클라이언트로 전달한다.
  3. 이 때, 템플릿 엔진은 사용되지 않으며, 단순히 문자열이 그대로 응답으로 반환된다.


@ResponseBody가 객체를 반환하는 예시 -> 데이터 전달하고 싶을 때 사용

package hello.hello_project.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-string")
    @ResponseBody
    public String helloString(@RequestParam("name") String name){
        return "hello " + name;
    }

    // 객체를 반환
    @GetMapping("hello-api")
    @ResponseBody
    public Hello helloApi(@RequestParam("name") String name){
        Hello hello = new Hello();
        hello.setName(name);
        return hello;
    }
    // static class를 만들면 class 안에서 class를 생성할 수 있다.
    static class Hello{
        private String name;

        public String getName(){
            return name;
        }

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

@ResponseBody 를 사용하고, 객체를 반환하면 객체가 JSON으로 변환된다.


http://localhost:8080/hello-api?name=spring로 실행


@ResponseBody 사용 원리

  1. 스프링은 이전과 같이 hello-api라는 Controller를 찾는다.
  2. 이때 Controller에 @ResponseBody 태그가 붙어있으면 MVC 방식에서의 viewResolver가 아닌 HttpMessageConverter가 동작한다.
    • Controller에서 반환하는 값이 string이라면 StringHttpMessageConverter가 작동하여 string을 바로 처리하고,
    • 객체가 반환되면 MappingJackson2HttpMessageConverter가 작동해 객체를 JSON방식으로 변환한다.
    • JSON으로 만들어진 객체는 바로 웹 브라우저에 key-value 쌍으로 반환된다.


getter, setter란?

  • getter와 setter는 클래스의 필드(변수)에 대한 접근을 제어하기 위해 사용되는 메서드이다. -> 객체 지향 프로그래밍 캡슐화 가능
  • 단축키(windows)⭐: (Alt+Insert)에 들어가 Getter and Setter 클릭
메서드 설명
Getter 클래스의 필드 값을 반환하는 메서드
Setter 클래스의 필드 값을 설정하는 메서드


getter, setter 예제

public class Person {
    private String name;
    private int age;

    // Getter for name
    public String getName() {
        return name;
    }

    // Setter for name
    public void setName(String name) {
        this.name = name;
    }

    // Getter for age
    public int getAge() {
        return age;
    }

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


카테고리:

업데이트:

댓글남기기