Spring 입문 Chapter 2-2. 스프링 웹 개발 기초 : MVC와 템플릿 엔진
이 글은 인프런에 있는 김영한님의 "스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술" 강의를 듣고 정리한 필기입니다.
⛅️ MVC란 무엇인가?
- MVC는 Model, View, Controller의 약자이다.
- 과거에는 Controller와 view가 따로 분리되어 있지 않았다.
Class에 역할을 하나씩 부여하는 것처럼 MVC도 역할을 나누는 것이다. - View는 화면을 렌더링하는 코드들이 들어가있다.
Controller에는 비지니스 모델, 서버 뒷단에 관련된 일들, 내부적인 것들을 처리한다.
Model은 화면(view)에서 필요한 자료들을 담아서 화면(view)쪽에 넘겨주는 패턴을 많이 사용한다. - 이것이 MVC 패턴이다.
⛅️ @RequestParam을 이용한 Controller 발전시키기
이전에는 매개변수를 Model 객체만을 전달했지만, 이번에는 @RequestParam을 이용하여 변수를 받아보자.
public String helloMvc(@RequestParam("name") String nameVal, Model model){
model.addAttribute("name", nameVal);
return "hello-template";
}
위 코드는 외부(url)에서 parameter를 받아오는 코드이다.
먼저 @RequestParam을 사용함으로 인해서 url에서 String nameVal의 값을 받아올 수 있게 됐다.
이후 Model 객체에 addAttribute 함수를 통해 값을 저장한다. model 객체는 view에서 렌더링할 때 담은 값을 사용한다.
hello-template를 반환하므로, resources/templates/hello-template.html을 찾아갈 것이다.
hello-template.html을 다음과 같이 적어주자.
(프론트엔드쪽은 수업 자료에 있는 내용을 복붙합시다!)
<html xmlns:th="http://www.thymeleaf.org">
<body>
<p th:text="'hello ' + ${name}">hello! empty</p>
</body>
</html>
첫째 줄을 통해 Thymeleaf를 사용한다는 것을 알 수 있다. 이 템플릿 엔진은 html을 한 차례 가공해서 웹 브라우저에 전달할 것이다.
세번째 줄을 보면 ${name} 이라는 부분을 볼 수 있는데, $는 model에서 값을 꺼내겠다는 뜻이고, {name}은 key값 name의 value 값을 꺼내서 치환하겠다는 뜻이다.
hello! empty는 만일 서버 없이 이 html 파일을 열었을 때 출력될 디폴트 값을 표시해놓은 것이다.
이제 localhost:8080/hello-mvc에 접속해보자.
화면이 나올 것이라는 예상과는 달리 WhiteLable Error가 뜨는 것을 볼 수 있다.
IntelliJ의 error message를 살펴보자.
WARN 20496 --- [nio-8080-exec-3] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.bind.MissingServletRequestParameterException:
Required request parameter 'nameVal' for method parameter type String is not present]
에러 메세지를 보면 필요한 parameter인 nameVal이 없다는 메세지를 발견할 수 있다.
nameVal이 없을 때에도 에러가 나지 않게 하는 방법이 있는데, @RequestParam의 매개변수를 하나 더 전달하는 것이다.
@GetMapping("hello-mvc")
public String helloMvc(@RequestParam(value = "name", required = false) String nameVal, Model model){
model.addAttribute("name", nameVal);
return "hello-template";
}
위 코드를 보면 "required = false"가 추가된 것을 볼 수 있다.
이 매개변수는 default값으로 true로 설정되어 있으며, key 값을 무조건 받아야 한다. 그렇지 않으면 BadRequest 에러가 발생한다.
위 코드로 변경 후 localhost:8080/hello-mvc 로 접속해도 BadRequest가 뜨지 않음을 확인할 수 있다.
그렇다면 url로 값을 어떻게 전달할까?
localhost:8080/hello-mvc?name=spring 으로 접속하면 "hello spring"이 뜨는 것을 볼 수 있다.
⛅️ @RequestParam 정리
@RequestParam 어노테이션은 HttpServletRequest 객체와 같은 역할을 한다.
HttpServletRequest에서는 getParameter()를 이용한다.
[사용 방법]
1. 단일 파라미터
@RequestParam ("가져올 데이터의 이름") [자료형] [가져온 데이터를 담을 변수명]
public String checkId(@RequestParam("id") String id, Model model){
...
}
이처럼 사용할 수 있지만, @RequestParam에 지정한 키가 존재하지 않는다면, BadRequest로 에러가 발생한다.
2. 에러를 방지하기 위한 방법
@RequestParam를 까보면(?) 총 세 가지 매개변수를 받을 수 있다.
1) String value - 가져올 데이터의 이름을 String으로 넘긴다.
2) boolean required - 기본값은 true로 걸정되어 있으며, required=false로 설정하면 해당 키 값이 존재하지 않아도 BadRequest가 발생하지 않는다.
3) String defaultValue - 값이 존재하지 않을 때, 이 값으로 설정한 값이 변수에 들어가게 된다.
@GetMapping("hello-mvc")
public String helloMvc(@RequestParam(value = "name", required = false, defaultValue = "sung")
String nameValue, Model model){
model.addAttribute("name", nameValue);
return "hello-template";
}
이후 localhost:8080/hello-mvc?name=spring 으로 들어가면 hello spring이라고 써져있는 것을 볼 수 있다.
⛅️ MVC, Template engine 작동 방식
- 웹 브라우저에서 localhost:8080/hello-mvc 를 요청한다.
- spring boot를 띄울 때 같이 띄우는 내장 tomcat 서버를 먼저 거친다. tomcat 서버는 hello-mvc 요청이 왔음을 spring에게 넘긴다.
- spring은 helloController에 hello-mvc가 @GetMapping을 통해 hello-mvc가 mapping 되어 있는 것을 확인하고, mapping 되어있는 해당 메서드를 실행한다.
해당 메서드는 "hello-template"라는 String을 반환하고, model에는 (key : name, value : spring)이라는 값을 넣는다. 그리고 이 값들을 spring에게 넘겨준다. - spring의 viewResolver가 동작한다. viewResolver는 view를 찾아주고, 템플릿 엔진을 연결시켜주는 역할을 한다.
viewResolver가 templates/hello-template.html 을 찾아서 Thymeleaf 템플릿 엔진에게 처리 요청을 한다. - 템플릿 엔진인 Thymeleaf가 렌더링해서 html로 변환한 후, 웹 브라우저에 반환한다.
정적 컨텐츠를 사용할 때에는 템플릿 엔진을 거치지 않고 바로 웹 브라우저에 넘겼지만, 이번에는 템플릿 엔진을 통해 한 차례 변환을 진행했다.
참고 링크
@RequestParam에 대한 이해 https://heavenly-appear.tistory.com/302
@RequestParam을 이용한 값 받아오기 https://hongku.tistory.com/119