Closed yeollow closed 3 years ago
HttpEntity<T>
: HTTP Request / Response에 해당하는 header와 body를 포함하는 class
RequestEntity<T>
: 사용자의 HttpRequest에 대한 data를 포함하는 class.
ResponseEntity<T>
: 사용자의 HttpRequest에 대한 response data를 포함하는 class
RestTemplate이란? : org.springframework.http.client
package에 존재하는 HTTP 를 사용하여 통신하는 라이브러리인 HttpClient
를 HttpEntity
의 json이나 xml등으로 추상화하여 제공해주어 json이나 xml 라이브러리를 사용하여 직접 변환하지 않아도 자동으로 변환해주도록 하고 REST 서비스를 호출하도록 설계되어 HTTP method의 기능에 맞게 여러 method를 제공하며 REST API호출 이후 응답을 받을때 까지 기다리는 동기 방식으로 동작한다. RestTemplate API
RestTemplate 동작 원리
RestTemplate
을 생성하고 URI, HTTP method등의 header를 담아 요청한다.RestTemplate
은 HttpMessageConverter
를 이용하여 RequestEntity
를 요청 메시지로 변환한다.RestTemplate
은 ClientHttpRequestFactory
로 부터 ClientHttpRequest
를 가져와 요청을 보낸다.ClientHttpRequest
는 요청 메시지를 만들어 HTTP 를 통해 서버와 통신한다.RestTemplate
는 ResponseErrorHandler 로 오류를 확인하고 있다면 처리로직을 태운다.ClientHttpResponse
에서 응답데이터를 가져와서 처리한다.RestTemplate
는 HttpMessageConverter
를 이용해서 응답메세지를 java object(Class responseType) 로 변환한다.@RequestParam
HttpServletRequest
객체와 같은 역할을 함@RequestParam
은 필수 여부가 true이기 때문에 반드시 해당 parameter가 전송되어야 한다. 전송되지 않으면 400 Error
를 유발.
@PathVariable
@ModelAttribute
MessageConverter
를 통해 변환시키는 @RequestBody
와는 달리 HTTP ContentType중 하나인 multipart/form-data 형태의 HTTP Body 내용을 setter를 통해 1:1로 객체에 바인딩 하기 위해 사용한다.@RequestBody
@RequestBody
가 붙어있으면 HTTP request의 Media Type과 Parameter Type을 확인한 후 MessageConverter
중 해당 Media Type과 Parameter Type을 처리해줄 수 있는 Converter가 있다면 HTTP request Body를 통째로 변환하여 지정된 method parameter로 전달해준다.HttpMessageConverter
type의 MessageConverter들
StringHttpMessageConverter
: 모든 종류의 Media Type을 String으로 변환MarshallingHttpMessageConverter
: Media Type이 XML일때 Object로 변환MappingJacksonHttpMessageConverter
: Media Type이 Json일때 Model Object로 변환@ResponseBody
@RequestBody
와 반대로 HttpMessageConverter
를 통해 java Object를 response Body로 변환한다.@Controller
를 사용할 경우 @ResponseBody
를 선언해야 MessageConverter
가 적용된다. 선언하지 않으면, @Controller
는 ViewResolver에 의해 해당하는 view를 찾으려고 시도한다.
@ResponseBody
를 통해 MessageConverter
로 변환하여 데이터를 반환하는 경우에는 @Controller
와 @ResponseBody
가 합쳐진 @RestController
를 사용할 수도 있다.Servlet
이란? : client의 요청에 대해 동적으로 결과를 응답해주는 자바 [CGI](https://ko.wikipedia.org/wiki/%EA%B3%B5%EC%9A%A9%EA%B2%8C%EC%9D%B4%ED%8A%B8%EC%9B%A8%EC%9D%B4%EC%9D%B8%ED%84%B0%ED%8E%98%EC%9D%B4%EC%8A%A4) 프로그램. html을 사용하여 요청에 응답하며 java thread를 이용하여 동작한다. 흔히 MVC 패턴에서 controller로 이용되며 HttpServlet
class를 상속받는다. 포스팅 참조HttpServlet
: client 요청에 따라 servlet container는 service()
method를 호출하고 service()
method는 요청이 GET 인지 POST 인지 구분하여 각 doGet()
과 doPost()
를 호출한다.
Servlet
interface를 implements하고 있는 GenericServlet
class를 extends하며 GenericServlet
을 extends하여 Servlet객체를 생성할 경우, service()
method를 @Override하여 정의해야 하지만, HttpServlet
을 extends하여 Servlet객체를 생성하는 경우 _client의 GET_, POST 요쳥 등에 따른 doGet()
, doPost()
등을 실ㅇ하기에 _client_의 요청에 맞는 doXXX()
method를 @Override하면 된다.doGet()
method와 doPost()
method는 모두 HttpServletRequest
와 HttpServletResponse
객체를 매개변수로 가지고 있다. 해당 객체들은 servlet과 client사이의 request와 response를 책임지는 객체들이다.해당 PR의 geoHash구현 내용은 MySQL DB에 저장되어있는 모든 Topic에 대한 GPS 위치를 뽑아 위치 별로 encoding된 geoHash값을 통해 prefix가 같은 GPS 위치의 경우는 List로 연결하여 HashMap<String,Collection<GPS>>
구조를 가지고 있다.
해당 구현 방법은 geoHash값을 요청하는 req가 있을때마다 모든 GPS정보에대한 geoHash값의 계산 이후 HashMap에 저장하는 꼴이니 절대 효율적이지 못하다.
따라서 Redis에서 GeoHash관련된 GPS정보 색인을 제공한다고 하니 아래의 Spring Redis연동을 통해 해결해보자.
Redis geohash
HTTP 는 기본적으로 80, HTTPS 는 기본적으로 443 포트를 통해 통신하므로 Tomcat 의 기본 포트인 8080포트로 접속하기 위해 Nginx 웹서버를 통해 Reverse Proxy 하도록 한다.
apt-get install nginx
을 통해 nginx 설치/etc/nginx/nginx
경로에 있는 nginx.conf
에 아래와 같은 내용을 작성한다.service nginx start
를 통해 nginx 구동listen하는 port로 접속하면 proxy_pass
를 통해 redirect 됨을 확인할 수 있음.
server {
listen {port};
listen [::]:{port};
server_name {hostname or ip};
location / {
proxy_pass http://{hostname or ip}:{port};
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
}
}
listen
을 통해 지정한 포트로의 요청을 받음server_name
: 요청하는 host의 이름location
: 특정 url을 처리하는 방법을 정의./
로 설정 해놓았기 때문에 모든 request에 대해 적용proxy_pass
: request에 대해 어디로 redirect할 것인지를 설정.proxy_set_header
: request한 실ㅔ 데이터를 HTTP header 항목에 할당Forward Proxy : client와 server의 request / response 처리를 중간에 proxy server가 매개하여 중계해 주는 것.
Reverse Proxy : 일반적인 인터넷 서비스에서 널리 사용하고 있으며 user의 요청을 받아 reverse network에 있는 server에 단순히 요청을 전달하기만 할 뿐, 요청의 처리는 WS들이 맡아서 한다. -WebServer 와 WebApplicationServer 를 연동하기 위해서는 Reverse Proxy에 대한 이해가 필수이다.
톺아보기
- 위 내용들은 WS인 Nginx 를 이용하여 Reverse Proxy과정을 거쳐 port forwarding을 > 하는 내용에 기반한다.
- ssl 인증서를 발급받고 443 포트로 https를 적용하는것이나 loadbalancing 내용도 추후 공부해보면 좋을 것 같다.
local api module
구조는 기존 PR인 #26 내용과 동일하지만 comment내용의 비즈니스 로직(GeoHash) 추가 및 GET 과 POST 방식의 통신을 가능하게 함.
GET :
/api/v1/{topic}/reqParam?longitude=...latitude=...
와 같이 queryString을 포함한 url로 request 시 @RequestParam을 통해 longitude, latitude값을 읽어 해당 위치와 인접한 GPS위치를 GeoHash 를 통해 반환POST :
/api/v1/{topic}
url로 request시 @RequestBody를 통해application/json
content Type으로 전송되는 GPS json data를 MessageConverter에 의해 변환하여 Controller에서 매개변수로 받은 후 해당 위치와 인접한 GPS위치를 GeoHash 를 통해 반환