[AsyncTask] 안드로이드에 서버(JSP,PHP) JSON 데이터 가져오기
◆ 기존방식
- JSP에서 out.println() 방식으로 html 에 뿌려준 후 가져오는방식
- Android Source Code 에서 AsynTask를 파라미터를 사용 안했었음.
전역변수로 onPostExecute 부분에서 대충 코딩함
◆ 변경
- JSON을 적용!
- Android Source Code 에서 AsyncTask 를 좀 더 활용하도록 공부
라이프사이클을 고려한 생성~완료단계까지 모두 구현
new A.execute(); -> doInBackground(); -> onPostExecute();
- 백그라운드 Asynctask 는 아래 링크를 통해 쉽게 이해가능하십니다.
◆ 개념
- Android Studio -> JSP(SQL) -> DB -> JSP(JSON) -> Android Studio
순서로 키값을 먼저 보낸 후! JSP에서 해당 키값을 파라미터로 받아 DB에서 SELECT 조회후
JSON으로 Android Studio에 다시 보내주는 순서로 구현을 하였습니다.
1. 서버로 키값 보내기 (Android)
원하는 값을 서버DB에서 찾아서 가져오려면 해당 값에 대한 고유 식별값(기본키) 하나쯤을 보내줍니다.
가. 호출부 (BackgroundService - 제가 본 기능을 호출하려고 설정 서비스부분입니다.)
- 저는 서비스(백그라운드 핸들러)에서 10초마다 체킹을 해야하는 기능을 구현하기 위하여
백그라운드 핸들러 안에 호출부를 셋팅하였습니다.
- 본인이 원하는 클래스에서 B 클래스를 생성합니다.
new Time_Check(context);
private class myServiceHandler extends Handler {
@Override
public void handleMessage(Message msg) {
new Time_Check(context);
super.handleMessage(msg);
}
}
나. 수신부 (Time_Check.class > AsyncTask > doInBackground)
@Override
protected String doInBackground(String... serialkey) {
String get_serialkey = serialkey[0];
String get_json = "";
try {
String urlAddr = "https://Host/dir1/dir2/dir2/A.jsp?&Serial_key=" + get_serialkey;
Log.d(TAG, urlAddr);
URL url = new URL(urlAddr);
HttpURLConnection conn = (HttpURLConnection) url
.openConnection();
if (conn != null) {
conn.setConnectTimeout(20000);
conn.setUseCaches(false);
if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
// 서버에서 읽어오기 위한 스트림 객체
InputStreamReader isr = new InputStreamReader(
conn.getInputStream());
// 줄단위로 읽어오기 위해 BufferReader로 감싼다.
BufferedReader br = new BufferedReader(isr);
// 반복문 돌면서읽어오기
while (true) {
String line = br.readLine();
if (line == null) {
break;
}
Buffer.append(line);
}
br.close();
conn.disconnect();
}
}
get_json = Buffer.toString();
Log.d(TAG, "get_json: " + get_json);
} catch (Exception e) {
// TODO: handle exception
Log.e("에러 ", e.getMessage());
}
return get_json;
}
여러분께서 구축해두신 서버내의 jsp 경로를 넣어주시면 됩니다.
"https://Host/dir1/dir2/dir2/A.jsp?&Serial_key=" + get_serialkey;
2. 서버(JSP)에서 json으로 데이터 보내주기
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@page import="java.sql.SQLException"%>
<%@page import="java.sql.Statement"%>
<%@page import="java.sql.Connection"%>
<%@page import="java.io.*"%>
<%@page import="java.util.*"%>
<%@page import="java.sql.DriverManager"%>
<%@page import="java.sql.ResultSet"%>
<%@page import="java.sql.PreparedStatement"%>
<%@page import="org.json.simple.JSONArray"%>
<%@page import="org.json.simple.JSONObject"%>
<%
Class.forName("com.mysql.jdbc.Driver");
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost/디비", "디비아이디" , "패스워드");
ResultSet rs = null;
PreparedStatement stmt = null;
boolean flagStatus = false;
// 초기 선언
JSONObject jsonMain = new JSONObject();
JSONArray jArray = new JSONArray();
JSONObject jObject = new JSONObject();
String Key = request.getParameter("Serial_key");
// CHECKING DATA EXIST
try{
String sql = " 쿼리를 만들어 넣어주세요 ";
stmt = conn.prepareStatement(sql);
rs = stmt.executeQuery();
if(rs.next()){
// 안드로이드로 보낼 메시지를 만듬
jObject.put("START_TIME", rs.getString("START_TIME"));
jObject.put("STOP_TIME", rs.getString("STOP_TIME"));
jObject.put("REG_TIME", rs.getString("REG_TIME"));
// 위에서 만든 각각의 객체를 하나의 배열 형태로 만듬
jArray.add(0, jObject);
// 최종적으로 배열을 하나로 묶음
jsonMain.put(rs.getString("SERIAL_KEY"), jArray);
// 안드로이드에 보낼 데이터를 출력
out.println(jsonMain.toJSONString());
}else{
conn.close();
}
}catch(SQLException sqlex){
application.log("[Select_Time_info.jsp-로그] sqlex="+sqlex.getMessage());
}catch(Exception ex){
application.log("[Select_Time_info.jsp-로그] ex="+ex.getMessage());
}finally{
if(rs!=null)
try{rs.close();
}catch(SQLException ex){}
if(conn!=null)
try{conn.close();
}catch(SQLException ex){}
}
%>
3. Json 데이터를 받아보기 (Android)
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
Log.d(TAG, " <<<<<onPostExecute>>>> ");
try {
JSONArray jarray = new JSONObject(result).getJSONArray(serial_key);
if (jarray != null) {
JSONObject jsonObject = jarray.getJSONObject(0);
String Start = jsonObject.getString("START_TIME");
String Stop = jsonObject.getString("STOP_TIME");
String REG = jsonObject.getString("REG_TIME");
//String Start = jsonObject.optString("START_TIME", "text on no value");
//String Stop = jsonObject.optString("STOP_TIME", "text on no value");
//String REG = jsonObject.optString("REG_TIME", "text on no value");
Log.d(TAG, Start + "/" + Stop + "/" + REG);
} else {
Toast.makeText(mcontext, "123", Toast.LENGTH_SHORT).show();
}
} catch (Exception e) {
Log.e(TAG, e.getMessage());
}
}
4. 결과
2019-07-04 15:06:24.160 2661-2793/com.프로젝트 D/Time_Check 테스트: https://호스트/dir1/dir2/dir2/app.jsp?&Serial_key=기본키
2019-07-04 15:06:24.186 2661-2793/com.프로젝트 D/Time_Check 테스트: get_json: {"기본키":[{"REG_TIME":null,"START_TIME":"09:00","STOP_TIME":"18:00"}]}
2019-07-04 15:06:24.187 2661-2661/com.프로젝트 D/Time_Check 테스트: <<<<<onPostExecute>>>>
2019-07-04 15:06:24.188 2661-2661/com.프로젝트 D/Time_Check 테스트: 09:00/18:00/null
5. Android 전체 코드
public class Time_Check {
String TAG = Time_Check.class.getSimpleName() + " 테스트";
DatabaseHandler_Dongle dongle;
Context mcontext;
String serial_key;
public Time_Check(Context context) {
mcontext = context;
dongle = new DatabaseHandler_Dongle(mcontext);
serial_key = new GET_Serial_Key().getDeviceSerialNumber();
new check_date().execute(serial_key);
}
class check_date extends AsyncTask<String, Void, String> {
StringBuffer Buffer = new StringBuffer();
@Override
protected String doInBackground(String... serialkey) {
String get_serialkey = serialkey[0];
String get_json = "";
try {
String urlAddr = "https://호스트/dir1/dir2/dir2/app.jsp?&Serial_key=" + get_serialkey;
URL url = new URL(urlAddr);
HttpURLConnection conn = (HttpURLConnection) url
.openConnection();
if (conn != null) {
conn.setConnectTimeout(20000);
conn.setUseCaches(false);
if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
// 서버에서 읽어오기 위한 스트림 객체
InputStreamReader isr = new InputStreamReader(
conn.getInputStream());
// 줄단위로 읽어오기 위해 BufferReader로 감싼다.
BufferedReader br = new BufferedReader(isr);
// 반복문 돌면서읽어오기
while (true) {
String line = br.readLine();
if (line == null) {
break;
}
Buffer.append(line);
}
br.close();
conn.disconnect();
}
}
get_json = Buffer.toString();
Log.d(TAG, "get_json: " + get_json);
} catch (Exception e) {
// TODO: handle exception
Log.e("에러 ", e.getMessage());
}
return get_json;
}
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
Log.d(TAG, " <<<<<onPostExecute>>>> ");
try {
JSONArray jarray = new JSONObject(result).getJSONArray(serial_key);
if (jarray != null) {
JSONObject jsonObject = jarray.getJSONObject(0);
String Start = jsonObject.getString("START_TIME");
String Stop = jsonObject.getString("STOP_TIME");
String REG = jsonObject.getString("REG_TIME");
// null을 가끔 못 읽어오는 때가 있다고 하기에 써봄
//String Start = jsonObject.optString("START_TIME", "text on no value");
//String Stop = jsonObject.optString("STOP_TIME", "text on no value");
//String REG = jsonObject.optString("REG_TIME", "text on no value");
Log.d(TAG, Start + "/" + Stop + "/" + REG);
} else {
Toast.makeText(mcontext, "123", Toast.LENGTH_SHORT).show();
}
} catch (Exception e) {
Log.e(TAG, e.getMessage());
}
}
}
}