2015. 4. 24. 16:55

public String getMcodeFromMLB() {
HttpURLConnection uc = null; // 연결용 커넥션
URL url = null;
String sUrl = "http://localhost:8080/MLBServerTest/MLBTest.jsp"; // 연결할 주소
String result = "";

try {

url = new URL(sUrl);

uc = (HttpURLConnection) url.openConnection();

uc.setDoInput(true);
uc.setDoOutput(true);
uc.setUseCaches(false);
uc.setRequestMethod("POST");
uc.setConnectTimeout(10000); // 커넥션 타임아웃
uc.setAllowUserInteraction(true);

// Http Header Setting
uc.setRequestProperty("Content-type", "application/x-www-form-urlencoded;charset=euc-kr");

// Http Parameter Sending
String partner_id = "O00128"; // CP의 파트너ID
String service_code = "001"; // 각 CP서버에 할당된 코드
String music_code = "00293876"; // MLB에서 조회된 MUSIC_CODE
String content_price = "800"; // 컨텐츠 단가
String content_name = "핑계"; // 컨텐츠가 서비스되는 이름
String content_num = "1"; // 패키지에 포함한 컨텐츠의 갯수. 단일상품일 경우 1, 복합상품일 경우 2이상
String pid = "3102306023"; // PID
String sub_code = "12700000012"; // CP서버가 자체적으로 관리하는 Code(SCID등). 12자리 이하
String carrier_code = "00"; // ASP에 서비스하는 캐리어를 구분하기 위한 구분코드

StringBuffer sb = new StringBuffer();
sb.append(MLBConstants.MCODE_REQUEST_PARTNER_ID).append("=").append(partner_id).append("&");
sb.append(MLBConstants.MCODE_REQUEST_SERVICE_CODE).append("=").append(service_code).append("&");
sb.append(MLBConstants.MCODE_REQUEST_MUSIC_CODE).append("=").append(music_code).append("&");
sb.append(MLBConstants.MCODE_REQUEST_CONTENT_PRICE).append("=").append(content_price).append("&");
sb.append(MLBConstants.MCODE_REQUEST_CONTENT_NAME).append("=").append(content_name).append("&");
sb.append(MLBConstants.MCODE_REQUEST_CONTENT_NUM).append("=").append(content_num).append("&");
sb.append(MLBConstants.MCODE_REQUEST_PID).append("=").append(pid).append("&");
sb.append(MLBConstants.MCODE_REQUEST_SUB_CODE).append("=").append(sub_code).append("&");
sb.append(MLBConstants.MCODE_REQUEST_CARRIER_CODE).append("=").append(carrier_code);

PrintWriter pw = new PrintWriter(new OutputStreamWriter(uc.getOutputStream(), "euc-kr"));
pw.write(sb.toString());
pw.flush();


int resCode = 0; // RMS 와의 연결 응답값
resCode = uc.getResponseCode();

StringBuffer resp = new StringBuffer();
if(resCode < 400){ // 연결이 성공적일때

String line;
BufferedReader br = new BufferedReader(new InputStreamReader(uc.getInputStream(), "euc-kr"));
while ((line = br.readLine()) != null) {
System.out.println(line);
resp.append(line);
}

pw.close();
br.close();

// html 파싱
result = getResultCode(resp.toString());
result = (result.equals("OK")) ? result : "MLB연동 중 에러 발생 : " + getResultCode(resp.toString());
}
else{
result = "MLB연동 중 에러 발생 : " + resCode + " 에러입니다.";
}

} catch (IOException e) {
e.printStackTrace();
}
catch(Exception e) {
e.printStackTrace();
}

return result;
}

넘기고 받을 때 euc-kr로 변환하는 것도 주목.

http://lonelycat.tistory.com/314

'ApplicationPrograming > Java' 카테고리의 다른 글

자바 암호화  (0) 2015.02.25
Commons-Fileupload의 한글관련 문제 추가  (0) 2013.03.15
Commons-DbUtils  (0) 2013.03.15
Commons-Fileupload의 한글관련 문제 추가  (0) 2013.03.15
JDOM  (0) 2013.01.31
Posted by 물색없는세상
2015. 4. 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. 4. 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 물색없는세상