스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술 - 섹션6. 스프링 MVC - 기본 기능
CS/김영한 스프링 강의

스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술 - 섹션6. 스프링 MVC - 기본 기능

 

 

전까지 배웠던 @Controller와 @RestController의 차이는 @Controller는 저 return이 "ok"인 string을 반환하면 저 이름의 뷰 파일을 찾으려고 하는데 @RestController이라면 저 string을 그냥 반환한다. 이 점이 나중에 @ResponseBody와 함께 중요한 역할을 한다고 함.

 

그냥 url 받는 종류가 뭐 있고 뭐 있고.. 하는 것들이다. 그냥 쭉 보면 이해할 수 있다.

가장 자주 쓰이는 @PathVariable. 이름 같으면 생략 가능

 

query로 mode가 debug가 아니면 안받아들임

 

위 query의 header 버전

 

요청이 application/json이 아니면 안 받아들임

 

요청하는 클라이언트가 text/html을 못 받아들이면 안 받아들임(클라이언트 헤더에서 accept 하고 뭘 받을 수 있는지 적는거)

 

 

실제 쓰는 방법

 

 

요청 파라미터는 스프링이 가능한 진짜 왠만한건 다 받을 수 있다.

https://docs.spring.io/spring-framework/docs/current/reference/html/web.html#mvc-ann-arguments

 

Redirecting...

 

docs.spring.io

https://docs.spring.io/spring-framework/docs/current/reference/html/web.html#mvc-ann-return-types

 

Redirecting...

 

docs.spring.io

 

@RequestMapping의 여러가지 사용법.

@ResponseBody를 붙이면 해당 함수에는 view를 찾는게 아닌 그냥 그걸 반환해주는 @RestController 효과가 난다.

 

조건문.

주의할 건 그냥 int는 null이 허용이 안되서 int + null = Integer를 사용해야 한다는 것과, username= 으로 아무것도 입력 안하면 빈 문자 ''가 들어간다는 점, 빈 문자 ''가 들어가도 defaultValue로 채운다는 점이다.

 

@ModelAttribute를 쓰면 해당 값아 알맞게 set을 넣어준다. @Data는 lombok의 것으로, 저걸 넣어주면 get, set, toString 등을 알아서 해준다.

만약 타입이 맞지 않으면 bindException이 뜸. @ModelAttribute가 생략되었을 시 스프링이 자동으로 찾는 순서는 단순 타입 int, string 뒤에 argument resolver로 지정해둔 타입 외에 모델을 찾는다. 저건 나중에 배움.

 

 

위 내용은 HTTP 요청 파라미터를 읽은거고, 밑에는 http에서 단순 텍스트만 읽는거. JSON, XML 같이.

 

 

주의할건 http 요청 읽는것에서 쓰였던 @RequestParam과 @ModelAttribute와는 아무 관계가 없다. @RequestParam과 @ModelAttribute는 query로 전해주던거 분석한거고 RequestEntity와 @RequestBody는 http body를 분석하는거.

@ResponseBody를 사용하면 뷰를 사용하는게 아닌 저 단순 텍스트든 뭐든 반환함.

 

 

 

다음은 json 받기

조심할 점은 query에서 @ModelAttribute를 생략했던 것과는 다르게 여기선 생략하면 안됨. 작동은 되지만 annotation 생략 시 String, int, Integer같은 단순타입 뒤에 @ModelAttribute로 자동으로 잡는데 post로 보낼거면 query에는 아무것도 없을 거기 때문에 모델의 각각의 값에 기본 값으로 된다.

또 주의점은 이렇게 json으로 받는다고 가정하기 때문에, 클라이언트에서 헤더에 Content-type: application/json인지 확인해야 함. 그래야 JSON을 처리할 수 있는 HTTP 메시지 컨버터가 실행된다.

@ResponseBody로 객체를 응답할 때도 클라이언트에서 Accept-type에 application/json이 있어야 함. 그래야 응답도 객체 -> HTTP 메시지 컨버터 -> JSON 응답으로 변환됨.

 

 

다음은 뷰 응답.

정적 리소스의 경우 다음 디렉토리에 있는 정적 리소스를 제공한다.

/static, /public, /resources, /META-INF/resources

url에서 저 경로 하위에 있는 파일을 입력하면 된다.

다음은 뷰 탬플릿

 

thymeleaf는 처음 프로젝트 만들 때 추가한거.

thymeleaf의 기본 설정은 templates 밑 파일들의 .html로 끝나는 파일들 설정임.

 

다음은 직접 HTTP 응답 메시지 전달

ResponseEntity 안쓰고 그냥 json으로 전달할 경우, 응답 상태 메시지를 지정할 수 없기 때문에 @ResponseStatus로 지정해줘야 함. 만약 여러개를 하고 싶으면 ResponseEntity를 사용하는 방식으로 바꾸면 된다.

@RestController는 매번 함수에 그 자체를 반환하는 @ResponseBody를 일일히 붙이지 말라고 편의성을 위한 것이다.

 

 

주고받는건 분명난 HTTP를 넣어주지 않고 단순 @ResponseBody나 @RequestBody로 그냥 모냈을 뿐이다.

중간에서 이것드을 변환해주는 HttpMessageConverter가 있기 때문이다.

 

컨버터는 어디에 있는가. 사실 컨버터가 그렇게 중요한가는 미끼였고 분명 HTTP의 응답과 반환이었음에도 불구하고 우리가 막 Controller에서 argument를 멋대로 정의하고 멋대로 반환해도 알아서 잘 된 것은 Argument Resolver와 ReturnValue Handler가 있었기 때문이다.

핸들러 어댑터에서 컨트롤러에 전해주기 전에 처리할 수 있는지 모든 AgrumentResolver에게 물어본다. 있다면 걔를 통해서 Object로 만들어 처리해서 전해준다. 30개 정도 있다고 한다.

https://docs.spring.io/spring-framework/docs/current/reference/html/web.html#mvc-ann-arguments

 

Redirecting...

 

docs.spring.io

 

ReturnValueHandler도 비슷하게 동작한다. 얘는 10가지 정도 (ModelAndView, @ResponseBody, HttpEntity, String, ... 등)을 지원한다.

https://docs.spring.io/spring-framework/docs/current/reference/html/web.html#mvc-ann-return-types

 

Redirecting...

 

docs.spring.io

 

 

HTTP 컨버터는 이 Resolver와 Handler가 자신의 역할을 수행하기 위해 사용하는 도구 쯤으로 생각하면 된다.

Argument Resolver와 ReturnValue Handler도 인터페이스로 확장하기 쉽게 만들어져 있기 때문에, 이미 충분히 구현되어 있지만 직접 커스텀을 만들어서 확장시킬 수도 있다. 나중에 실습으로 해본다고 함.