Mobile/Android(Java)

[Android/java] Retrofit2를 이용한 JSON 데이터 HTTP 통신(GET, POST) 방법 (CLEARTEXT 오류 해결)

개발왕 금골드 2020. 3. 1. 14:48
반응형

안녕하세요 골드입니다.

오늘은 Retrofit2를 사용해서 HTTP통신을 하는 방법에 대해서 글을 쓰겠습니다.

 

 

1. HTTP 통신규약

HTTP는 www상에서 정보를 주고받을 수 있는 프로토콜입니다. 

HTTP는 이름이고 통신규약(프로토콜)은 원거리 통신 장비 사이에서 메세지를 주고 받는 규칙입니다.

웹에서 이루어지는 데이터 교환의 기초이며, 클라이언트와 서버를 이루고 요청/응답을 하는 프로토콜입니다.

 

작동 방식은 간단하게,

클라이언트에서 요청(Request)를 보내면

서버에서 그 요청을 받고 응답(Response)합니다.

 

서버의 과부화를 막기 위해 응답을 받으면 요청을 끊어버린다는 것은 많이 들어봤을 것입니다.

 

http에는 서버에게 요청의 종류를 알려주는 몇 가지 메서드가 존재합니다.

그 중 네 가지를 살펴보겠습니다.

 - GET : 정보를 요청하기 위해서 사용합니다. (SELECT)

 - POST : 정보를 밀어넣기 위해서 사용합니다. (INSERT)

 - PUT : 정보를 수정하기 위해서 사용합니다. (UPDATE)

 - DELETE :  정보를 삭제하기 위해서 사용합니다. (DELETE)

 

출처 : https://ko.wikipedia.org/wiki/HTTP

 

HTTP - 위키백과, 우리 모두의 백과사전

위키백과, 우리 모두의 백과사전. HTTP(HyperText Transfer Protocol, 문화어: 초본문전송규약, 하이퍼본문전송규약)는 WWW 상에서 정보를 주고받을 수 있는 프로토콜이다. 주로 HTML 문서를 주고받는 데에 쓰인다. TCP와 UDP를 사용하며, 80번 포트를 사용한다. 1996년 버전 1.0, 그리고 1999년 1.1이 각각 발표되었다. HTTP는 클라이언트와 서버 사이에 이루어지는 요청/응답(request/response) 프로토

ko.wikipedia.org

2. Retrofit

Retrofit은 Square에서 만든 라이브러리입니다.

Android와 Java 환경에서 HTTP API를 쉽고 안전하게 사용할 수 있도록 도와줍니다.

Retrofit은 HTTP API를 자바 인터페이스 형태로 사용할 수 있습니다.

 

Retrofit 사이트 : http://devflow.github.io/retrofit-kr/

 

Retrofit - 한글 문서

A type-safe HTTP client for Android and Java

devflow.github.io

읽어보시면 분명 도움이 될 것입니다.

 

물론, Android에서 제공되는 메소드를 이용하여 http를 직접 구현해서 사용할 수도 있습니다.

다만 초보자가 사용하기에 구현해야 하는 것도 많고,

생각할 것이 많기 때문에 라이브러리를 사용하는 것을 추천드립니다.

 

3. JSON Data

코드를 작성하기 전에 우리가 웹에서 어떤 자료를 가져오는지 알아야 합니다.

저는 JSON이라는 키-값이 쌍으로 이루어진 데이터를 가져올 것입니다.

JSON 표현식은 사람과 기계 모두 이해하기 쉬우며 용량이 작아서, 최근에 데이터 전송에 많이 사용됩니다.

또한, 대부분 프로그래밍 언어에서 JSON 데이터를 다룰 수 있는 라이브러리를 제공합니다.

 

JSON 형식은 이렇게 생겼습니다. key값과 value값이 쌍을 이루고 있습니다.

String, int 등등 자료형을 사용할 수 있습니다.

(현재 "password"의 자료형은 ""안에 있기 때문에 String입니다.)

 

혹은 [] 대괄호를 사용하여 배열(Array)형식으로 나열 할 수도 있습니다.

 

4. Retrofit을 사용하기 위한 Android 권한 설정

Retrofit을 사용하기 위해서 Gradle에 추가하도록 하겠습니다.

JSON은 Object 형식으로,

혹은 Object 형식을 JSON으로 바꿀 수 있습니다.

이게 매우 큰 장점인데, gson은 JSON을 자바 클래스로 바꿔주는 역할을 합니다.

한마디로 따로 변환 객체를 구현하지 않아도 되게 도와줍니다.

 

그리고 인터넷을 사용하기 위해 manifest 파일에 인터넷 권한을 추가합니다.

(인터넷만 추가하시면 됩니다.)

 

5. Interface 선언하기

먼저 Retrofit을 사용하기 위해 Interface를 하나 선언합니다.

이름은 RetrofitAPI라고 하겠습니다.

 

예제를 위해서는 JSON 데이터가 필요합니다. 저는

http://jsonplaceholder.typicode.com/ 라는 사이트를 이용하여 JSON 데이터에 접근하겠습니다.

- GET

@ 어노테이션이라고 표현합니다. 이 어노테이션으로 HTTP 메소드를 구현할 수 있습니다.

먼저 GET을 구현하겠습니다.

 

GET() 괄호 안에 /posts는 주소입니다. 

http://jsonplaceholder.typicode.com/posts 정확하게 말하면 이 주소를 말합니다.

하지만 /posts 앞에 주소는 공통이기 때문에 하나하나 적지 않고 바뀌는 부분만 적어놓습니다.

앞 부분은 나중에 정의할 것입니다.

 

Call객체를 선언해서 HTTP 요청을 웹서버로 보냅니다. 

<> 안에 자료형은 JSON 데이터를 <> 안에 자료형으로 받겠다는 뜻입니다.

그렇기 때문에 Post.class는 직접 구현해야 합니다.

 

그리고 userId값을 쿼리하기 위해 사용하는 SQL의 Query입니다. 

id변수에 값을 담아서 userId를 쿼리합니다.

 

- POST

@FieldMap은 Field 형식을 통해 넘겨주는 값이 여러개일 경우 사용합니다.

Field 형식이란 인자를 form-urlencoded로 보낼때 사용하는데

form-urlencoded는 key=value&key=value와 같은 형태로 데이터를 전달하는 것을 말합니다.

Retrofit에서 Field는 @FormUrlEncoded와 함께 쓰입니다.(없으면 에러)

 

Retrofit에서 Map보다 HashMap을 사용하길 권장한다고 합니다.

HashMap은 보시는 것처럼 key - value 쌍을 이루는 데이터 타입입니다.

 

(@FieldMap이 에러가 난다면 @Body 방법도 있습니다.

@Body는 java objects를 직렬화해서 보내는 방법입니다.

객체를 Json형식처럼 넘겨줄때 사용합니다.)

 

참고자료 : https://github.com/HwangEunmi/Retrofit-Sample#@FieldMap

https://youngest-programming.tistory.com/135

 

 

주소창에 http://jsonplaceholder.typicode.com/posts 주소를 적으면

이렇게 JSON 데이터를 볼 수 있습니다. 

 

 

6. JSON 데이터를 받아오기 위한 class 선언하기

이제 Post 클래스를 정의하겠습니다.

 

앞서 본 JSON 데이터들을 class로 받아오기 위한 작업입니다.

간단하게 생각하면 저 데이터에 key값들을 그대로 변수화한다고 생각하면 쉽습니다.

 

JSON 데이터값과 정확하게 일치하여야 합니다.

@SerializedName()으로 JSON 객체를 매칭해줬습니다. 여기서 gson을 사용하게 됩니다.

변수를 선언하고 변수에 대한 겟터 셋터를 만들어주었습니다.

겟터 셋터를 꼭 만들어 주셔야 합니다.

 

7. MainActivity에서 Retrofit 선언하기

MainActivity에 Retrofit 객체를 생성하겠습니다.

 

Retrofit 객체를 선언합니다. 

 - baseUrl 을 선언해서 주소값 중에 바뀌지 않는 고정값을 적어줍니다.

보통 바뀌지 않기 때문에 따로 상수로 저장해서 사용하게 됩니다.

 - addConverterFactory로 gson converter를 생성합니다. gson은 JSON을 자바 클래스로 바꾸는데 사용됩니다.

 

그리고 인터페이스를 생성합니다. 

- GET

생성한 인터페이스 getData에 쿼리할 id값을 넣고 인큐합니다.

인큐는 하나하나 큐에 집어넣는다는 말입니다. 큐는 선입선출입니다.

 

인큐에 오버라이드된 두 메소드가 있습니다.

성공적으로 Response했다면 onResponse가 호출되고,

실패했다면 onFailure가 호출됩니다.

 

onResponse가 호출됐다 하더라고 안전장치로 if문을 구현합니다.

우리가 원하는 데이터는 response의 body 안에 있습니다.

자료형을 맞춰서 데이터를 가져오고 테스트로 Log에 뿌려보겠습니다.

 

실행합니다.

로그가 찍히는 모습을 볼 수 있습니다.

 

- POST

HashMap형식의 데이터를 전달하고 onResponse가 호출됐을 경우 로그로 보여줍니다.

 

참고자료 : https://altongmon.tistory.com/745

 

* UnknownServiceException CLEARTEXT communication not permitted

실행을 했는데 이런 에러와 함께 onFailure 메소드가 호출될 수 있습니다.

이유는 Android Pie(9.0)부터 네트워크 보안 정책이 바뀌었기 때문입니다.

 

https:// 주소가 아닌 http:// 주소는 보안에 취약하기 때문에 따로 설정을 해주셔야 합니다.

 

설정을 하기 위해 res/xml 폴더에 network_security_config.xml 파일을 만듭니다.

xml 파일을 작성합니다.

cleartextTrafficPermitted를 true로 설정하여 http를 사용할 수 있게 선언하고,

여러분이 사용하는 주소를 작성하여 줍니다.

 

그러면 저 주소에 한하여 http를 허용하게 됩니다.

 

이제 Manifest파일에 <application>부분에 config.xml파일을 사용하겠다고 선언합니다.

참고자료 : https://developer.android.com/training/articles/security-config?hl=ko

 

네트워크 보안 구성  |  Android 개발자  |  Android Developers

앱 개발자가 안전한 구성 파일에서 네트워크 보안 설정을 사용자설정할 수 있는 기능입니다.

developer.android.com

https://gun0912.tistory.com/80

오늘은 Retrofit에 대해 알아보았습니다.

 

여기까지 골드였습니다.

감사합니다.

반응형