Google 로그인 오픈 API(3)[Spring boot/toyProject]

ᄋᄌᄒ·2023년 5월 1일
0

toyProject(Spring boot)

목록 보기
3/3
post-thumbnail

✉️ 글 쓰기 앞서

이번 글이 google 로그인 오픈api 관련 마지막 글이다. 주로 restTemplate에 관한 내용을 쓸 예정이다. http 통신에 관해서는 아직 감이 오지 않아서 글 작성하면서 배워보자.


HTTP 통신기술 (java)

구글 로그인 오픈 api 기술을 사용하려면 구글로부터 정보를 주고받아야한다. 우리가 웹 페이지를 만들 때는 우리가 만든 html을 클라이언트로부터 주고받아야하지만 이번에는 그 대상이 다르고, 내용물이 다르다.

그렇기 때문에 해당 플랫폼에 연결하는 통신 기술이 필요하다. 아래에 설명할 기술들은 java에서 지원하는 통신 기술이다.

📌 HttpURLConnection

jdk 1.2 부터 내장되어 있었으며, java.net 패키지에 있다. URL의 내용을 읽어오거나, URL 주소에 GET, POST로 데이터를 전달 할 때 사용한다. 또한 HTTP 프로토콜 이외에도 가능하다.(File 등)

예시) 네이버 도서 오픈 api

http connection
다음에 포스팅할 내용이기도 하다만 토이프로젝트에서 직접 사용한 http urlconnection방법이다. 위 코드는 네이버 도서 api로부터 정보를 얻기 위해 http를 네이버 오픈 api에 연결한 것이다.(컨트롤러의 일부 코드이다.)위와 같이 연걸하여 원하는 내용을 JsonObject를 통해 가져오는 방식을 사용했다.
위 코드를 봐서도 알겠지만 원하는 선택지를 하나하나 호출해서 사용해야한다.

1. new URL("http:// ....")
2. openConnection()
3. URLConnection
4. getInputStream, getOutputStream
5. InputStream, OutputStream 처리

문제점

1. 응답코드가 4xx 거나 5xx 면 IOException 이 터진다.
2. 타임아웃을 설정할 수 없다.
3. 쿠키 제어가 불가
4. 정형화가 되어있지 않아서 확장성이 비교적 불편하다.

📌 Http Client

1. CloseableHttpClient httpclient=HttpClients.createDefault();
2. 메소드에 따라 new HttpGet("http:// ....");
3. CloseableHttpResponse response = httpclient.execute(httpget);
4. HttpEntity entity = response.getEntity();
5. Stream으로 entity.getContent() 처리 등

아래 코드는 위와 비슷한 구조로 post한다.
직접 코드를 짠건 아니지만 httpconnection보다는 수월하다고한다.(보다 짧고 직관적)
코드 출처 : https://digitalbourgeois.tistory.com/58

public void post(String requestURL, String jsonMessage) {
    try {
        HttpClient client = HttpClientBuilder.create().build(); // HttpClient 생성
        HttpPost postRequest = new HttpPost(requestURL); //POST 메소드 URL 새성 
        postRequest.setHeader("Accept", "application/json");
        postRequest.setHeader("Connection", "keep-alive");
        postRequest.setHeader("Content-Type", "application/json");
        postRequest.addHeader("x-api-key", RestTestCommon.API_KEY); //KEY 입력 
        //postRequest.addHeader("Authorization", token); // token 이용시

        postRequest.setEntity(new StringEntity(jsonMessage)); //json 메시지 입력 

        HttpResponse response = client.execute(postRequest);

        //Response 출력
        if (response.getStatusLine().getStatusCode() == 200) {
            ResponseHandler<String> handler = new BasicResponseHandler();
            String body = handler.handleResponse(response);
            System.out.println(body);
        } else {
            System.out.println("response is error : " + response.getStatusLine().getStatusCode());
        }
    } catch (Exception e){
        System.err.println(e.toString());
    }
}

httpURLconnection과 비교했을 때 좋은 점

* 모든 응답코드를 읽을 수 있다. httpResponse.getStatusLine().getStatusCode()
* 타임아웃 설정 가능
* 쿠키 제어가 가능

단점

* URLConnection을 이용한 방식보다 코드가 간결해졌지만, 여전히 반복적이고 코드들이 길다.
* 스트림 처리 로직을 별도로 짜야한다.
* 응답의 컨텐츠타입에 따라 별도 로직이 필요하다. ->restTemplate이 유용한 이유 중 하나

RestTemplate

📌 restTemplate이란?

동작원리를 설명하기전에 간단히 restTemplate에 대해 설명한다면 아래와 같다.

  • spring 3.0 부터 지원한다.
  • 스프링에서 제공하는 http 통신에 유용하게 쓸 수 있는 템플릿
  • HTTP 서버와의 통신을 단순화하고 RESTful 원칙을 지킨다.(json, xml을 쉽게 응답 받음)

.
.
.

httpclient방식은 사용한 적 없지만 resttemplate방식까지의 세 방식을 살펴 봤을 때 유사한 점은 request 메시지에 필요한 요소들을 작성하여 연결하면, response를 받아온다는 점이다.

다르다면 "연결"방식인 것 같다.

가령 HttpURLConnection은 openConnection(), getResponseCode()등을 통해 연결하고 bufferReader을 통해 받아온 정보들을 읽는다거나, HttpClient는 executue(post)를 통해 response를 가져온다는 것이다.

그렇다면 restTemplate은?

📌 code

일단 두가지 코드가 있다.

첫번째는 restTemplate을 bean 설정해주는 것이다. restTemplate을 매번 new 키워드로 생성하는것은 번거롭고 위험하다.(반복적인 작업을 줄여주는 부분이 굉장히 좋다. 이부분 덕분에 HttpURLConnection이나 HttpClient에서 매번 반복되는 작업과 달리 호출만해도 다른 세팅이 필요하지 않은 것이다.)
RestTemplate Config

위처럼 설정해도 되지만 원한다면 connection time, read time도 설정할 수 있다.

두번째는 위에서 생성한 restTemplate을 실제 호출하여 사용한 코드다.

저번에 올렸던 google OAuth를 사용한 것 중 token의 정보를 받아올 수 있도록 하는 메서드이다. GoogleOAuth.class에 restTemplate 변수를 의성 주입을 하여 호출한 것이다. 위에 다른 방식들과 코드를 비교해보자.

보낼 http message에 필요한 parameter를 작성하는 것은 똑같지만, 단지 postForEntity()메서드를 통해 connection의 많은 부분이 생략된다. 미리 config로 이부분을 만들어두었기 때문에 가능한 것이다.

직접 작성하면서 느낀 장점은 위의 두방식보다 코드의 일정 부분을 잘라 어떤 기능을 하는지 분리 하는것이 더 수월하고 그로 인해 코드 이해나 확장성이 좋다는 것이다.

📌 동작원리

동작 원리

1. 어플리케이션이 RestTemplate를 생성 -> URI, HTTP메소드 등의 헤더를 담아 요청
2. RestTemplate는 HttpMessageConverter를 사용하여 requestEntity를 요청메세지로 변환한다.
3. RestTemplate는 ClientHttpRequestFactory로 부터 ClientHttpRequest를 가져와서 요청을 보낸다.
4. ClientHttpRequest는 요청메세지를 만들어 HTTP 프로토콜을 통해 서버와 통신한다.
5. RestTemplate는 ResponseErrorHandler로 오류를 확인하고 있다면 처리로직을 태운다.
6. ResponseErrorHandler는 오류가 있다면 ClientHttpResponse에서 응답데이터를 가져와서 처리한다.
7. RestTemplate는 HttpMessageConverter를 이용해서 응답메세지를 
java object(class responseType)으로 변환한다.
8. 어플리케이션에 반환된다.

📨 글을 마치며

이번에 여러 기술을 비교하면서 느꼈던 점이, 사람들이 얘기하던 "직관적으로나 확장성으로나, 여러 방면에서 더 좋은 코드"를 짠다는게 이런게 아닌가 싶다. 처음에 이해하기 전에는 복잡해보이지만 제대로 공부하고 나면 훨씬 쉬운것 아닌가.

묘하게 mvc 구조도 생각나던데, 잊고있었던(공부한지 얼마 안됐으면서) mvc 구조도 들여다 보기로 하며.

0개의 댓글