okhttp 튜 토리 얼-시작 편
이 글 은 주로 안 드 로 이 드 의 유명한 네트워크 프레임 워 크-
okhttp
의 기초 사용 을 정리 하고 나중에 그의 고급 사용 에 관 한 것 이 있 을 것 이다.뭐 공부 해요?
okhttp
안 드 로 이 드 엔 드 의 Http 클 라 이언 트 입 니 다.그 기본 기능 은 안 드 로 이 드 자체HttpURLConnection
와Apache HTTP Client
에 해당 하지만 그 는 자체 가 가지 고 있 는 2 개의 Http 클 라 이언 트 보다 훨씬 좋 습 니 다.하 나 는 쓰기 가 간단 하고 양자 okhttp 은 많은 네트워크 복잡 한 문 제 를 처리 합 니 다.예 를 들 어 자주 사용 하 는 연결 문제 에서 자동 으로 회 복 됩 니 다.서버 에 여러 개의 IP 주 소 를 설정 하면 첫 번 째 IP 연결 이 실 패 했 을 때 OkHttp 는 자동 으로 다음 IP 를 시도 합 니 다.OkHttp 는 프 록 시 문제 와 SSL 악수 실패 등 많은 문 제 를 처리 했다.양자 에 관 해 서 는 이 글 은 토론 하지 않 는 다.okhttp 가 져 오기
Gradle 가 져 오기
compile 'com.squareup.okhttp3:okhttp:3.2.0'
compile 'com.squareup.okio:okio:1.6.0'
okhttp 기본 사용
여기 서 우 리 는 주로 간단 한 사용 을 소개 하 는데,소개 내용 은 다음 과 같다.
get 요청 은 동기 get 과 비동기 get 으로 나 뉘 는데 이들 의 차 이 는 주로 get 의 방식 이 다른 스 레 드 에서 일 하 는 것 입 니까?아니면 이 스 레 드 에서 일 하 는 것 입 니까?요청 방식 은 대동소이 하 다.우선 OkHttpClient 대상 을 정의 합 니 다.다음 과 같 습 니 다.
private OkHttpClient client = new OkHttpClient();
그리고 Request 를 구축 합 니 다.구축 방식 은 다음 과 같 습 니 다.
Request request = new Request.Builder().
url("http://www.baidu.com").
build();
이것 은 가장 간단 한 request 의 구축 방식 입 니 다.물론 우 리 는 매우 복잡 하 게 구축 할 수 있 습 니 다.
Request request = new Request.Builder().
url("http://www.baidu.com").
addHeader("User-Agent","android").
header("Content-Type","text/html; charset=utf-8").
build();
addHeader 와 header 방법 을 통 해 요청 머리 를 추가 할 수 있 습 니 다.header(name,value)를 사용 하면 유일한 name,value 를 설정 할 수 있 습 니 다.값 이 있 으 면 오래된 것 은 제거 되 고 새 것 을 추가 합 니 다.addHeader(name,value)를 사용 하면 여러 값 을 추가 할 수 있 습 니 다.
동기 화 get 방법,client.newCall(request).execute()방법 으로 요청 한 response 를 받 습 니 다.
Response response = okHttpClient.newCall(request).execute();
OkHttp 는 response.headers()의 headers 를 얻 는 등 response 를 처리 하 는 방법 을 많이 패키지 합 니 다.
Headers headers = response.headers();
for (int i = 0; i < headers.size(); i++) {
System.out.println(headers.name(i) + ": " + headers.value(i)); }
결 과 는 다음 과 같다.
Date: Mon, 18 Apr 2016 05:23:43 GMT
Content-Type: text/html; charset=utf-8
Transfer-Encoding: chunked
Connection: Keep-Alive
Vary: Accept-Encoding
Set-Cookie: BAIDUID=A323EC9BF678C0EB78E20741FD71211B:FG=1; expires=Thu, 31-Dec-37 23:55:55 GMT; max-age=2147483647; path=/; domain=.baidu.com
Set-Cookie: BIDUPSID=A323EC9BF678C0EB78E20741FD71211B; expires=Thu, 31-Dec-37 23:55:55 GMT; max-age=2147483647; path=/; domain=.baidu.com
Set-Cookie: PSTM=1460957023; expires=Thu, 31-Dec-37 23:55:55 GMT; max-age=2147483647; path=/; domain=.baidu.com
Set-Cookie: BDSVRTM=0; path=/
Set-Cookie: BD_HOME=0; path=/
Set-Cookie: H_PS_PSSID=1434_19672_18281_19690_17948_18205_19558_15952_12257; path=/; domain=.baidu.com
P3P: CP=" OTI DSP COR IVA OUR IND COM "
Cache-Control: private
Cxy_all: baidu+2db7793e0e32b9f6c20be8f623e1ae43
Expires: Mon, 18 Apr 2016 05:22:55 GMT
X-Powered-By: HPHP
Server: BWS/1.1
X-UA-Compatible: IE=Edge,chrome=1
BDPAGETYPE: 1
BDQID: 0xfacc6fc10004ca96
BDUSERID: 0
OkHttp-Sent-Millis: 1460957021226
OkHttp-Received-Millis: 1460957021430
메시지 에 응답 하 는 실 체 는 response.body().string()을 통 해 가 져 올 수 있 습 니 다.되 돌아 오 는 바 이 너 리 바이트 배열 을 원 하면 response.body().bytes()를 호출 합 니 다.되 돌아 오 는 input Stream 을 받 고 싶다 면 response.body().by teStream()을 호출 하 십시오.
비동기 get 요청 으로 얻 은 response 방법 은 다음 과 같 습 니 다.
okHttpClient.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) throws IOException {
}
});
onResponse 방법 에서 요청 에 성공 한 코드 를 실행 합 니 다.onFailure 방법 에서 요청 에 실패 한 코드 를 실행 합 니 다.다음은 완전한 비동기 get 의 밤 을 드 립 니 다.
import android.os.Bundle;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.text.method.ScrollingMovementMethod;
import android.widget.TextView;
import java.io.IOException;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.Headers;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
public class MainActivity extends AppCompatActivity {
private OkHttpClient okHttpClient = new OkHttpClient();
public TextView show;
public Handler handler = new Handler();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
show = (TextView) findViewById(R.id.show);
show.setMovementMethod(ScrollingMovementMethod.getInstance());
Request request = new Request.Builder().
url("http://www.baidu.com").
addHeader("User-Agent", "android").
header("Content-Type", "text/html; charset=utf-8").
get().
build();
okHttpClient.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, final Response response) throws IOException {
final Headers headers = response.headers();
final String str = response.body().string();
handler.post(new Runnable() {
@Override
public void run() {
for (int i = 0; i < headers.size(); i++) {
show.append(headers.name(i) + ": " + headers.value(i));
show.append(str);
}
}
});
}
});
}
}
사실 홈 페이지 에 따 르 면 리 셋 은 response 의 headers 가 준비 되면 발생 하기 때문에 response 를 요청 하 는 실체 부분 이 막 힐 때 가 있다.
post 요청-키 값 쌍 을 매개 변수 로 합 니 다.
post 요청 과 get 요청 은 request 구축 에 있어 서 다른 것 을 제외 하고 response 처리 에 있어 서 모두 같 습 니 다.따라서 다음은 post 구축 request 만 토론 하 겠 습 니 다.물론 post 도 동기 화 post 와 비동기 post 를 지원 하 므 로 get 방법 을 참고 할 수 있 습 니 다.post 의 request 를 구축 할 때 먼저 FormBody.Builder 로 request 의 body 부분 을 구축 합 니 다.밤 은 다음 과 같 습 니 다.물론 이것 은 OKHttp 3 의 방법 입 니 다.
FormBody.Builder builder = new FormBody.Builder();
for(int i = 0 ; i < key.size() ;i ++){
builder.add(key.get(i),value.get(i));
}
RequestBody body = builder.build();
builder 에서 add 는 추가 할 인자 키 쌍 입 니 다.바디
Request request = new Request.Builder().url(url).post(body).build();
요청 한 request 를 얻 으 면 다음 작업 은 get 방법 과 같 습 니 다.비동기 get 의 밤 을 참고 하여 post 의 request 를 구축 할 수 있 습 니 다.아래 의 쓰기 방법 은 그대로 입 니 다.
post 요청--다양한 종류의 body
앞에서 말 했 듯 이 post 와 get 의 용법 은 주로 서로 다른 request 를 구축 하 는 데 있 기 때문에 다음 에 우리 가 주로 토론 하 는 것 도 request 를 어떻게 구축 하 는 지 입 니 다.참고 로 우 리 는 먼저 request Body 를 만들어 야 합 니 다.우 리 는 아래 의 방식 으로 구축 할 수 있 습 니 다.물론 이것 도 okhttp 3 의 방법 입 니 다.
MultipartBody.Builder builder = new MultipartBody.Builder().setType(MultipartBody.FORM);
폼 이 올 라 온 형식 으로 post 를 제출 합 니 다.builder 방법 좀 볼 게 요.
/** Add a part to the body. */
public Builder addPart(RequestBody body) {
return addPart(Part.create(body));
}
/** Add a part to the body. */
public Builder addPart(Headers headers, RequestBody body) {
return addPart(Part.create(headers, body));
}
/** Add a form data part to the body. */
public Builder addFormDataPart(String name, String value) {
return addPart(Part.createFormData(name, value));
}
/** Add a form data part to the body. */
public Builder addFormDataPart(String name, String filename, RequestBody body) {
return addPart(Part.createFormData(name, filename, body));
}
여기 서 알 수 있 듯 이
public Builder addFormDataPart(String name, String filename, RequestBody body)
로 File 을 직접 업로드 할 수 있 습 니 다.마지막 매개 변 수 는 요청 한 실체 로RequestBody.create(final MediaType contentType, final File file)
를 통 해 얻 을 수 있 고MediaType
는 다음 과 같은 방법 으로 얻 을 수 있 습 니 다.// judgeType
private static final MediaType MEDIA_TYPE = MediaType.parse(judgeType(fileName);
//judge
private String judgeType(String path) {
FileNameMap fileNameMap = URLConnection.getFileNameMap();
String contentTypeFor = fileNameMap.getContentTypeFor(path);
if (contentTypeFor == null) {
contentTypeFor = "application/octet-stream";
}
return contentTypeFor;
}
내 백 스테이지 능력 이 비교적 떨 어 지기 때문에,여 기 는 홈 페이지 의 예 를 들 어 내 가 방금 토론 한 방법 을 한 번 실현 한다.
MultipartBody.Builder builder = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("image", "logo-square.png",
RequestBody.create(MEDIA_TYPE_PNG, new File("website/static/logo-square.png")));
RequestBody requestBody = builder.build();
Request request = new Request.Builder()
.header("Authorization", "Client-ID " +"9199fdef135c122")
.url("https://api.imgur.com/3/image")
.post(requestBody)
.build();
물론 이 방법 을 제외 하고 다음 과 같은 방법 을 호출 하 는 것 도 가능 합 니 다.우 리 는 name 과 filename 을 이용 하여 자체 적 으로 Header 를 만들어 전달 할 수 있 습 니 다.
public Builder addPart(Headers headers, RequestBody body) {
return addPart(Part.create(headers, body))
밤 은 다음 과 같다.
builder.addPart(Headers.of("Content-Disposition", "form-data; name=\"" + name + "\"; filename=\"" + fileName + "\""),fileBody);
뒤의 쓰 기 는 위 와 유사 해서 우 리 는 파일 업로드 의 쓰 기 를 실현 했다.
파일 다운로드
방금 위 에서 말 했 듯 이 되 돌아 오 는 바 이 너 리 바이트 배열 을 얻 으 려 면 response.body().bytes()를 호출 합 니 다.되 돌아 오 는 input Stream 을 받 고 싶다 면 response.body().by teStream()을 호출 하 십시오.다시 말 하면 파일 의 다운 로드 는 get 요청 을 통 해 해당 하 는 response 를 얻 을 수 있 고 그의 실 체 를 바 이 너 리 스 트림 으로 파일 에 기록 하 는 것 은 파일 의 다운 로드 를 실현 하 는 것 이다.주요 한 서법 은 바로 파일 의 읽 기와 쓰기 입 니 다.OKHttp 와 관계 가 크 지 않 습 니 다.물론 우 리 는 okio 로 파일 의 읽 기와 쓰 기 를 실현 할 수 있 습 니 다.여기 수준 이 제한 되 어 있 으 면 소개 하지 않 습 니 다.다음은 간단 한 예 를 드 리 겠 습 니 다.
private void _download(final String url, final String destFileDir, final ResultCallback callback) {
final Request request = new Request.Builder().url(url).build();
final Call call = okHttpClient.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) throws IOException {
InputStream is = null;
byte[] buf = new byte[2048];
int len = 0;
FileOutputStream fos = null;
try {
is = response.body().byteStream();
File file = new File(destFileDir, getFileName(url));
fos = new FileOutputStream(file);
while((len = is.read(buf)) != -1){
fos.write(buf,0,len);
}
fos.flush();
//....
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
if (is != null) is.close();
} catch (IOException e) {
}
try
{
if (fos != null) fos.close();
} catch (IOException e)
{
}
}
}
});
}
Gson 가입
그 다음 에 우 리 는 매우 실제 적 인 문 제 를 토론 합 니 다.안 드 로 이 드 의 네트워크 요청 은 보통 한 사이트 의 Html 을 요청 하지 않 습 니 다.더 많은 것 은 배경 인 터 페 이 스 를 요청 하 는 Json 파일 이기 때문에 우 리 는 Gson 으로 json 의 분석 을 처리 합 니 다.이 부분 은 앞에서 말 한 것 과 다 릅 니 다.앞에서 말 한 것 은 서로 다른 request 를 어떻게 구축 하여 response 를 얻 는 지,응답 한 결과 에 대한 처 리 는 일치 합 니 다.그러나 여기 서 주요 한 표기 법 은 Gson 으로 response 를 처리 하 는 것 이 고 request 의 구축 은 위 에서 소개 한 방법 에 따라 구축 되 며 바 꿀 필요 가 없다.
Gson 가 져 오기
compile 'com.google.code.gson:gson:2.6.2'
예 를 들 어 저희 백 스테이지 에서 제 시 된 api 는 이런 제 이 슨 파일 입 니 다.
{
"status": 0,
"intro": " ",
"shopName": "byhieg",
"message": " ",
}
이러한 Test.java 파일 을 간단하게 구축 할 수 있 습 니 다.다음 과 같 습 니 다.
public class Test {
/**
* status : 0
* intro : byhieg
* shopName : byhige
* message :
*/
private int status;
private String intro;
private String shopName;
private String message;
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
public String getIntro() {
return intro;
}
public void setIntro(String intro) {
this.intro = intro;
}
public String getShopName() {
return shopName;
}
public void setShopName(String shopName) {
this.shopName = shopName;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
response 를 받 은 후 다음 코드 로 JSon 파일 을 result 대상 으로 해석 합 니 다.그리고 result 대상 의 get 방법 을 호출 하면 json 파일 의 intro 값 과 shopname 값,status 와 message 를 얻 을 수 있 습 니 다.
Test result = new Gson().fromJson(response.body().string,Test.class);
총결산
간단하게 okHttp 의 사용 을 소 개 했 습 니 다.일부 고급 용법 에 대해 다음 글 을 주목 하 십시오.본인 의 수준 이 유한 합 니 다.만약 에 잘못 이 있 으 면 지적 해 주 십시오.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.