개발자로 후회없는 삶 살기
[문법] Spring 핸들러 어댑터, API 설계 실전 본문
서론
※ 과거에 기록한 내용에서 중요한 부분만 발췌하여 모두가 이해하기 쉽게 다시 서술한다.
본론
- 스프링 MVC 전체 구조
Dispatcher Servlet : 프론트 컨트롤러
Handler Mapping : 핸들러를 보관하는 맵
- 디스패쳐 서블릿 구조 살펴보기
스프링도 프론트 컨트롤러 패턴을 사용한다.
HttpServlet을 상속 받고, urlPattens를 "/'로 모든 요청을 받는다.
-> 요청 흐름
디스패쳐 핸들러의 doDispatch 메서드에서 핸들러 매핑을 찾고
핸들러 매핑을 인자로 핸들러 어댑터를 찾는다.
get 메서드 내부를 보면 for문으로 support 메서드로 해당 핸들러를 처리할 수있는 어댑터를 찾는다.
어댑터는 support 메서드를 가지고 handle로 컨트롤러를 호출한다.
-> 스프링 MVC 구조
1) 핸들러 매핑 조회
2) 핸들러 어댑터 조회
3) 핸들러 어댑터 실행
4) 뷰 리졸버 호출
5) 뷰 반환 및 랜더링
핵심 동작 방식을 알아두어야 향후 문제 발생 시 오류를 잡을 수 있다.
- 핸들러 매핑과 어댑터
스프링에서 제공하는 핸들러 매핑과 어댑터를 살펴보자, 어노테이션 기반 어댑터도 있다.
-> 핸들러 매핑
0순위는 어노테이션 기반 핸들러 매핑으로 디스패쳐가 0순위로 이 방식을 선택한다. RequestMapping이 있으면 0순위를 사용하고 없으면 스프링 빈이름으로 핸들러 매핑을 구한다.
-> 핸들러 어댑터
이제 찾은 핸들러 매핑에 맞는 어댑터를 찾는다. support 메서드로 지원되는 어댑터를 찾는다.
RequestMappingHandlerAdapter 내부를 보면 컨트롤러 호출에 필요한 요소들이 존재한다.
스프링 부트가 자동으로 여러 뷰 리졸버를 등록해주고 0순위는 빈 이름, 1순위가 인터널 뷰 리졸버이다. 타임리프를 쓸 때는 타임리프 뷰 리졸버가 있다.
핸들러 매핑 내부 토드에 isHandler 메서드에 컨트롤러 어노테이션이 있으면 해당 어댑터를 꺼내올 수 있다. 핸들러가 어노테이션 방식의 컨트롤러에 있는 모든 메서드를 호출할 수 있다.
- 로깅
slf4j : 로그 인터페이스
logback : 구현체
로그.info를 출력하면,
시간, INFO, 프로세스 번호(15380), 쓰레드 번호, 로그가 남는다. 로그 하나에 이렇게 다양한 정보를 포함해서 실무에서 반드시 사용한다. 표준 출력과는 차이를 보인다.
1) info : 이 로그는 중요한 정보라는 것
2) debug : 개발 서버에 남은 로그라는 것
3) warn : 위험한 것
4) error : 에러
표준 출력은 콘솔에 남는데, 파일로 별도로 저장할 수 있다. 분할 파일 저장, 압추도 가능하고 로그를 찍을 때 내부 버퍼링, 멀티 쓰레드 등 성능을 최적화했다.
- 요청 매핑
요청이 왔을 때 어떤 컨트롤러 메서드가 호출되어야 하는지 배운다.
-> 미디어 타입
consume은 서버가 받아들일 수 있는 content type을 명시한다. 동일 url에 json일 때만 위 메서드가 호출되고 html이면 호출 안 되도록 구분한다.
postman으로 json을 넣으면 헤더에 자동으로 content type이 app/json으로 바뀌어 있다. 텍스트를 제공하면 400 오류가 난다.
produce는 Accept 헤더와 함께 쓰이며, 서버가 어떤 타입으로 클라이언트에게 제공할 지를 의미한다.
클라이언트는 json을 원하는데 서버가 제공하는 것이 text/html이라서 에러가 뜬다.
- 요청 매핑 API 예시
실전에서 API 설계를 어떻게 하나 보자.
API 명세는 위와 같다.
동일한 매핑 URI에 http 메서드로 리소스와 행동을 구분했다.
- 요청 데이터 조회
스프링은 서블릿이 req, resp 만 받을 수 있는 것에 비해 다양한 매개를 직접 받을 수 있다. http 메서드, locale 언어 정보, 한 번에 모든 헤더를 받는 Multi, 하나만 받아서 나온 호스트, 쿠키도 받을 수 있다.
- HTTP 데이터 조회
1) Get 쿼리 파라미터
2) Post 방식의 HTML FORM(content type x-www)
3) HTTP 메세지 바디 API 방식
- @RequestParam
required = true가 기본값이다. false로 하고 값을 안 넣으면 null이 들어가서 레퍼런스 타입으로 받아야 한다.
name은 req True인데 = 하고 값을 안 넣으면 통과가 된다. req는 null만 막는다. 근데 “ “ 빈 문자가 와서 통과가 된다.
빈 문자도 통과 못하게 막아야 한다. 기본 값을 넣으면 빈 문자일 경우 기본 값을 넣는다.
'[백엔드] > [spring | 학습기록]' 카테고리의 다른 글
[문법] 검증 (0) | 2024.08.04 |
---|---|
[문법] 요청과 응답, HttpMessageConverter (0) | 2024.08.03 |
[문법] 웹 서버와 서블릿 (0) | 2024.08.01 |
[문법] 빈 생명주기 콜백 (0) | 2024.08.01 |
[문법] 의존관계 자동 주입 (0) | 2024.07.31 |