아파 치 기반 HttpClient HTTP 네트워크 접근

Android 에 서 는 java.net 패키지 의 API 를 사용 하여 HTTP 서 비 스 를 방문 하 는 것 외 에 도 작업 을 수행 할 수 있 습 니 다.android SDK 에 Apache 의 HttpClient API 가 첨부 되 어 있 습 니 다.Apache HttpClient 는 완벽 한 HTTP 클 라 이언 트 입 니 다.HTTP 프로 토 콜 에 대한 전면적 인 지원 을 제공 합 니 다.HTTP GET 와 POST 를 사용 하여 접근 할 수 있 습 니 다.다음은 인 스 턴 스 를 결합 합 니 다.HttpClient 사용법 소개:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package=""
android:versionCode="1"
android:versionName="1.0">
<application android:icon="@drawable/icon" android:label="@string/app_name">
<!--            -->
<uses-library android:name="android.test.runner"/>
</application>
<!--               -->
<instrumentation android:name="android.test.InstrumentationTestRunner"
android:targetPackage="com.scott.http"/>
<!--   HTTP          -->
<uses-permission android:name="android.permission.INTERNET"/>
<uses-sdk android:minSdkVersion="8" />
</manifest>

그 다음 에 우리 의 단원 테스트 클래스 는 android.test.android TestCase 클래스 를 계승 해 야 합 니 다.이 클래스 자 체 는 Junit.framework.TestCase 를 계승 하고 getContext()방법 을 제공 하여 안 드 로 이 드 상하 문 환경 을 얻 는 데 매우 유용 합 니 다.왜냐하면 많은 안 드 로 이 드 API 는 Context 가 있어 야만 완성 할 수 있 기 때 문 입 니 다.
이제 테스트 용례 를 살 펴 보 겠 습 니 다.HttpTest.java 코드 는 다음 과 같 습 니 다.
4.567913.이 파일 은 세 개의 테스트 사례 를 포함 하기 때문에 하나씩 소개 하 겠 습 니 다.
우선,주의해 야 할 것 은 서버 주 소 를 찾 을 때 IP 를 사 용 했 습 니 다.여기 서 localhost 를 사용 할 수 없 기 때문에 서버 는 windows 에서 실 행 됩 니 다.이 단원 테스트 는 Android 플랫폼 에서 실 행 됩 니 다.localhost 를 사용 하면 Android 내부 에서 서 비 스 를 방문 하 는 것 을 의미 합 니 다.접근 할 수 없 을 수도 있 으 므 로 IP 로 서 비 스 를 찾 아야 합 니 다.
먼저 testGet 테스트 용례 를 분석 해 보 겠 습 니 다.HttpGet 을 사 용 했 습 니 다.요청 매개 변 수 는 URL 뒤에 직접 붙 인 다음 HttpClient 에서 GET 요청 을 수행 합 니 다.응답 이 성공 하면 입력 흐름 과 같은 응답 을 얻 고 문자열 로 변환 하여 GET 인지 여 부 를 판단 합 니 다.SUCCESS.
testGet 테스트 에 대응 하 는 서버 Servlet 코드 는 다음 과 같 습 니 다.
4.567913.그리고 test Post 테스트 사례 를 다시 말 합 니 다.저 희 는 HttpPost 를 사 용 했 습 니 다.URL 뒤에 매개 변수 정보 가 첨부 되 어 있 지 않 습 니 다.매개 변수 정 보 는 NameValuePair 형식 으로 구 성 된 집합 형식 으로 포장 되 었 고 UrlEncodedFormEntity 처 리 를 거 친 후에 HttpPost 의 setEntity 방법 으로 매개 변 수 를 설정 한 다음 에 HttpClient 에서 실 행 됩 니 다.
test Post 테스트 에 대응 하 는 서버 코드 는 다음 과 같 습 니 다.
public class HttpTest extends AndroidTestCase {
	private static final String PATH = "http://192.168.1.57:8080/web";

	public void testGet() throws Exception {
		HttpClient client = new DefaultHttpClient();
		HttpGet get = new HttpGet(PATH
				+ "/TestServlet?id=1001&name=john&age=60");
		HttpResponse response = client.execute(get);
		if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
			InputStream is = response.getEntity().getContent();
			String result = inStream2String(is);
			Assert.assertEquals(result, "GET_SUCCESS");
		}
	}

	public void testPost() throws Exception {
		HttpClient client = new DefaultHttpClient();
		HttpPost post = new HttpPost(PATH + "/TestServlet");
		List<NameValuePair> params = new ArrayList<NameValuePair>();
		params.add(new BasicNameValuePair("id", "1001"));
		params.add(new BasicNameValuePair("name", "john"));
		params.add(new BasicNameValuePair("age", "60"));
		HttpEntity formEntity = new UrlEncodedFormEntity(params);
		post.setEntity(formEntity);
		HttpResponse response = client.execute(post);
		if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
			InputStream is = response.getEntity().getContent();
			String result = inStream2String(is);
			Assert.assertEquals(result, "POST_SUCCESS");
		}
	}

	public void testUpload() throws Exception {
		InputStream is = getContext().getAssets().open("books.xml");
		HttpClient client = new DefaultHttpClient();
		HttpPost post = new HttpPost(PATH + "/UploadServlet");
		InputStreamBody isb = new InputStreamBody(is, "books.xml");
		MultipartEntity multipartEntity = new MultipartEntity();
		multipartEntity.addPart("file", isb);
		multipartEntity.addPart("desc", new StringBody("this is description."));
		post.setEntity(multipartEntity);
		HttpResponse response = client.execute(post);
		if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
			is = response.getEntity().getContent();
			String result = inStream2String(is);
			Assert.assertEquals(result, "UPLOAD_SUCCESS");
		}
	}

	//           
	private String inStream2String(InputStream is) throws Exception {
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		byte[] buf = new byte[1024];
		int len = -1;
		while ((len = is.read(buf)) != -1) {
			baos.write(buf, 0, len);
		}
		return new String(baos.toByteArray());
	}
}
위의 두 가 지 는 가장 기본 적 인 GET 요청 과 POST 요청 입 니 다.매개 변 수 는 모두 텍스트 데이터 형식 으로 일반적인 수 요 를 만족 시 킬 수 있 습 니 다.그러나 어떤 경우 에 예 를 들 어 우리 가 파일 을 업로드 할 때 기본 적 인 GET 요청 과 POST 요청 을 사용 할 수 없습니다.우 리 는 여러 위 젯 의 POST 요청 을 사용 해 야 합 니 다.다 중 위 젯 POST 작업 을 통 해 서버 에 파일 을 업로드 하 는 방법 을 소개 한다.
Android 에 첨부 된 HttpClient 버 전 은 다 중 위 젯 POST 요청 을 지원 하지 않 기 때문에 HttpMime 오픈 소스 프로젝트 를 사용 해 야 합 니 다.이 구성 요 소 는 MIME 형식 과 관련 된 작업 을 전문 적 으로 처리 합 니 다.Http Mime 은 Http Components 프로젝트 에 포함 되 어 있 기 때문에 우 리 는 apache 공식 사이트 에 가서 Http Components 를 다운로드 한 다음 에 그 중의 Http Mime.jar 가방 을 프로젝트 에 넣 어야 합 니 다.
그 다음 에 testUpload 테스트 사례 를 살 펴 보 겠 습 니 다.저 희 는 HttpMime 에서 제공 하 는 InputStreamBody 로 파일 흐름 파 라 메 터 를 처리 하고 StringBody 로 일반 텍스트 파 라 메 터 를 처리 하 며 마지막 으로 모든 유형의 파 라 메 터 를 MultipartEntity 의 인 스 턴 스 에 추가 하고 이 multipartEntity 를 이번 POST 가 요청 한 매개 변수 실체 로 설정 한 다음 에 POST 요청 을 수행 합 니 다.서버 Servlet 코드 는 다음 과 같 습 니 다.
@Override
protected void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {
        System.out.println("doGet method is called.");
	String id = request.getParameter("id");
	String name = request.getParameter("name");
	String age = request.getParameter("age");
	System.out.println("id:" + id + ", name:" + name + ", age:" + age);
	response.getWriter().write("GET_SUCCESS");
}
서버 에서 apache 오픈 소스 프로젝트 FileUpload 를 사용 하여 처리 하기 때문에 comons-fileupload 와 comons-io 두 프로젝트 의 jar 패키지 가 필요 합 니 다.
위의 세 가지 다른 상황 을 소개 한 후에 우 리 는 하나의 문 제 를 고려 해 야 한다.실제 응용 에서 우 리 는 매번 HttpClient 를 새로 만 들 수 없고 전체 응용 프로그램 에 만 HttpClient 를 만 들 고 모든 HTTP 통신 에 사용 해 야 한다.또한,또한 하나의 HttpClient 를 통 해 여러 요청 을 동시에 보 낼 때 발생 할 수 있 는 다 중 스 레 드 문제 도 주의해 야 합 니 다.이 두 가지 문제 에 대해 우 리 는 우리 의 프로젝트 를 개선 해 야 합 니 다.
1.시스템 의 기본 애플 리 케 이 션 을 확장 하고 프로젝트 에 적용 합 니 다.
2.HttpClient 라 이브 러 리 에서 제공 하 는 ThreadSafeClient Manager 를 사용 하여 HttpClient 를 만 들 고 관리 합 니 다.
그 중에서 MyApplication 은 시스템 의 Application 을 확 장 했 습 니 다.코드 는 다음 과 같 습 니 다.
@Override
protected void doPost(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {
	System.out.println("doPost method is called.");
	String id = request.getParameter("id");
	String name = request.getParameter("name");
	String age = request.getParameter("age");
	System.out.println("id:" + id + ", name:" + name + ", age:" + age);
	response.getWriter().write("POST_SUCCESS");
}
우 리 는 onCreate()방법 을 다시 썼 고 시스템 이 시 작 될 때 HttpClient 를 만 들 었 습 니 다.onLowMemory()와 onTerminate()방법 을 다시 썼 습 니 다.메모리 부족 과 응용 이 끝 날 때 연결 을 닫 고 자원 을 방출 합 니 다.주의해 야 할 것 은 DefaultHttpClient 를 예화 할 때 ThreadSafeClient ConnManager 가 만 든 Client Connection Manager 의 실제 예 를 들 어 HttpClient 의 HTTP 연결 을 관리 하 는 것 입 니 다.
그리고 이 강화 판 의"Application"을 적용 하려 면 AndroidManifest.xml 에서 다음 과 같은 설정 을 해 야 합 니 다.
4.567913.만약 에 우리 가 설정 하지 않 으 면 시스템 은 기본적으로 android.app.application 을 사용 합 니 다.우 리 는 설정 을 추 가 했 습 니 다.시스템 은 우리 의 com.scott.http.MyApplication 을 사용 한 다음 에 context 에서 getApplication()을 호출 하여 MyApplication 인 스 턴 스 를 가 져 올 수 있 습 니 다.
위의 설정 이 있 으 면 이벤트 에 사용 할 수 있 습 니 다.HttpActivity.java 코드 는 다음 과 같 습 니 다.
@SuppressWarnings("serial")
public class UploadServlet extends HttpServlet {
	@Override
	@SuppressWarnings("rawtypes")
	protected void doPost(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		boolean isMultipart = ServletFileUpload.isMultipartContent(request);
		if (isMultipart) {
			FileItemFactory factory = new DiskFileItemFactory();
			ServletFileUpload upload = new ServletFileUpload(factory);
			try {
				List items = upload.parseRequest(request);
				Iterator iter = items.iterator();
				while (iter.hasNext()) {
					FileItem item = (FileItem) iter.next();
					if (item.isFormField()) {
						//         
						String paramName = item.getFieldName();
						String paramValue = item.getString();
						System.out.println(paramName + ":" + paramValue);
					} else {
						//         
						String fileName = item.getName();
						byte[] data = item.get();
						String filePath = getServletContext().getRealPath(
								"/files")
								+ "/" + fileName;
						FileOutputStream fos = new FileOutputStream(filePath);
						fos.write(data);
						fos.close();
					}
				}
			} catch (FileUploadException e) {
				e.printStackTrace();
			}
		}
		response.getWriter().write("UPLOAD_SUCCESS");
	}
}

좋은 웹페이지 즐겨찾기