MVC와 템플릿 엔진

Sunny·2022년 5월 21일
0

✨ 스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술


🔅 목차


✅스프링 웹 개발 기초

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


🔅 MVC

  1. Model : 어플리케이션의 정보, Data. 화면에 필요한 것을 담아 넘김

    • 사용자가 편집하길 원하는 모든 데이터를 가지고 있어야 함
      🙄 예를 들어, 화면 안의 네모 박스에 글자가 표현된다면, 네모 박스의 화면 위치 정보, 네모 박스의 크기 정보, 글자 내용, 글자의 위치, 글자의 포맷 정보 등을 가지고 있어야 함.

    • View나 Controller에 대해서 어떤 정보도 알지 말아야 함
      🙄 데이터 변경이 일어났을 때 모델에서 화면 UI를 직접 조정해서 수정할 수 있도록 뷰를 참조하는 내부 속성 값을 가지면 안됨

    • 변경이 일어나면, 변경 통지에 대한 처리 방법을 구현해야 함
      🙄 정보가 변경이 된다면, 이벤트를 발생시켜 누군가에게 전달해야 하며, 누군가 모델을 변경하도록 요청하는 이벤트를 보냈을 때 이를 수신할 수 있는 처리 방법을 구현해야 함. 모델은 재사용가능해야 하며, 다른 인터페이스에서도 변하지 않아야 함

  2. View : 사용자들이 볼 수 있는 화면

    • 모델이 가지고 있는 정보를 따로 저장해서는 안됨
      🙄화면에 글자를 표시하기 위해 모델이 가지고 있는 정보를 전달받게 될텐데, 그 정보를 유지하기 위해서 임의의 뷰 내부에 저장하면 안됨

    • 모델이나 컨트롤러와 같이 다른 구성요소들을 몰라야 함
      🙄모델과 같은 자기 자신을 제외한 다른 요소는 참조하거나 어떻게 동작하는지 알아서는 안됨. 뷰는 데이터를 받으면 화면에 표시해주는 역할만 가짐

    • 변경이 일어나면 변경통지에 대한 처리 방법을 구현해야 함
      🙄변경이 일어났을 때 이를 누군가에게 변경을 알려줘야하는 방법을 구현해야 함. 뷰에서는 화면에서 사용자가 화면에 표시된 내용을 변경하게 되면 이를 모델에게 전달해서 모델을 변경해야 함. 그 작업을 하기 위해 변경 통지를 구현. 그리고 재사용이 가능하게끔 설계를 해야하며, 다른 정보들을 표현할 때 쉽게 설계를 해야 함

  3. Controller : 사용자가 데이터를 클릭하고, 수정하는 것에 대한 "이벤트"들을 처리하는 부분을 뜻함

    • 모델이나 뷰에 대해 알고 있어야 함
      🙄모델이나 뷰는 서로의 존재를 모르고, 변경을 외부로 알리고, 수신하는 방법만 가지고 있는데 이를 컨트롤러가 중재하기 위해 모델과 그에 관련된 뷰에 대해 알고 있어야 함

    • 모델이나 뷰의 변경을 모니터링 해야 함
      🙄모델이나 뷰의 변경 통지를 받으면 이를 해석해서 각각의 구성 요소에게 통지를 해야 함. 또한, 애플리케이션의 메인 로직은 컨트롤러가 담당.

*** 출처: https://m.blog.naver.com/jhc9639/220967034588


🔅 MVC 실습

📌 HelloController.java

  • 경로 : /src/main/java/hello.hellospring.controller.HelloController.java
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){ 
        model.addAttribute("name", name); // 파라미터로 넘어온 name 추가
        return "hello-template";
    }

}

📌 HelloController.java 소스 설명

  1. @Controller
  • 클래스를 Spring MVC 컨트롤러로 표시하는데 사용
  • View에 표시될 데이터가 있는 Model 객체를 만들고 올바른 View를 선택하는 일을 담당

  1. @GetMapping
@GetMapping("hello-mvc")
  • @GetMapping은 HTTP GET 요청을 처리하는 메서드를 맵핑(@RequestMapping)하는 어노테이션으로, 주어진 URL 표현식과 일치하는 HTTP 요청을 처리
ex) http://localhost:8080/hello-mvc
  • 위와 같이 웹 어플리케이션에서 /hello-mvc라고 들어오면, @GetMapping("hello-mvc")를 보고 해당 메서드로 이동

  1. @RequestParam
  • 1개의 HTTP 요청 파라미터를 받기 위해서 사용

  • 형식

	@RequestParam("가져올 데이터의 이름") [데이터 타입] [가져온 데이터를 담을 변수]
  • Model 객체를 이용해서 뷰로 값을 넘김
	model.addAttribute("id", id);
  • 예시
	https://localhost:8080/hello-mvc?name=sunny

    위와 같은 url이 전달될 때 뒤에 붙는 name 파라미터를 가져올 때 사용

    @GetMapping("hello-mvc")
    public String helloMvc(@RequestParam("name") String name, Model model){ 
        model.addAttribute("name", name); // 파라미터로 넘어온 name을 모델 객체를 이용해 받음
        return "hello-template";
    }
  • Default가 true이기 때문에 반드시 해당 파라미터가 전송되어야 함

  • 해당 파라미터가 전송되지 않으면 400 error 유발

  • 에러를 방지하기 위해서 default 값을 설정해주거나, required 속성을 이용하면 됨

    ❓required
    -타입 : boolean
    -설명 : 해당 파라미터가 반드시 필수인지 여부. 기본값은 true

    • 예시 1) required = false 이용으로 에러 방지
    public String testMethod(@RequestParam(required=false) Integer num) {...}
    
    • 예시 2) default 값 설정으로 에러 방지
    public String testMethod(@RequestParam("num", required=false, defaultValue="1") Integer num) {...}

    default 값을 명시해줄때는 required=false 속성을 반드시 사용해야 함


  1. 매개변수 Model
  • Controller는 Model을 이용해 데이터를 가져오고, View에 데이터를 넘겨 적절한 View를 생성하는 역할을 함
  • 매개변수로 전달받은 Model은 model.addAttribute("key", "value"); 메소드를 이용하여 view에 전달할 데이터를 key-value 쌍으로 전달 가능

📌 hello-template.html

  • 경로 : /src/main/resources/templates/hello-template.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"><!--타임리프 엔진을 쓴다-->
<body>
<p th:text="'hello ' + ${name}">hello! empty</p>
</body>
</html>


<!--타임리프 템플릿 엔진의 장점: html을 서버없이 그대로 열어봐도 껍데기를 볼 수 있다-->
<!--엔진으로서 동작하면 p 태그 안의 내용으로 치환이 된다-->
<!--서버없이 볼때는 태그들 사이에 있는 hello! empty가 보인다-->

📌 hello-template.html 소스 설명

  1. Thymeleaf(타임리프)
  • 타임리프는 컨트롤러가 전달하는 데이터를 이용해 동적으로 화면을 만들어주는 역할을 하는 뷰 템플릿 엔진
  • 서버 상에서 동작하지 않아도 HTML 파일 내용 확인 가능
  • 서버를 가동하지 않으면 순수 HTML을, 서버를 구동하면 뷰 템플릿을 거쳐 동적으로 변경된 HTML 확인 가능
  • 속성을 나타내는 방법 : th:속성

🔅 결과

HelloController.java 와 hello-template.html를 작성하고 난 뒤 localhost:8080/hello-mvc를 하면 다음과 같이 에러페이지가 뜸

❓에러가 나는 이유는?

  • 로그 : Required request parameter 'name' for method parameter type String is not present!
  • @RequestParam 속성을 default 값(=true) 그대로 해주었기 때문에 파라미터 값을 꼭 넘겨야하는데, 넘기지 않아서 에러가 발생하였음

❗해결 방안

  • name은 spring!으로 바뀌게 됨
  • 모델에 담겨서 템플릿으로 넘어갔음
  • ${name} : 모델에서 꺼내서 치환

🔅 MVC 실습 동작 원리

  1. 웹브라우저에서 localhost:8080/hello-mvc 해서 넘긴다.

  2. 내장 톰캣 서버를 먼저 지나가는데, hello-mvc라는 것이 왔다고 스프링에게 넘긴다.

  3. helloController의 특정 메서드에 hello-mvc가 매핑이 되어있는 것을 확인하고 호출을 한다.

    • return은 hello-template.html로!
    • model 객체에 name:spring 담아 같이 넘긴다.
  4. viewResolver에게 넘긴다. (View를 찾아주고, 템플릿 엔진을 연결시켜주는 역할)

    • templates/hello-template.html (thymeleaf 템플릿 엔진 처리)
  5. 템플릿 엔진이 렌더링을 해서 변환을 한 html을 웹 브라우저에 반환한다.

profile
개발에 재미를 붙여보기 :)

0개의 댓글