티스토리 뷰
안드로이드에서는 보안 때문에 일반적 RDBMS(MySQL, MSSQL 등)를 사용하지 못한다고 한다.
그래서 AsyncTask객체의 doInBackground메서드를 이용해서 이 구현부에서 HttpURLConnection객체를 이용해 로컬서버나 실서버와 통신하고 결과를 json형태로 가져와 파싱하는 과정을 거치는 프로그램을 짜야 한다.
다음은 로컬서버와 통신하기 위한 테스트 코드이다.
+서블릿 코드
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | @WebServlet("/CommonJdbc") public class CommonJdbc extends HttpServlet { private static final long serialVersionUID = 1L; public CommonJdbc() { super(); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { JSONObject json = new JSONObject(); String result = "success"; Connection connection = null; Statement statment = null; ResultSet rs; System.out.println("진입 진입!!!!!!"); try { // Connect to database retrieve user credentials Class.forName("com.mysql.jdbc.Driver"); connection = DriverManager.getConnection( "jdbc:mysql://localhost:3306/project", "admins", "c9999"); statment = connection.createStatement(); rs = statment.executeQuery("SELECT * FROM MEMBER;"); List<Map<String, String>> list = new ArrayList<>(); Map<String, String> map = null; while(rs.next()){ map = new HashMap<>(); map.put("email", rs.getString("EMAIL")); map.put("name", rs.getString("NAME")); list.add(map); } json.put("memberData", list); } catch (SQLException e) { result = "fail - SQLException"; } finally { try { if (statment != null) { statment.close(); statment = null; } if (connection != null) { connection.close(); connection = null; } json.put("result", result); response.setContentType("application/json"); response.setCharacterEncoding("UTF-8"); //응답 스트림에 정제한 json을 쓴다. response.getWriter().write(json.toString()); } catch (SQLException e) { } } } } | cs |
DB에 연결되고 쿼리 질의 후 JSONObject타입의 변수 json을 이용해 데이터를 넣고 응답스트림에 쓴다.
+액티비티에서 호출할 AsyncTask확장 클래스
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 | public class HttpUtil extends AsyncTask<String, Void, JSONArray> { @Override public JSONArray doInBackground(String... params) { JSONArray memberJsonArr = null; try { //HttpURLConnection을 이용해 url에 연결하기 위한 설정 String url = "http://192.168.0.192:8080/CommonJdbc"; URL obj = new URL(url); HttpURLConnection conn = (HttpURLConnection) obj.openConnection(); //커넥션에 각종 정보 설정 conn.setReadTimeout(15000); conn.setConnectTimeout(15000); conn.setRequestMethod("POST"); conn.setDoInput(true); conn.setDoOutput(true); conn.setRequestProperty("Content-Type", "application/json"); //응답 http코드를 가져옴 int responseCode = conn.getResponseCode(); ByteArrayOutputStream baos = null; InputStream is = null; String responseStr = null; //응답이 성공적으로 완료되었을 때 if (responseCode == HttpURLConnection.HTTP_OK) { is = conn.getInputStream(); baos = new ByteArrayOutputStream(); byte[] byteBuffer = new byte[1024]; byte[] byteData = null; int nLength = 0; while ((nLength = is.read(byteBuffer, 0, byteBuffer.length)) != -1) { baos.write(byteBuffer, 0, nLength); } byteData = baos.toByteArray(); responseStr = new String(byteData); JSONObject responseJSON = new JSONObject(responseStr); //json데이터가 하나의 값일 때 String result = (String) responseJSON.get("result"); //json데이터가 Map같은 형식일 때 memberJsonArr = responseJSON.getJSONArray("memberData"); //Log.i("info", "DATA response = " + responseStr); } else { is = conn.getErrorStream(); baos = new ByteArrayOutputStream(); byte[] byteBuffer = new byte[1024]; byte[] byteData = null; int nLength = 0; while ((nLength = is.read(byteBuffer, 0, byteBuffer.length)) != -1) { baos.write(byteBuffer, 0, nLength); } byteData = baos.toByteArray(); responseStr = new String(byteData); Log.i("info", "DATA response error msg = " + responseStr); } } catch (Exception e) { e.printStackTrace(); Log.i("errorInfo", "error occured!" + e.getMessage()); } return memberJsonArr; } } | cs |
이곳에서 URL에 커넥션하고 json결과를 가져온다.
로컬호스트가 대상이라고 해서 127.0.0.1, localhost와 같이 사용하면 안된다. cmd창에서 ipconfig명령으로 확인 후에 내 내부아이피가 되는 Ipv4 주소를 적어야 한다.
+메인 액티비티
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); try { ObjectMapper objectMapper = new ObjectMapper(); HashMap<String, String> map = new HashMap<>(); String json = objectMapper.writeValueAsString(map); HttpUtil util = new HttpUtil(); util.execute(json); JSONArray jsonArray = util.get(); for(int i = 0; i<jsonArray.length(); i++){ JSONObject obj = jsonArray.getJSONObject(i); Log.i("memberData", "["+ obj.getString("email") + ", " + obj.getString("name") +"]"); } } catch (Exception e) { e.printStackTrace(); } } } | cs |
가져온 배열형태의 json데이터를 로그에 출력하고 있다.
이 코드가 정상적으로 동작하기 위해서는 AndroidManifest.xml에 다음과 같은 태그를 넣어야한다.
<manifest>안에 넣으면 된다.
1 | <uses-permission android:name="android.permission.INTERNET"></uses-permission> | cs |
그리고 접속하고자 하는 방화벽 포트를 오픈해 놓아야한다. 이것은 운영체제마다 틀리니 검색해서 방법을 찾아본다.
가상 안드로이드 머신인 지니모션을 사용할 때는 에러가 난다.
와이파이로 잡아 놓고 스마트폰으로 테스트 해야 정상적으로 실행된다.
마지막으로 또 안드로이드의 jdk버전과 서블릿을 돌리는 jdk버전이 일치해야 에러가 발생하지 않는다.