okhttp 튜 토리 얼-시작 편

okhttp 튜 토리 얼-시작 편
이 글 은 주로 안 드 로 이 드 의 유명한 네트워크 프레임 워 크-okhttp의 기초 사용 을 정리 하고 나중에 그의 고급 사용 에 관 한 것 이 있 을 것 이다.
뭐 공부 해요?okhttp안 드 로 이 드 엔 드 의 Http 클 라 이언 트 입 니 다.그 기본 기능 은 안 드 로 이 드 자체HttpURLConnectionApache 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 요청
  • post 요청,매개 변 수 는 키 쌍
  • post 요청,다양한 종류의 body
  • 파일 다운로드
  • Gson 가입
  • get 요청
    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 의 사용 을 소 개 했 습 니 다.일부 고급 용법 에 대해 다음 글 을 주목 하 십시오.본인 의 수준 이 유한 합 니 다.만약 에 잘못 이 있 으 면 지적 해 주 십시오.

    좋은 웹페이지 즐겨찾기