OkHttp 란?
OkHttp는 REST API, HTTP 통신을 간편하게 구현할 수 있도록 다양한 기능을 제공해주는 Square에서 제공하는 Java 오픈소스 라이브러리 입니다. OkHttp 라이브러리는 Retrofit 이라는 라이브러리의 베이스가 된다. OkHttp를 이용하면 간편하게 몇 줄의 코딩으로 REST 호출을 전송, HTTP 기반의 요청, 응답을 처리할 수 있습니다.
공식 사이트 : square.github.io/okhttp/
깃허브 : github.com/square/okhttp
여기서
http 통신이 궁금하다면 다음 글을 :
RestAPI 이 궁금하다면 다음글을 :
참고해주세요 ^^
OkHttp 구현?
gradle의 dependencies를 설정해줍니다.
dependencies {
// define a BOM and its version
implementation(platform("com.squareup.okhttp3:okhttp-bom:4.9.1"))
// define any required OkHttp artifacts without version
implementation("com.squareup.okhttp3:okhttp")
implementation("com.squareup.okhttp3:logging-interceptor")
}
아래는 공식 사이트에 나온 사용 예제 코드입니다.
Get a URL
URL을 다운로드하고 그 내용을 문자열로 출력해줍니다.
OkHttpClient client = new OkHttpClient();
String run(String url) throws IOException {
Request request = new Request.Builder()
.url(url)
.build();
try (Response response = client.newCall(request).execute()) {
return response.body().string();
}
}
Post to a Server
json을 서버로 전송해줍니다.
public static final MediaType JSON
= MediaType.get("application/json; charset=utf-8");
OkHttpClient client = new OkHttpClient();
String post(String url, String json) throws IOException {
RequestBody body = RequestBody.create(JSON, json);
Request request = new Request.Builder()
.url(url)
.post(body)
.build();
try (Response response = client.newCall(request).execute()) {
return response.body().string();
}
}
GET, POST, HEAD, DELETE 예제 ?
GET, HEAD, DELETE 동기요청 예제
GET http://127.0.0.1:8080/v1/test/get?key=123
http://127.0.0.1:8080/v1/test/get 이라는 API가 공개되어 있고
이 URL에 정보를 조회하고자 하는 Key를 쿼리 파라미터로 전달하는 Java 코드
public boolean getUserInfo(String key) {
try {
String url = "http://127.0.0.1:8080/v1/test/get?key=" + key;
OkHttpClient client = new OkHttpClient();
// GET 요청을 Request.Builder 를 통해 만듦 (get 요청임을 명시)
Request.Builder builder = new Request.Builder().url(url).get();
builder.addHeader("password", "BlahBlah");
Request request = builder.build();
// client 객체의 newCall() 메소드에 만들어진 Request를 전달하고, execute() 메소드를 실행
Response response = client.newCall(request).execute();
// execute() 메소드는 요청에 대한 응답이 올때까지 기다렸다가 반환
if (response.isSuccessful()) {
ResponseBody body = response.body();
if (body != null) {
System.out.println("Response:" + body.string());
}
}else{
System.err.println("Error Occurred");
}
return true;
} catch(Exception e) {
e.printStackTrace();
return false;
}
}
우선 OkHttp 요청을 전송할 OkHttpClient 객체가 필요하다.
그 다음 GET 요청을 Request.Builder 를 통해 만든다. 이 때, REST API 요청을 전송할 URL과 get() 메소드를 사용하여 GET 요청임을 명시한다. addHeader() 메소드를 이용하여 헤더 정보에 Password를 명시한다.
그리고 client 객체의 newCall() 메소드에 만들어진 Request를 전달하고, execute() 메소드를 실행한다. execute() 메소드는 요청에 대한 응답이 올때까지 기다렸다가 반환한다.
요청에 대한 응답이 오면 Response 객체를 반환 받게 된다. Response 객체에는 요청에 대한 바디(Body) 정보가 담겨 있으며, 요청이 실패했을 경우 에러 코드 등이 담겨있다.
HEAD 요청과, DELETE 요청은 기본적으로 GET 요청과 동일하게 처리된다.
다만 Request.Builder 에서 get() 메소드 대신 head() 혹은 delete() 메소드로 바꾸기만 하면됩니다.
GET요청
GET http://127.0.0.1:8080/v1/test/get?key=123 HTTP/1.1
Request.Builder builder = new Request.Builder().url(url).get();
HEAD요청
HEAD http://127.0.0.1:8080/v1/test/get?key=123 HTTP/1.1
Request.Builder builder = new Request.Builder().url(url).head();
DELETE 요청
DELETE http://127.0.0.1:8080/v1/test/get?key=123 HTTP/1.1
Request.Builder builder = new Request.Builder().url(url).delete();
POST, PUT 동기요청 예제
POST http://127.0.0.1:8080/v1/test/post
{ "name": "blue", "age": 5 }
public boolean postUserInfo() {
try {
String url = "http://127.0.0.1:8080/v1/test/post";
String postBody = "" + "{" + "\"key\":123," + "\"value\":55323" + "}";
OkHttpClient client = new OkHttpClient();
RequestBody requestBody = RequestBody.create(
MediaType.parse("application/json; charset=utf-8"), postBody);
Request.Builder builder = new Request.Builder().url(url)
.addHeader("Password", "BlahBlah")
.post(requestBody);
Request request = builder.build();
Response response = client.newCall(request).execute();
if (response.isSuccessful()) {
ResponseBody body = response.body();
if (body != null) {
System.out.println("Response:" + body.string());
}
} else
System.err.println("Error Occurred");
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
RequestBody 객체에 전달할 Body의 내용과 컨텐츠 타입(JSon)이 추가되었다.
Body가 없이 빈 POST 요청을 보내고 싶으면,
RequestBody body = RequestBody.create(null, new byte[0]);
이런 식으로 RequestBody를 만들어도 된다.
PUT 요청도 POST 요청처럼 RequestBody body = RequestBody.create() 요청으로 body를 만들어서 request builder의 put() 메소드의 인자로 주면된다.
POST, PUT 비동기요청 예제
여기까지는 동기 요청(Synchronous Request)였다. 즉, client.newCall(request).execute()를 실행하면, 요청에 대한 응답이 얻어 질때까지 대기했다. OkHttp는 비동기적인 요청(Asynchronous Request)도 지원한다. OkHttpClient의 execute() 메소드 대신 enqueue() 메소드를 사용하면된다. enqueue() 메소드의 인자로 요청이 완료되면 실행될 콜백(Callback)을 넘겨주면 비동기적인 요청을 전송하게 된다.
Callback은 인터페이스로 다음과 같은 메소드를 구현해야 한다.
public interface Callback {
void onFailure(Call call, IOException e);
void onResponse(Call call, Response response) throws IOException;
}
비동기적으로 요청한 Request가 성공적으로 응답을 받으면 onResponse() 메소드가 호출되고, 예외가 발생하는 등 실패하면 onFailure() 메소드가 호출된다.
위에서 구현한 POST 요청을 비동기적인 방식으로 구현하면 다음과 같다.
public void postAsyncUserInfo() {
try {
String url = "http://127.0.0.1:8080/v1/test/post";
String postBody = "" + "{" + "\"key\":123," + "\"value\":55323" + "}";
OkHttpClient client = new OkHttpClient();
RequestBody requestBody = RequestBody.create(
MediaType.parse("application/json; charset=utf-8"), postBody);
Request.Builder builder = new Request.Builder().url(url)
.addHeader("Password", "BlahBlah")
.post(requestBody);
Request request = builder.build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
System.err.println("Error Occurred");
}
@Override
public void onResponse(Call call, Response response) throws IOException {
ResponseBody body = response.body();
if (body != null) {
System.out.println("Response:" + body.string());
}
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
enqueue() 메소드는 요청에 대한 응답을 기다리지 않고 바로 리턴한합니다.
이 후, 비동기적으로 요청이 전송되며, 요청이 실패하거나 응답을 받으면 등록해놓은 Callback() 객체가 실행되어 상황에 따라 onFailure(), onResponse() 메소드가 실행됩니다.
정리하면
동기처리는 execute를
비동기 처리를 원한다면 enqueue !!
출처
'Android > Android 더하기' 카테고리의 다른 글
내부(innter)클래스 중첩(nested)클래스 그리고 메모리 누수 (0) | 2021.05.02 |
---|---|
MVVM 패턴 (0) | 2021.04.22 |
[Android Library] Gson : Json을 Java 객체로 변환 (0) | 2021.04.19 |
REST API : HTTP 모범생 (0) | 2021.04.16 |
HTTP 원리 (0) | 2021.04.15 |