2015.04.23 18:14

HttpURLConnection을 이용해서 통신프로그램을 작성하던중... POST방식을 네이버 검색해보니 일부 블로그에서
파라미터를 아래와 같은 방식 처리하는 예제가 있었다.

String param = "xx="+xx+"&xxx="+xxx+"&xxxx="+xxxx;

URL targetURL = new URL(http://xxx.xxx.xxx.xxx/xxx/xxx.html);


... 중략 ...

PrintWriter out =

new PrintWriter(hurlc.getOutputStream());

out.println(param);

out.flush();

out.close();


해본 결과 PrintWriter 쓰면 안된다. (이것 때문에 또 삽질을....역시 네이버는 너무 믿으면 안된다 ㅡ_ㅡ;;;)
구글링을 해본결과 아래와 같이 OutputStream을 써야한다.

String param = "xx="+xx+"&xxx="+xxx+"&xxxx="+xxxx;

URL targetURL = new URL(http://xxx.xxx.xxx.xxx/xxx/xxx.xxx);

URLConnection urlConn = targetURL.openConnection();

HttpURLConnection hurlc = (HttpURLConnection) urlConn;

// 헤더값을 설정한다.

hurlc.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
// 전달 방식을 설정한다. POST or GET, 기본값은 GET 이다.
hurlc.setRequestMethod(
"POST");
// 서버로 데이터를 전송할 수 있도록 한다. GET방식이면 사용될 일이 없으나, true로
// 설정하면 자동으로 POST로 설정된다. 기본값은 false이다.

hurlc.setDoOutput(
true);
// 서버로부터 메세지를 받을 수 있도록 한다. 기본값은 true이다.
hurlc.setDoInput(
true);
hurlc.setUseCaches(
false);

hurlc.setDefaultUseCaches(false);


//안됨...

//PrintWriter out = new PrintWriter(hurlc.getOutputStream());

//out.println(param);

//out.flush();

//out.close();

OutputStream opstrm = hurlc.getOutputStream();

opstrm.write(param.getBytes());

opstrm.flush();

opstrm.close();

String buffer = null;

BufferedReader in =

new BufferedReader(new InputStreamReader
(hurlc.getInputStream()));

while ((buffer = in.readLine()) != null) {

ecgResultXML += buffer;

}

in.close();

 

http://everlikemorning.tistory.com/47

Posted by 물색없는세상
2015.04.23 18:14

안드로이드에서 HTTP 연결은 다음 두 가지 방법 중 하나를 통해 구현할 수 있다.

첫번째 방법은 HttpClient 클래스 혹은 이 클래스의 하위 클래스들(AbstractHttpClient, AndroidHttpClient, DefaultHttpClient)을 이용하는 방법이다. 하지만 이 클래스를 이용하는 방법은 간단하기는 성능이 다소 떨어지고 ICS 이상의 버전에서는 많은 버그를 내포하고 있어 프로요나 진저브래드 버전에서 동작하는 어플리케이션을 구현할 때 적합하다.

두번째 방법은 HttpURLConnection 클래스를 이용하는 방법이다. 이 클래스를 이용하면 처음에 구현이 다소 까다롭기는 하나 더 효율적이고 유연하고 가볍게 동작하며 ICS 이상의 버전에서도 문제없이 작동하는 어플리케이션을 만들 수 있다.

또 허니콤 이상의 버전에서 HTTP 연결을 구현하고자 할 때에는 메인 액티비티에서 구현할 경우 StrictMode$AndroidBlockGuardPolicy.onNetwork 에러가 발생한다. 따라서 별로의 스레드를 구성하여 HTTP 연결을 구현하야 한다.


이 글에서는 허니콤 버전의 환경에서 HttpURLConnection 클래스를 사용하여 스레드를 통해 HTTP 연결을 하고 POST 메세지를 웹 서버로 전송하는 방법을 다루고자 한다.

디바이스 외의 장치와 서로 상호작용하는 HTTP 네트워킹의 경우에는 항상 예측하지 못한 딜레이를 야기할 수 있다. 따라서 메인 액티비티(혹은 UI 스레드) 외에 별로의 스레드에서 HTTP 동작을 수행하는 것이 올바른 구현이다. AsyncTask 클래스는 메인 액티비티와 별도의 스레드를 구현하기 위한 간단한 방법 중 하나다.

AsyncTask는 짧은 기간 동안만 동작하는 스레드를 구현하는데 최적화되어 있다. 따라서 지금과 같이 잠시 POST를 하는 등의 동작에는 적합하지만 오랜 시간 동안 백그라운드에서 HTTP 연결을 유지하기에는 적합하지 않다.

우선 AsyncTask를 상속받는 HttpConnectionThread 라는 클래스를 메인 액비티비 클래스의 내부 클래스로 정의한다.(메인 클래스의 내부 클래스로 정의해야 UI 요소에 접근하기가 용의하다.) AsyncTask 내의 메소드 중 doInBackground() 메소드는 백그라운드에서 HTTP 연결에 실제하는 부분이 동작되고, onPostExecute() 메소드는 HTTP 웹 서버로 부터 받아온 정보 등을 UI에 전달하기 위해 사용된다.

public class HttpConnectionThread extends AsyncTask<String, Void, String> {
@Override
protected String doInBackground(String... url) {
// URL 연결이 구현될 부분
return null;
}
@Override
protected void onPostExecute(String result) {
// UI 업데이트가 구현될 부분
}
}

먼저 doInBackground() 내부에 HTTP 연결을 하고 POST 메세지를 전송하는 구현을 해보자. 우선 연결할 URL 주소를 파라미터로부터 받아와 URL 클래스 인스턴스를 이용하여 입력한 후에, 그 외 연결에 필요한 기본적인 설정을 해준다. 요청 방식은 “POST”로 지정하고 connect() 메소드를 호출하면 POST 메세지가 전송된다. 전송의 결과를 response라는 String 객체를 통해 전달 받은 후 반환해 주면, 이후 구현될 onPostExecute() 메소드에서 활용할 수 있다.

@Override
protected String doInBackground(String... url) {
URL url;
String response = null;
try {
url = new URL(url);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(10000 /* milliseconds */);
conn.setConnectTimeout(15000 /* milliseconds */);
conn.setRequestMethod("POST");
conn.setDoInput(true);
conn.connect();
response = conn.getResponseMessage();
Log.d("RESPONSE", "The response is: " + response);
}
catch (IOException e) {
}
return response;
}

위의 doInBackground() 결과로 반환했던 String 객체가 onPostExecute() 메소드의 result라는 String 객체 파라미터로 들어온다. 이 파라미터를 이용하여 토스트 메세지를 띄워 웹 서버로부터 받은 응답 메세지를 확인할 수 있다.

@Override
protected void onPostExecute(String result) {
Toast.makeText(getApplicationContext(), result, Toast.LENGTH_SHORT).show();
}

이렇게 구현한 HttpConnectionThread 라는 이름의 내부 클래스를 메인 액티비티의 필요한 곳에서 new 생성자를 이용해 생성한 후 excute() 메소드를 통해 url을 넘겨 실행해주면 된다. 아래 예제에서는 리스트의 특정 아이템을 선택했을 때 실행되는 onListItemClick()이라는 메소드 내부에 구현하였다.

@Override
public void onListItemClick(ListView l, View v, int position, long id) {
// Thread for Http connection
new HttpConnectionThread.excute("http://http://dontsdondone.esy.es/");
}

 

 

http://dontsdondone.esy.es/archives/90

 

Posted by 물색없는세상
2015.04.23 18:11

import java.io.*;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;

public class URLConnectionPOST {
public static void main(String[] args) {
try {
// Construct data
String data = URLEncoder.encode("key1", "UTF-8") + "=" + URLEncoder.encode("value1", "UTF-8");
data += "&" + URLEncoder.encode("key2", "UTF-8") + "=" + URLEncoder.encode("홍길동", "UTF-8");

// Send data
URL url = new URL("http://localhost:80/TestWeb/sample.jsp");
URLConnection conn = url.openConnection();
// If you invoke the method setDoOutput(true) on the URLConnection, it will always use the POST method.
conn.setDoOutput(true);
OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
wr.write(data);
wr.flush();

// Get the response
BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream(),"UTF-8"));
String line;
while ((line = rd.readLine()) != null) {
System.out.println(line);
}
wr.close();
rd.close();
}
catch (Exception e) {
}
}
}


 

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title></title>
</head>
<body>
<%
//request.setCharacterEncoding("UTF-8");
String value1 = request.getParameter("key1");
String value2 = request.getParameter("key2");

out.println("This is server response.");
out.println("key1="+value1);
out.println("key2="+value2);
%>
</body>
</html>


URLConnectionPOST.java를 컴파일하고 위의 sample.jsp 를 포함한 Tomcat을 기동한 후에 URLConnectionPOST를 실행하면 다음과 같은 결과를 확인할 수 있다.

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title></title>
</head>
<body>
This is server response.
key1=value1
key2=홍길동
</body>
</html>

 

http://micropilot.tistory.com/290

Posted by 물색없는세상