이 친구 에 추가??로 한 느낌?
MVC1, MVC2 차이점도 있다. 되게 간단하게.
Spring 프레임워크에서 제공하는 웹 모듈이다.
소프트웨어의 비즈니스 로직과 화면을 구분을 하고,
Model
, View
, Controller
로 분리하여 개발하는 디자인 패턴이다.
데이터와 비즈니스 로직을 관리한다.
애플리케이션이 포함해야할 데이터가 무엇인지를 정의한다.
사용자 인터페이스(화면) 처리
애플리케이션의 데이터를 보여주는 방식을 정의한다.
Thymeleaf, jsp 등 여러 Template Engine이 있다.
Model과 View 사이의 상호작용, 인터페이스 역할을 한다.
애플리케이션 사용자의 입력에 대한 응답으로 Model 및 View를 업데이트하는 로직을 포함한다.
Model/View에 대한 사용자 입력 및 요청을 수신하여 그에 따라 적절한 결과를 Model에 담아 View에 전달한다.
Controller —> Service —> Dao —> DB
Client(브라우저 요청) → DispatcherServlet(접수)
요청을 처리할 handler를 handlerMapping 한테 물어본다.
DispatcherServlet → Controller
HandlerAdapter 한테 요청하면 HandlerAdapter가 Handler를 호출하면서 request처리 요청.
Controller → DispathcerServlet
a. Controller 가 Client 으로 받은 API 요청을 처리
b. 'Model' 정보와 'View' 정보를 DispatcherServlet 으로 전달
DispatcherServlet → Client
a. ViewResolver 통해 View 에 Model 을 적용
b. View 를 Client 에게 응답으로 전달
@RequestMapping("/hello/response")
public class HelloResponseController {
@GetMapping("/html/redirect")
public String htmlFile() {
return "redirect:/hello.html";
}
.
.
.
이런식으로 GelloResponseController 안에 메서드가 여러 개 있다고 가정하자.
공통적인 url 부분을 클래스 단위로 @RequestMapping
해준 후 각 메서드 마다 Mapping을 한 번 더 해주면 url은 클래스 - 메서드 순으로 읽혀지게 된다.
ex) ... /hello/response/html/redirect 를 입력하면 hello.html이 보여진다.
@GetMapping("/html/templates")hello.html을 찾는다
public String htmlTemplates() {
return "hello";
}
/templates
-> templates 안에 있는 .html 파일을 찾는다.
@GetMapping("/body/html")
@ResponseBody
public String helloStringHTML() {
return "<!DOCTYPE html>" +
"<html>" +
"<head><meta charset=\"UTF-8\"><title>By @ResponseBody</title></head>" +
"<body> Hello, 정적 웹 페이지!!</body>" +
"</html>";
}
@ResponseBody
이 친구가 있으면 view를 통해 내려주는 것이 아닌(템플릿 엔진을 통해) 바로 body에 때려박는다.
@GetMapping("/json/class")
@ResponseBody
public Star helloJson() {
return new Star("BTS", 28);
}
json
으로 값을 넘겨준다. content-Type 이 application/json인지 확인.
@GetMapping("/star/{name}/age/{age}")
@ResponseBody
public String helloRequestPath(@PathVariable String name, @PathVariable int age)
@PathVariable
- url 에 담겨져서 온 정보들을 각각 name, age에 저장
@GetMapping("/form/param")
@ResponseBody
public String helloGetRequestParam(@RequestParam String name, @RequestParam int age) {
return String.format("Hello, @RequestParam.<br> name = %s, age = %d", name, age);
}
form 요청을 하더라도 url 뒤에 붙어서 온다.
!! - GET은 url 요청 안에 바인딩 하는 값이 들어가면, POST 는 BODY에 들어간다.
자 여기서 내가 궁금했던
@RequestParam
- 필수 여부가 true이기 때문에 기본적으로 반드시 해당 파라미터가 전송되어야 한다.
해당 파라미터가 전송되지 않으면 400 Error를 유발하게 된다.
그렇기 때문에 반드시 필요한 변수가 아니라면 required의 값을 false로 설정해둘 수 있으며 해당 Parameter를 사용하지 않고 요청을 보낼 경우에 default로 받을 값을 defaultValue 옵션을 통해 설정할 수도 있다.
@Requestbody
- json 형태의 HTTP Body 내용을 Java객체로 변환.
@RequestBody에는 값을 주입하기 위한 생성자나 Setter가 필요없다.
Json 데이터를 변환하기 위해서는 Jackson 라이브러리가 사용되는데, Jackson 라이브러리 내부적으로는 Getter나 Setter등을 통해 필드에 있는 변수들의 이름을 찾고, Reflection을 이용해 값을 할당한다.
@ModelAttribute
- model에 있는 attribute에 접근, 데이터 바인딩 + 유효성 검사.
ModelAttribute는 바인딩하는 값을 주입해주는 생성자나 Setter가 없다면 매핑이 되지 않는다.
파라미터 이름을 명시하지 않으면 필드명과 일치하는 필드의 Setter를 이용해서 데이터 바인딩을 한다.
Reflection은 생성자가 필요한거 아닌가요?