쿠키를 올바르게 처리하는 동안 원격 서버에 http 요청을하고 싶습니다 (예 : 서버에서 보낸 쿠키를 저장하고 후속 요청을 할 때 해당 쿠키를 전송). 모든 쿠키를 보존하는 것이 좋지만 실제로 내가 신경 쓰는 유일한 것은 세션 쿠키입니다.
java.net을 사용하면 선호하는 방법은 java.net.CookieHandler (추상 기본 클래스) 및 java.net.CookieManager (구체적 구현)를 사용하는 것 같습니다. Android에는 java.net.CookieHandler가 있지만 java.net.CookieManager가없는 것 같습니다.
http 헤더를 검사하여 모든 것을 수작업으로 코딩 할 수 있지만 더 쉬운 방법이있을 것 같습니다.
쿠키를 보존하면서 Android에서 http 요청을하는 적절한 방법은 무엇입니까?
답변
Google Android는 Apache HttpClient 4.0과 함께 제공되며 HttpClient 문서 의 “Form based logon”예제를 사용하여 수행하는 방법을 알아낼 수있었습니다 .
import java.util.ArrayList;
import java.util.List;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.cookie.Cookie;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;
/**
* A example that demonstrates how HttpClient APIs can be used to perform
* form-based logon.
*/
public class ClientFormLogin {
public static void main(String[] args) throws Exception {
DefaultHttpClient httpclient = new DefaultHttpClient();
HttpGet httpget = new HttpGet("https://portal.sun.com/portal/dt");
HttpResponse response = httpclient.execute(httpget);
HttpEntity entity = response.getEntity();
System.out.println("Login form get: " + response.getStatusLine());
if (entity != null) {
entity.consumeContent();
}
System.out.println("Initial set of cookies:");
List<Cookie> cookies = httpclient.getCookieStore().getCookies();
if (cookies.isEmpty()) {
System.out.println("None");
} else {
for (int i = 0; i < cookies.size(); i++) {
System.out.println("- " + cookies.get(i).toString());
}
}
HttpPost httpost = new HttpPost("https://portal.sun.com/amserver/UI/Login?" +
"org=self_registered_users&" +
"goto=/portal/dt&" +
"gotoOnFail=/portal/dt?error=true");
List <NameValuePair> nvps = new ArrayList <NameValuePair>();
nvps.add(new BasicNameValuePair("IDToken1", "username"));
nvps.add(new BasicNameValuePair("IDToken2", "password"));
httpost.setEntity(new UrlEncodedFormEntity(nvps, HTTP.UTF_8));
response = httpclient.execute(httpost);
entity = response.getEntity();
System.out.println("Login form get: " + response.getStatusLine());
if (entity != null) {
entity.consumeContent();
}
System.out.println("Post logon cookies:");
cookies = httpclient.getCookieStore().getCookies();
if (cookies.isEmpty()) {
System.out.println("None");
} else {
for (int i = 0; i < cookies.size(); i++) {
System.out.println("- " + cookies.get(i).toString());
}
}
// When HttpClient instance is no longer needed,
// shut down the connection manager to ensure
// immediate deallocation of all system resources
httpclient.getConnectionManager().shutdown();
}
}
답변
쿠키는 또 다른 HTTP 헤더입니다. 아파치 라이브러리 또는 HTTPUrlConnection을 사용하여 HTTP 호출을 수행하는 동안 언제든지 설정할 수 있습니다. 어느 쪽이든이 방식으로 HTTP 쿠키를 읽고 설정할 수 있어야합니다.
자세한 내용은 이 기사 를 읽을 수 있습니다 .
나는 당신이 얼마나 쉽게 만들 수 있는지 보여주기 위해 내 코드의 평화를 공유 할 수 있습니다.
public static String getServerResponseByHttpGet(String url, String token) {
try {
HttpClient client = new DefaultHttpClient();
HttpGet get = new HttpGet(url);
get.setHeader("Cookie", "PHPSESSID=" + token + ";");
Log.d(TAG, "Try to open => " + url);
HttpResponse httpResponse = client.execute(get);
int connectionStatusCode = httpResponse.getStatusLine().getStatusCode();
Log.d(TAG, "Connection code: " + connectionStatusCode + " for request: " + url);
HttpEntity entity = httpResponse.getEntity();
String serverResponse = EntityUtils.toString(entity);
Log.d(TAG, "Server response for request " + url + " => " + serverResponse);
if(!isStatusOk(connectionStatusCode))
return null;
return serverResponse;
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
답변
이후 아파치 라이브러리가 사용되지 않으며 , 사용하고자하는 사람들을 위해 HttpURLConncetion
, 나는 가져 오기 및의 도움으로 POST 요청을 보내려면이 클래스 쓴 이 답변 :
public class WebService {
static final String COOKIES_HEADER = "Set-Cookie";
static final String COOKIE = "Cookie";
static CookieManager msCookieManager = new CookieManager();
private static int responseCode;
public static String sendPost(String requestURL, String urlParameters) {
URL url;
String response = "";
try {
url = new URL(requestURL);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(15000);
conn.setConnectTimeout(15000);
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/json; charset=utf-8");
if (msCookieManager.getCookieStore().getCookies().size() > 0) {
//While joining the Cookies, use ',' or ';' as needed. Most of the server are using ';'
conn.setRequestProperty(COOKIE ,
TextUtils.join(";", msCookieManager.getCookieStore().getCookies()));
}
conn.setDoInput(true);
conn.setDoOutput(true);
OutputStream os = conn.getOutputStream();
BufferedWriter writer = new BufferedWriter(
new OutputStreamWriter(os, "UTF-8"));
if (urlParameters != null) {
writer.write(urlParameters);
}
writer.flush();
writer.close();
os.close();
Map<String, List<String>> headerFields = conn.getHeaderFields();
List<String> cookiesHeader = headerFields.get(COOKIES_HEADER);
if (cookiesHeader != null) {
for (String cookie : cookiesHeader) {
msCookieManager.getCookieStore().add(null, HttpCookie.parse(cookie).get(0));
}
}
setResponseCode(conn.getResponseCode());
if (getResponseCode() == HttpsURLConnection.HTTP_OK) {
String line;
BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
while ((line = br.readLine()) != null) {
response += line;
}
} else {
response = "";
}
} catch (Exception e) {
e.printStackTrace();
}
return response;
}
// HTTP GET request
public static String sendGet(String url) throws Exception {
URL obj = new URL(url);
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
// optional default is GET
con.setRequestMethod("GET");
//add request header
con.setRequestProperty("User-Agent", "Mozilla");
/*
* /programming/16150089/how-to-handle-cookies-in-httpurlconnection-using-cookiemanager
* Get Cookies form cookieManager and load them to connection:
*/
if (msCookieManager.getCookieStore().getCookies().size() > 0) {
//While joining the Cookies, use ',' or ';' as needed. Most of the server are using ';'
con.setRequestProperty(COOKIE ,
TextUtils.join(";", msCookieManager.getCookieStore().getCookies()));
}
/*
* /programming/16150089/how-to-handle-cookies-in-httpurlconnection-using-cookiemanager
* Get Cookies form response header and load them to cookieManager:
*/
Map<String, List<String>> headerFields = con.getHeaderFields();
List<String> cookiesHeader = headerFields.get(COOKIES_HEADER);
if (cookiesHeader != null) {
for (String cookie : cookiesHeader) {
msCookieManager.getCookieStore().add(null, HttpCookie.parse(cookie).get(0));
}
}
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
return response.toString();
}
public static void setResponseCode(int responseCode) {
WebService.responseCode = responseCode;
Log.i("Milad", "responseCode" + responseCode);
}
public static int getResponseCode() {
return responseCode;
}
}
답변
나는 구글 안드로이드와 함께 일하지 않지만 당신이 이것을 작동시키는 것이 그렇게 어렵지 않다는 것을 알게 될 것이라고 생각합니다. 자바 튜토리얼의 관련 부분 을 읽으면 등록 된 쿠키 핸들러가 HTTP 코드에서 콜백을받는 것을 볼 수 있습니다.
따라서 기본값이없는 경우 ( CookieHandler.getDefault()
정말 null 인지 확인 했습니까?) 간단히 CookieHandler를 확장하고 put / get을 구현하고 거의 자동으로 작동하도록 할 수 있습니다. 해당 경로로 이동하는 경우 동시 액세스 등을 고려해야합니다.
편집 : 분명히 CookieHandler.setDefault()
콜백을 수신하려면 사용자 정의 구현의 인스턴스를 기본 핸들러로 설정해야합니다 . 그것을 언급하는 것을 잊었습니다.