2016-07-03 3 views
0

"브라우저로"(쿠키의 측면에서 보면 & 헤더로) 통신하려는 일부 코드를 작성했습니다. 나는 현재 네 가지 요청 (GET, POST, POST, GET)을 가지고있다.HttpsUrlConnection 안드로이드 대 네이티브 Java

코드는 매우 간단합니다. 연결 열기, 헤더 및 쿠키 추가, 응답 구문 분석.

GET 코드 :

conn = (HttpsURLConnection) url.openConnection(); 
conn.setRequestMethod("GET"); 
conn.setUseCaches(false); 
conn.setRequestProperty("User-Agent", userAgent); 
conn.setRequestProperty("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"); 
conn.setRequestProperty("Accept-Language", "en-US,en;q=0.5"); 
if (cookies != null) { 
    for (String cookie : this.cookies) { 
     conn.addRequestProperty("Cookie", cookie.split(";", 1)[0]); 
    } 
} 
int responseCode = conn.getResponseCode(); 
BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream())); 
String inputLine; 
StringBuilder response = new StringBuilder(); 

while ((inputLine = in.readLine()) != null) { 
    response.append(inputLine); 
} 
in.close(); 

setCookies(conn.getHeaderFields().get("Set-Cookie")); 

return response.toString(); 

우편 번호 :

conn = (HttpsURLConnection) url.openConnection(); 
conn.setUseCaches(false); 
conn.setRequestMethod("POST"); 
conn.setRequestProperty("Host", "..."); 
conn.setRequestProperty("User-Agent", userAgent); 
conn.setRequestProperty("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"); 
conn.setRequestProperty("Accept-Language", "en-US,en;q=0.5"); 
conn.setRequestProperty("Accept-Encoding","identity"); 
for (String cookie : this.cookies) { 
    conn.addRequestProperty("Cookie", cookie.split(";", 1)[0]); 
} 
conn.setRequestProperty("Connection", "keep-alive"); 
conn.setRequestProperty("Referer", "https://..."); 
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); 
conn.setRequestProperty("Content-Length", Integer.toString(postParams.length())); 

conn.setDoOutput(true); 
conn.setDoInput(true); 

DataOutputStream wr = new DataOutputStream(conn.getOutputStream()); 
wr.writeBytes(postParams); 
wr.flush(); 
wr.close(); 

int responseCode = conn.getResponseCode(); 
InputStream is = responseCode != 400 ? conn.getInputStream() : conn.getErrorStream(); 
BufferedReader in = new BufferedReader(new InputStreamReader(is)); 
String inputLine; 
StringBuilder response = new StringBuilder(); 

while ((inputLine = in.readLine()) != null) { 
    response.append(inputLine); 
} 
in.close(); 

return response.toString(); 

이 프로그램은 내 PC에 잘 작동합니다. 그러나 Android 기기에서 실행할 때 두 번째 POST에 여러 개의 문제가 발생합니다. ; 한 장치에는 Too many redirections 예외가 있고 또 다른 장치 (내가 집중 한 장치)에는 정확히 동일한 요청이 내 PC에 200을 반환하지만 단순히 400 Bad Request 만받습니다.

실제로 두 가지 구현이 있습니다 : PC에서는 sun.net.www.protocol.https.DelegateHttpsURLConnection을 사용하고 있고 Android에서는 com.android.okhttp.internal.http.HttpURLConnectionImpl입니다. 객체 conn은 런타임 동안 약간 다르게 보입니다. 그러나, 나는 의미있는 차이를 발견하지 못했다. (필요한 경우, 나는이 대상들의 전체 내용을 게시 할 수있다.) 첫 번째 GET에서 설정 한 쿠키가 한 가지 차이점을 발견했지만 수동 조작으로 같은 결과를 얻었습니다.

Wireshark를 사용하여 Android 출력 요청을 캡처하려고했지만 결과가 암호화되어있어 관리하지 못했습니다. 해독하십시오.

가 나는 기본적으로 두 가지 가능한 시나리오를 생각 :

  • 그 구현의 차이 (들)을 찾아 그에 따라 행동한다.
  • Android에서 sun.net.www.protocol.https.DelegateHttpsURLConnection을 사용하는 방법을 찾아보십시오.

지금까지 이러한 문제를 파악하지 못했습니다. 이러한 구현과 관련하여 알려진 차이점이나 문제점이 있습니까? Android에 원시 Java 라이브러리를 실행하는 방법이 있습니까? 어떤 도움을 주셔서 감사합니다, 감사합니다.

+0

로그를 사용하거나 더 헤더가 속아하거나 추가 헤더가 존재되었는지 확인 좋습니다. http://stackoverflow.com/questions/22173517/httpurlconnection-wire-logging-in-android 그리고 'writer'로 본문의 원시 바이트 인코딩을 시도하십시오. 마지막 포인트는 바이트 배열을 스트림으로 변환하는 것과 같습니다. –

+0

헤더를 요청할 때 암시 적으로 스트림을 가져 오기 때문에 출력 스트림을 가져 오기 전에 헤더를 로깅하면 예외가 발생합니다. 'Watches'창에서 비슷한 것을 체크 할 때 똑같은 일이 일어났습니다. –

+0

두 번째 조언에 대해서는 현재 POST 요청의 입력 매개 변수에 대해서만이 작업을 수행하고 있습니다 (변수'postParams' 참조). JSoup 사용하기 나는 모든 엘리먼트에'input' 태그를 붙이고, 인코딩 후에'URLEncoder.encode'를 사용하여 연결합니다. 이 주제에 대해 할 일이 있다고 생각하십니까? –

답변

0

예, SDK의 차이점은 데스크톱이 Oracle sdk이고 Android에 Google이 게시 한 것입니다. 안드로이드에 HTTP 요청을 할 때

ONY 방법은, 그것은 Retrofit 또는 Volley

+0

지난 며칠 동안 Volley에 집중했고 지금까지 나는 같은 단계에서 문제를 해결할 수 없었고 두려웠습니다. 그것은 실제로 HttpUrlConnection에 의존하기 때문에 막 다른 골목 일 것입니다 ... –

+0

Oracle SDK를 사용하는 것이 가능한지 알고 있습니까? C와 C++을 사용할 수있게하는 NDK에 대해 읽었습니다. 아마도 네이티브 Java와 비슷한 것이있을 것입니다. –

+0

아니요, Oracle SDK를 사용할 수 없습니다. – shem