Android 개발시 apache http client 모듈을 이용할 경우 HttpClient 클래스를 이용하여 다음과 같이 GET/POST 메소드로 전송할 수 있다. 즉, HTTP로 요청할 수 있다.
일단 간단한 소스 코드를 살펴보자.
HttpClient client = new DefaultHttpClient();
HttpGet method = new HttpGet("http://www.daum.net");
method.setHeader("User-Agent", "Android emulator");
HttpResponse res = null;
try {
res = client.execute(method);
StatusLine status = res.getStatusLine();
if (status.getStatusCode() == HttpStatus.SC_OK) {
System.out.println("Method completed");
} else {
System.err.println("Method failed: " + status.getReasonPhrase());
}
} catch ( ClientProtocolException e ) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
} finally {
}
일단, 위의 소스는 에러가 발생하지 않는다. 왜냐하면 HttpGet 클래스를 이용한 GET 메소드로 요청하는 것이기 때문이다.
따라서 별도의 Content-Length를 명시하지 않아도 된다.
그런데, 만약 POST 메소드로 요청시에는 Http body 가 첨부됨으로 Content-Length 를 http header 에 명시해 준다. 안드로이드 상에서는 다음과 같이 해 주면 된다.
method.setHeader("Content-Length", "" + httpBody.length);
여기서 이 코딩이 화근이다. 실제로 안드로이드 버전이 아닌 자바 버전의 아파치 HttpComponents를 이용할 경우에는 POST로의 요청일 경우에도 위의 코드를 넣어줄 경우에는 에러가 발생하지 않는다.
하지만, 안드로이드 애플리케이션에서 다음과 같이 http body 를 넣어줄 수 있는데, 여기서 위의 코드와 같이 Content-Length 를 명시할 경우 ClientProtocolException 이 발생한다.
byte[] httpBody = "Android http body".getByte();
HttpEntity entity = new ByteArrayEntity(httpBody);
HttpGet method = new HttpGet("http://test.wiseant.net/debugger");
method.setHeader("Content-Length", "" + httpBody.length);
05-22 06:40:56.533: WARN/System.err(1030): org.apache.http.client.ClientProtocolException
따라서 실제코드 상에서는 Content-Length 를 명시하는 setHeader 메소드를 사용하지 않아야 한다.
자바 버전의 HttpComponents 를 사용하는 것과 안드로이드의 Http client 컴포넌트를 사용하는 것은 상당 부분 차이가 난다.
흠... 이 버그 찾는데 오후 내도록 찾은 것이니 아깝진 하다... 쩝...^^;;
댓글 3개:
안녕하세요.
http service를 찾다가 이렇게 오게 되었습니다.
제가 웹 서비스 쪽은 잘 몰라서 이렇게 질문을 드립니다.
위에서는 GET 방식을 쓰신거 같은데요.
POST의 경우에는 어떤 식으로 BODY를 정의해 줘야하는 건가요?
Entity에 Body의 값들을 정의 한 후, httpclient 에 setEntity 하면 되는 건가요????
@Netizen - 2009/08/21 14:44
안녕하세요.
위의 예제에서는 ByteArrayEntity 클래스를 사용하였습니다.
생성자로 httpBody 명으로 정의된 byte array 즉, 바이트 버퍼가 주어집니다.
보통 http body와 같은 패키지를 구성할 때 byte array를 이용한 버퍼 단위로 http 패키지를 구성합니다.
즉, 만약 이미지를 http body로 넣고 싶을 때 해당 바이너리 파일과 기타 정보를 byte array에 넣은 후, 위의 ByteArrayEntity 클래스를 생성할 때 넘겨줍니다.
좋은 하루 되세요^^
음 알겠습니다. 한 번 해보겠습니다 ^ ^
댓글 쓰기