최종수정 - 2013/11/05
1. 간략하게 JSON 알기
JSON 데이터형식은 Java Script Object Notation을 뜻합니다.
JSON은 원래 Java Script에서 사용하던 간단한 데이터에 특화된, 즉 경량의 데이터를
주고 받는데 효과적인 데이터 형식을 말하죠. 웹 언어에서 사용하는 목적이다보니 가벼운 것이
장점입니다. 그리고 구조또한 사람이 알아보기 쉽운 구조입니다.
자세한 내용은 JSON 공식 홈페이지에서 확인해보세요!
이제 본격적으로 JSON에 대해 알아보도록 해봅시다.
(아마 지금 이 페이지를 보시는 분들이라면 JSON을 어떻게 사용해야할지 모르는
분들, 혹은 이게 대체 무슨 원리로 왔다갔다 하는지 모르겠는 분들을 위해서
잠시 설명하고 넘어가겠습니다.
2. 안드로이드-> JSP
안드로이드 -> 서버(JSP) 로 데이터를 넘길 때는 정말 보편적인 방법으로 보낼 겁니다.
즉, 마치 보통 HTML에서 Form 방식의 post방식이나 get방식을 이용할 때 쓰는 방법인
경로 뒤에 마구마구 붙이기 방식입니다.
보통 우리는 ~~.jsp?id=value&pwd=1234 라고 해서 보내죠.
바로 이 방식! 물음표 뒤에 변수=값&변수=값&변수=값의 형태인 이것과 유사하게
보낼 겁니다(JSP를 모르신다면 OTL). 아니 거의 같다고 봐도 될 것 같습니다.
물론 이 방식은 get 방식일 때 이야기입니다.
보낼 때도 JSON으로 보내는 방법이 있다고는 알고 있습니다만... 아직은 탐구하지 못한 영역입니다.
그래서 데이터를 get방식으로 넘기는 거에요 ㅠㅠ
그렇다면 JSON은 언제쓰냐? 제가 이 실습에서 사용한 방식은 서버(JSP)에서 안드로이드로 데이터를 보낼 때 사용하였습니다.
이 JSON이란 친구가 객체화 된 데이터 혹은 키:값 형식(Map이라고도 하죠)을 보내는데 아주 특화가 되었거든요. 그것에 관해서는
조금 있다가 더 살펴보겠습니다.
그럼 이제부터 본론으로 들어가보도록 하겠습니다.
먼저 살펴볼 것은 안드로이드에서 서버로 데이터 넘기기입니다.
3. 안드로이드 -> 서버로 데이터 넘기기
먼저 JSP서버에서 사용할 JSON SIMPLE 이란 라이브러리를 다운 받아
사용하는 JSP 로컬 안에 WEB-INF 안에 짚어 넣습니다. 이 녀석이 하는 역활은
보통 JSON 보다 훨씬 쉽고 가볍게 사용 할 수 있게 해주는 친구입니다.
만약 JSP 서버를 아직 외부 접근을 허용하지 않았다면,
또는 아직 웹서버의 외부접근을 모르신다면 여길 참고하세요.
보내는 내용은 정말 간단합니다. 안드로이드에서의 예제를 한 번 아래 내용을 통해서 보죠.
try { HttpClient client = new DefaultHttpClient(); // 보낼 객체 만들기 final String URL = "0.0.0.0:8080/JsonTest.jsp"; // 주소 String simpleData = "?json=OK&really=CanDoThis"; // 보낼 데이터 HttpPost post = new HttpPost(URL+simpleData); // 주소 뒤에 데이터를 넣기 client.execute(post); // 데이터 보내기 } catch (IOException e) { e.printStackTrace(); }
위의 예제가 뭘 하는 건지 잘 감이 안 오신다면 우리가 외국에 놀러가서 관광용 엽서를 통해
친구에게 편지를 보내는 것에 허접하게 비유를 해보겠습니다.
"여행을 가서 어쩌다 관광샵에 들러 엽서(HttpClient)를 사게 되었습니다.
이 엽서는 앞장엔 주소를 적는 '주소란(HttpPost)'과 뒷 장엔 간략히 몇 마디 쓸 수 있는 엽서였습니다.
엽서는 구했고, 이제 주소를 적을 차례입니다. 친구의 '주소(URL)'는 알고 있구요. 주소를 주소란에 적고 난 뒤(new HttpPost())
이제 내용을 뒤에다 간략하게 몇 마디만 남깁니다(simpleData). 그리고 완성 된 엽서를 우체통에다 갔다 넣었습니다(client.execute(post))."
0.0.0.0은 자기 자신의 IP를 넣으시면 되겠구요.
저렇게 간단하게 데이터를 주었으면 서버에서는 이걸 받게 될 겁니다.
그 부분은 아래를 보도록 하죠.
<%@ page language="java" contentType="text/html; charset=EUC-KR" pageEncoding="EUC-KR"%> <%@ page import="org.json.simple.JSONObject"%> <%@ page import="org.json.simple.JSONArray"%> <% // 호출되면서 넘어온 값 받기 String[] getAndroidData = {"", ""}; getAndroidData[0] = request.getParameter("hey"); getAndroidData[1] = request.getParameter("really"); %>
먼저 디렉티브에 위에서 받은 JSON Simple 라이브러리를 Import 시키구요.
다음으로 일반적으로 데이터를 받아오듯 Request 객체의 getPArameter 메소드를
이용하여 받아옵니다. 위에 예제에선 단순히 받는 것만을 보여주느냐고 JSON은 아직 사용하진 않았습니다.
이제 안드로이드에서 서버로 데이터를 넘기는 걸 모두 보았으니
마지막으로 서버에서 안드로이드로 데이터를 넘기는 것을 보겠습니다.
PS - 3번 내용에서는 get방식으로 보냄에도 불구하고, Post객체를 쓰는 중대한 문법적 이슈가 있습니다.
이 부분은 제가 시간상 고치기는 어려울 것 같네요. 올바른 방식으로 쓰는 법을 아신다면 답글로 조언해주신다면 감사하겠습니다!!
4. **서버 -> 안드로이드로 데이터 넘기기**
위에선 서버의 디렉티브와 데이터를 받아오는 부분까지를 보여드렸습니다.
이번엔 서버에서 받은 데이터를 안드로이드로 넘기는 부분인데요. 한번 보고 자세히 설명하겠습니다.
// JSON 형태로 출력 원하는 값 출력 JSONObject jsonMain = new JSONObject(); // 객체 JSONArray jArray = new JSONArray(); // 배열 JSONObject jObject = new JSONObject(); // JSON내용을 담을 객체. jObject.put("hey", "you_SUCK!!!!"); jObject.put("really", getAndroidData[0] + getAndroidData[1]); jArray.add(0, jObject); jsonMain.put("dataSend", jArray); // JSON의 제목 지정 out.println(jsonMain); out.flush(); %>
위에 내용을 보면 JSONObject 하고 JSONArray가 나오고 뭘 add하고 put하고 있습니다.
그럼 찬찬히 이것들의 의미를 살펴보겠습니다.
우선은 이것의 결과값을 한번 보고 시작하죠. 이 내용이 수행 됬을 때 내용은 다음과 같습니다.
{"dataSend":
[
{"really":"IOKFunThis","hey":"you_SUCK!!!!"}
]
}
왠지 익숙하지 않나요? 마치 XML을 사용할 때와 비슷하게 보입니다!
"dataSend" 는 이 JSON 데이터의 이름을 의미합니다. 대괄호[] 는 여러 JSON 객체를 보내는 집합소이구요.
그 안의 중괄호{} 는 JSON 객체안의 데이터를 의미합니다. 데이터들은 "변수" : "값" 으로서 나눠집니다.
좀 더 응용해서 생각해볼까요? 여러개의 JSON 객체를 보낼 땐 다음과 같을 겁니다.
{"dataSend":
[
{"really":"IOKFunThis","hey":"you_SUCK!!!!"},
{"really":"IOKFunThis","hey":"you_SUCK!!!!"},
{"really":"IOKFunThis","hey":"you_SUCK!!!!"}
]
}
위와 같이 우리가 폼을 만들어서 보내도 되지만, 정말 수고스럽겠죠? 그래서 이러한 폼을 자동으로
만들어주는 것이, JSONObject와 JSONArray 입니다. 이제 위의 예제를 대입해서 이야기하자면
JsonMain이 "dataSend"이고, jArray가 대괄호[]를 의미하며, 또 다른 jObject는 대괄호
안의 내용물을 완성시켜줍니다.
↑ 이 부분도 미숙한 저의 능력으로 인해 올바르게 사용하지는 못했습니다. 객체지향적인 관점으로 본다면
굳이 저렇게 할 필요가 없죠. 이 부분도 한번 고민해보세요.(2013/11/05)
이걸 그림으로 보도록 하죠.
이해 되시나요? 개념적으로 봤을 때 큰 JsonObject안에 JsonArray를 통해 여러개의 오브젝트를
넣을 수 있게 해주는 것입니다. 위에서 보여드린 예제는 jArray 하나만 가지고 있기 때문에 여러개를
포함 할 수 있다는 뜻으로 하나를 더 넣어봤습니다. 그 점을 유념하시면 됩니다.
이러한 방식의 JSON 폼을 만드는 법에 대한 자세한 예제는 여기에서 확인 할 수 있습니다.
마지막으로 이렇게 만들어진 폼을 최종적으로 보내는 과정이 바로 out.println(jsonMain); 과
out.flush(); 입니다. 흔히들 println만 하면 출력이 되는 것으로 아는 분들이 있는데, 그건 버퍼의 개념을
아직 잘 모르는 거죠. 버퍼를 밀어줘야 보내줄 수 있습니다. 그 밀어주는 역활이 out.flush(); 입니다.
(굳이 out.flush()를 쓰지않아도 잘 갑니다)
이렇게 하고나면 폰에서 그 내용을 받아와야겠죠? 그 부분을 한번 보도록 하겠습니다.
try { HttpResponse response = client.execute(post); // 보낸 뒤, 리턴 되는 결과값을 받음 /* 위에 까진 안드로이드에서 보내기, 밑에서 부터는 서버에서 보낸 데이터 받기 */ BufferedReader bufreader = new BufferedReader( new InputStreamReader( response.getEntity().getContent(), "utf-8")); String line = null; String page = ""; // 버퍼의 웹문서 소스를 줄 단위로 읽어(line), page에 저장함 while ((line = bufreader.readLine()) != null) { page += line; } // 읽어들인 내용을 json 객체에 담아 그 중 dataSend로 정의 된 내용을 // 불어온다. 그럼 json 중 원하는 내용을 하나의 json 배열에 담게 된다. JSONObject json = new JSONObject(page); JSONArray jArr = json.getJSONArray("dataSend"); // JSON이 가진 크기만큼 데이터를 받아옴 for (int i = 0; i < jArr.length(); i++) { json = jArr.getJSONObject(i); getJsonData[0] = json.getString("hey"); getJsonData[1] = json.getString("really"); } /* 여기까지 서버가 보낸 데이터를 받아 왔다. 밑에는 확인을 위한 수행 */ String data = "받은 데이터 : " + getJsonData[0] + " " + getJsonData[1]; setTextView(data); } catch (Exception e) { e.printStackTrace(); }
자, 드디어 마지막 내용을 설명드릴 때가 왔군요.
상대방이 JSON의 형태로 보낸다면 안드로이드는 그걸 풀어서 이해를 해야합니다.
잘 포장해서 보낸 내용물을 풀어야 하는 것과 같죠. 그러기 위해선 일단 잘잘히 잘려서 오는
네트워크의 특성상 while문으로 들어온 내용을 모조리 하나의 String에 붙여 넣는 작업이 필요합니다.
그 이후에는 우리가 JSON 객체를 서버에서 만들었던 과정을 반대로 풀어내는 것이지요.
편의상 위에 쓰인 참조변수 이름을 사용해서 설명하겠습니다.
json에 모조리 더한 String인 page를 넣어주고, 거기서 "dataSend"라는 이름의 JSONArray를 찾아서
jArr에 넣어줍니다. 그리고 그 밑에 for문에 도달하게 되죠. 받는 이의 입장에서는 이 데이터가 단 하나일지
수 만개의 jObject를 포함하고 있을지 모르기 때문에 for문을 이용하게 됩니다. 그리고 JSONObject로 잘
포장 된 각각의 변수와 값을 변수의 이름으로 뽑아오는 거죠. 그 부분이 바로
getJsonData[0] = json.getString("hey");
입니다.
그럼 우리는 성공적으로 데이터를 보내고 받게 된 겁니다.
5. 마치며
이렇게 허섭스럽게 개념과 사용 방법을 알아 보았는데요.
대강의 이해를 목적으로 만들어진 것이기에-아니 설명을 나중에 덧붙이고 다듬기 위한 초안이기 때문에
모자란 부분이 많습니다. 그래서 이해 안되시는 부분은 꼭 답글이나 메일로 보내주세요. 그럼 바로 업데이트
하겠습니다.
그리고 제가 링크 걸어둔 사이트는 그 내용들을 잘 이해할 수 있는 곳인데요. 추가적으로 이해하기엔
더할 나위 없이 좋은 곳입니다. 참고하셔서 공부하시기 바랍니다^^ - 2013/06/13
이 글을 많은 분들이 보시는 데에 비해 부족한 글이란 생각이 들어 긴급하게 수정은 했습니다. 그렇지만
많이 부족한 부분들이 보이네요... 그래도 가볍게 이해하는 데에는 큰 문제는 없으실 거라 생각합니다.
앞으로 이 분야를 직업으로 삼을 일이 없을 거 같기에 더 자세한 블로깅은 못할 것 같아 죄송합니다.
- 2013/11/05
'Android' 카테고리의 다른 글
화면 고정하기 (0) | 2013.01.14 |
---|---|
비트맵Bitmap을 이용한 썸네일/축소와 회전 (0) | 2013.01.14 |
에디트텍스트 EditText 입력글자 제한하기 (0) | 2013.01.14 |
안드로이드 HttpClient / HttpPost를 이용한 톰캣 / JSP 연결 (2) | 2013.01.14 |
Multipart를 이용한 데이터 주고받기 - 안드로이드에서 서버로 보내기 - (14) | 2013.01.14 |
WRITTEN BY