참고로 내가 사용한 건 react와 Spring Boot!!
react에서 axios를 사용해서 API요청을 하고 Spring Boot에 Controller에서 API요청을 받아서 처리한다.
근데 이 axios(악시오스!!!)를 이용해서 API요청을 시작하고 Spring Boot의 Controller까지 도착하기까지 어떤 일이 일어나는지....
생각해 본 적 없는 거 같음... 그냥 요청 보내면 받는 걸 당연하다고 생각했으니... 하하.........ㅋㅋ
1. React에서 Axios사용해서 HTTP요청 발생시킴
클라이언트는 브라우저를 통해서 HTTP요청을 서버로 전송한다.
/api/request로 GET요청을 생성해서 Spring Boot서버로 전송
axios.get('/api/request')
.then(response => console.log(response.data))
.catch(error => console.error(error));
2. 브라우저가 HTTP 요청을 전송
Axios를 사용하면 내부적으로 XHR(XMLHttpRequest)를 사용해서 HTTP요청을 브라우저에서 생성한다.
객체로 생성된 HTTP요청을 Spring Boot 서버로 전송한다.
XHR(XMLHttpRequest)
XHR은 서버와 통신을 하도록 하는 객체이다.
HTTP요청을 객체로 생성한다. 이 객체를 사용해서 데이터를 서버에 전송하고 응답을 받는 역할을 한다.
* Axios는 XHR의 에러처러, JSON파싱, 헤더설정 등을 자동화하고 편리하게 처리할 수 있도록 해준다.
XHR객체는 서버와 상호작용할 때 사용한다. XHR을 사용하면 페이지의 새로고침 없이 URL에서 데이터를 가져올 수 있다. 이를 활용하면 사용자의 작업을 방해하지 않고 페이지의 일부를 업데이트할 수 있다.
- mdn web docs -
3. Spring Boot 서버가 HTTP요청을 수신(Proxy, CORS)
Spring Boot서버는 기본적으로는 8080포트에서 클라이언트의 요청을 받을 준비를 하고 있다.
React의 package.json파일에서 아래와 같이 프록시 설정을 해놓으면 어떤 일이 일어날까?
"proxy": "http://localhost:8080"
React 개발 서버에서 Spring Boot서버로 프록시 역할을 한다. -> CORS문제없이 Spring Boot로 HTTP요청을 보냄
axios.get('/api/request')
.then(response => console.log(response.data))
.catch(error => console.error(error));
proxy 설정 ❌ : localhost:3000/api/request로 요청을 보냄
proxy 설정 ⭕️ : localhost:8080/api/request로 요청을 보냄
근데 난 왜 proxy설정했는데 서버에서 CORS설정을 해줘야만 CORS오류가 안날까.....
원래는 proxy설정해주면 서버에서는 따로 설정안해줘도 되는 거 같은데.... 이거 왜 이러지....
제바 ㄹ누가 알려주세여
이건 더 자세히 알아봐야겠다..... 아니 진짜 공부의 연속임 ㄹㅇ,....
암튼 간에 이 HTTP요청이 서버로 도착하면, Spring Boot에 내장되어 있는 Tomcat서버가 요청을 받는다.
이 Tomcat이 WAS(Web Application Server)임!!
Spring Boot에 내장된 Tomcat이 브라우저로부터 온 HTTP요청을 해석하고 적절한 MVC계층으로 전달한다.
4. DispatcherServlet이 요청을 처리한다.
톰캣 서버가 요청을 받으면 DispatcherServlet으로 요청을 넘긴다.
DispatcherServlet에서 일어나는 일
- 모든 요청을 처리하는 첫 관문이다.(프론트 컨트롤러)
- 브라우저의 요청이 DispacherServlet에 도착하면 DispatcherServlet은 HadlerMapping에게 요청에 포함된 HTTP메서드(GET, POST, PUT, DELETE)와 URL경로를 전달하여 분석을 요청한다.(여기서 분석은 어떤 컨트롤러가 이 요청을 처리할 것인지)
- 그리고 HandlerMapping을 통해서 적절한 Controller를 찾는다!!
DispatcherServlet
Spring MVC패턴에서 가장 중요한 구성요소이다. 모든 HTTP요청을 가장 먼저 받아서 적절한 처리기로 전달한다.
주요 역할은
요청 라우팅 : 들어온 HTTP요청을 분석하여 해당 요청을 처리할 수 있는 Controller를 찾아서 요청을 전달한다.
Handler선택 : 요청을 처리할 Controller와 Handler를 찾는다
응답 처리 : 요청을 처리하고 나서 응답데이터도 처리해서 클라이언트에 응답한다.
프론트 컨트롤러란?
프론트 컨트롤러 패턴으로 모든 요청을 하나의 진입점에서 받아서 처리하는 소프트웨어 디자인 패턴이다.
즉, DispatcherServlet이 클라이언트로부터 온 모든 요청을 가장 먼저 처리하는 프론트 컨트롤러인 것!
5. HandlerMapping으로 컨트롤러 찾기
위에서 말한 Controller를 찾기 위해 DispatcherServlet은 HandlerMapping을 사용한다.
HandlerMapping
HandlerMapping은 Spring MVC에서 DispatcherServlet이 클라이언트의 요청을 적절한 Controller에 매핑할 수 있도록 돕는 인터페이스이다.
주요 역할은
URL경로나 요청 메서드(GET, POST)와 같은 정보를 기준으로 어떤 Controller가 이 요청을 처리할 것인지 결정한다.
HandlerMapping이 Controller를 찾는 과정이 좀 많이 복잡한 거 같아서 이건 따로 공부하고 포스팅하겠음 (+공부할 거 추가요~!)
HTTP메서드 : GET
URL경로 : /api/request
@GetMapping("/api/request")
public ResponseEntity<exDTO> ExRequest() {
// Service단에서 비즈니스 로직을 처리
return ResponseEntity.ok();
}
6. Controller로 요청을 전달한다.
~여기서부터는 우리가 아는 흐름~
알맞은 Contrller메서드를 찾았으면, 그 메서드로 요청을 전달한다!!
이때, 요청에 필요한 데이터들도 같이 전달한다
이제 요청에 맞는 로직을 수행하고, 응답을 생성한다.
7. 응답을 생성하고 클라이언트에 반환한다.
이때 응답 데이터는 다시 DispatcherServlet을 거쳐서, 톰캣 서버가 HTTP응답으로 변환해서 클라이언트로 보낸다.
이 과정을 좀 자세히 다뤄보겠음.
1) Controller에서 데이터를 반환한다. (MVC패턴에서는 View를 반환하지만 난 react를 View처럼 사용 중)
2) DispatcherServlet이 이 데이터를 받아서 HTTP응답 형식에 맞게 변환
Controller가 반환한 JSON데이터를 DispatcherServlet이 데이터를 받아서 HttpServletResponse객체에 담는다.
DispatcherServlet이 하는 일은
HandlerAdapter가 Controller로부터 데이터를 받는다. (보통 데이터는 Java객체 형태이다)
MessageConverter가 데이터를 JSON형식으로 변환한다.
변환된 JSON데이터는 HttpServletResponse 객체에 저장된다.
3) 톰캣 서버로 전달
DispatcherServletdms JSON데이터가 담긴 HttpServletResponse를 톰캣에 전달한다.
담긴 정보는 아래와 같음(오른쪽은 예시)
상태 코드 : 200, 403, 404 등등
헤더 정보 : Content-Type: application/json
응답 본문 : 실제 JSON 데이터
톰캣은 HttpServletResponse에 담긴 데이터를 받아서 HTTP 응답 형식으로 반환한다.
-> 완전한 HTTP 응답 메시지를 생성한다
4) 톰캣 서버가 HTTP 응답으로 변환
톰캣은 DispatcherServlet이 넘긴 HttpServletResponse를 기반으로 HTTP 응답 메시지를 만든다
HTTP 응답 메시지 구조
Status Line | 응답 상태 코드 & HTTP 버전 | HTTP/1.1 200 OK |
Headers | 응답 메타 정보 | Content-Type: application/json |
Body | 응답 데이터(JSON형태의 본문) | {"message": "Hello World!"} |
이 메시지가 클라이언트로 전송 -> HTTP응답메시지 자체는 JSON데이터가 아님! Body에 담긴 데이터가 JSON데이터임
8. React에서 응답을 수신한다!
톰캣으로부터 받은 HTTP 응답 메시지로 적절한 처리를 한다~
깨알 상식(상식 아닌가?)
HTTP응답 메시지 자체는 JSON형태가 아니라서 react에서 Body부분을 추출해서 JSON형식으로 파싱 해야 한다.
Axios는 이 파싱을 자동으로 처리해 줌!
Fetch는 HTTP 응답 메시지를 그대로 반환해서 (HTTP 응답 메시지에 담겨있는) body부분을 추출하기 위해서 response.json()을 사용해 수동으로 JSON파싱을 해줘야 함!
앞으로 할 일
+ proxy설정 공부
+ HandlerMapping & HandlerAdapter 흐름 공부하기
+ Spring Security 공부(새로 만들기)
바쁘다바빠현대사회.........
'[ STUDY ] > 끄적끄적..' 카테고리의 다른 글
[ 알아보자 ] HandlerMapping & HandlerAdapter 흐름 (1) | 2024.10.21 |
---|---|
[ 알아보자 ] Proxy란? (3) | 2024.10.18 |
[ 알아보자 ] Spring Security 다시 알아보자.... (0) | 2024.10.16 |
[ 알아보자 ] WEB과 WAS (0) | 2024.10.16 |
[ 알아보자 ] HTTP...그리고 JWT... (0) | 2024.10.15 |