Android PHP MySQL 예제 - 데이터베이스 질의(query) 결과 출력하기

 

 

안드로이드 앱에서 입력한 키워드를 웹서버에서 실행되는 PHP를 이용하여 MySQL 데이터베이스 서버에 질의하는 예제입니다.

질의 결과는 JSON 형식으로 가져와서 화면에 보여줍니다.


 

현재 예제에선 키워드를 2개 사용하고 있습니다. 3개 이상 필요한 경우 노란색 코드를 참고하여 추가하세요. 

activity_main.xml, MainActivity.java, query.php  파일을 수정하면 됩니다.


 

 

1. 웹기반 테스트

 

2. Android 앱에서 테스트

 

3. 코드 설명

 

4. 관련 포스팅


 

최초작성 2017.  8. 16

최종작성 2019. 11. 17 androidx 사용하도록 변경



 

다음 포스팅에 연결된 포스팅입니다. 

 

 

Android PHP MySQL 예제 - 데이터베이스에서 데이터를 JSON 형식으로 가져오기

http://webnautes.tistory.com/829   



 

1. 웹기반 테스트

Android 앱에서 진행하기 전에 웹기반으로 먼저 테스트를 진행합니다.

PC에 설치된 웹서버 및 데이터베이스 서버 접속하는데 문제 없는지,  PHP 코드에서 테이블 접근시 문제 없는지 등을 확인해보기 위해서입니다. 



 

1. 앞에서 진행했던 포스팅의 결과로 현재 db 데이터베이스의 Person 테이블에 다음 데이터가 저장되어 있는 상태입니다.

 

Android PHP MySQL 예제 - 데이터베이스에 데이터 입력하기

http://webnautes.tistory.com/828

 

웹브라우저에서 http://localhost/insert.php 에 접속하여 추가로 데이터를 더 집어 넣었습니다.

 



 

2. 다음 코드를 query.php 파일의 내용으로  복사해줍니다.

 

윈도우라면 C:\wamp64\www\ 경로에 query.php 파일을 생성합니다.

우분투라면 /var/www/html/ 경로에 query.php 파일을 생성합니다.

 

dbcon.php 파일은 이전 포스팅에 있는 것을 그대로 사용합니다. 

 

<?php 
error_reporting(E_ALL);
ini_set('display_errors',1);

include('dbcon.php');



//POST 값을 읽어온다.
$country=isset($_POST['country']) ? $_POST['country'] : '';
$name = isset($_POST['name']) ? $_POST['name'] : '';
$android = strpos($_SERVER['HTTP_USER_AGENT'], "Android");


if ($country != "" ){

    $sql="select * from person where country='$country' and name='$name'";
    $stmt = $con->prepare($sql);
    $stmt->execute();

    if ($stmt->rowCount() == 0){

        echo "'";
        echo $country,", ",$name;
        echo "'은 찾을 수 없습니다.";
    }
else{

  $data = array();

        while($row=$stmt->fetch(PDO::FETCH_ASSOC)){

        extract($row);

            array_push($data,
                array('id'=>$row["id"],
                'name'=>$row["name"],
                'country'=>$row["country"]
            ));
        }


        if (!$android) {
            echo "<pre>";
            print_r($data);
            echo '</pre>';
        }else
        {
            header('Content-Type: application/json; charset=utf8');
            $json = json_encode(array("webnautes"=>$data), JSON_PRETTY_PRINT+JSON_UNESCAPED_UNICODE);
            echo $json;
        }
    }
}
else {
    echo "검색할 나라를 입력하세요 ";
}

?>



<?php

$android = strpos($_SERVER['HTTP_USER_AGENT'], "Android");

if (!$android){
?>

<html>
  <body>
 
      <form action="<?php $_PHP_SELF ?>" method="POST">
        나라: <input type = "text" name = "country" />
        이름: <input type = "text" name = "name" />
        <input type = "submit" />
      </form>
 
  </body>
</html>
<?php
}

 
?>

 

 

 

3. PC의 웹브라우저에서 http://localhost/query.php 주소로 접속하면 다음과 같은 화면이 보이게 됩니다.

 

 

 

이미 데이터베이스의 테이블에 저장되어 있는 나라인 조선, 홍길동을 입력하고 제출을 클릭하면 JSON 포맷으로 결과를 보여줍니다.

 

 

 

 

없는 데이터를 검색한 경우입니다.

 

 

 

부분 문자열 검색은 구현안되어 있어서 일부만 입력하면 없다고 결과가 나옵니다.

 

 

 

4. 안드로이드 폰의 웹브라우저에서도 확인해봅니다.

주의할 점은 PC와 안드로이드가 같은 공유기에서 아이피를 할당받았거나 PC가 고정 아이피여야 테스트가 가능합니다.

 

본 포스팅에서는 안드로이드 폰의 핫스팟을 노트북에서 사용하도록 해서 테스트를 진행했습니다.

ifconfig 명령을 사용하여 노트북의 IP를 확인합니다. 여기에서는 192.168.43.52입니다.

 

 

 

크롬의 경우에는 데스크톱 버전으로 보기를 체크해줘야 텍스트 박스가 제대로 보입니다.

 

 

 

검색할 키워드를 입력하고 제출을 터치하면

 



 

PC와 동일한 결과를 얻을 수 있습니다.

문제가 있는 경우 PC와 스마트폰이 같은 네트워크(같은 공유기)를 사용하고 있는지 체크해보세요. 

 



 

2. Android 앱에서 테스트

1.  이제 웹서버의 PHP 파일에 접근하는 안드로이드 앱을 작성합니다. 

안드로이드 스튜디오에서 새로운  Empty 프로젝트를 생성합니다.



 

2. AndroidManifest.xml 매니페스트 파일의  manifest 태그 하위 항목으로 인터넷 접근 허용 퍼미션을 추가합니다.

 

android 9.0 이상에서 동작하게 하려면 usesCleartextTraffic 옵션도 추가해야 합니다. 해주지 않으면 “cleartext http traffic to not permitted” 라는 에러가 발생합니다.  

 

 

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.tistory.webnautes.phptest">

    <uses-permission android:name="android.permission.INTERNET" />

    <application
        android:usesCleartextTraffic="true"
        android:allowBackup="true"



 

3. activity_main.xml 레이아웃 파일을 다음 내용으로 변경합니다.

 

 

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/textView_main_label"
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:text="검색할 나라와 이름을 입력해주세요 . " />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:orientation="horizontal">

        <EditText
            android:id="@+id/editText_main_searchKeyword1"
            android:layout_width="0dp"
            android:layout_weight="0.35"
            android:hint="나라"
            android:layout_height="match_parent" />

        <EditText
            android:id="@+id/editText_main_searchKeyword2"
            android:layout_width="0dp"
            android:layout_weight="0.35"
            android:hint="이름"
            android:layout_height="match_parent" />

        <Button
            android:id="@+id/button_main_search"
            android:layout_width="0dp"
            android:layout_weight="0.3"
            android:layout_height="match_parent"
            android:text="Search" />
    </LinearLayout>

    <ListView
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="0.4"
        android:id="@+id/listView_main_list"/>

    <TextView
        android:id="@+id/textView_main_result"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="0.4" />
</LinearLayout>




 

4. item_list.xml  레이아웃 파일을 추가로 생성하여 아래 내용으로 바꿉니다. 

 

 

ListView의 한 줄을 여러 개의 열로 표현하기 위해 필요한 레이아웃입니다.

세 개의 TextVew에 각각의 크기를 지정해주었습니다. 

 


 

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:app="http://schemas.android.com/apk/res-auto"
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  android:orientation="horizontal"
  android:layout_margin="15dp"
  android:padding="10dp">


  <TextView
      android:id="@+id/textView_list_id"
      android:layout_width="0dp"
      android:layout_height="wrap_content"
      android:layout_weight="1"
      android:layout_margin="5dp"
      android:padding="5dp" />


  <TextView
      android:id="@+id/textView_list_name"
      android:layout_width="0dp"
      android:layout_height="wrap_content"
      android:layout_weight="4"
      android:layout_margin="5dp"
      android:padding="5dp" />


  <TextView
      android:id="@+id/textView_list_address"
      android:layout_width="0dp"
      android:layout_height="wrap_content"
      android:layout_weight="5"
      android:layout_margin="5dp"
      android:padding="5dp" />

</LinearLayout>




 

5. MainActivity.java 자바 파일을 아래 내용으로 바꿉니다.

 

경축! 아무것도 안하여 에스천사게임즈가 새로운 모습으로 재오픈 하였습니다.
어린이용이며, 설치가 필요없는 브라우저 게임입니다.
https://s1004games.com

 

코드에서 다음 라인은 접속할 서버 IP로 변경해야 합니다.

 

String serverURL = "http://서버IP/query.php";


 

import android.app.ProgressDialog;
import android.os.AsyncTask;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.TextView;


import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.BufferedReader;

import java.io.InputStream;
import java.io.InputStreamReader;

import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;


public class MainActivity extends AppCompatActivity {

    private static String TAG = "phpquerytest";

    private static final String TAG_JSON="webnautes";
    private static final String TAG_ID = "id";
    private static final String TAG_NAME = "name";
    private static final String TAG_ADDRESS ="country";

    private TextView mTextViewResult;
    ArrayList<HashMap<String, String>> mArrayList;
    ListView mListViewList;
    EditText mEditTextSearchKeyword1, mEditTextSearchKeyword2;
    String mJsonString;


    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mTextViewResult = (TextView)findViewById(R.id.textView_main_result);
        mListViewList = (ListView) findViewById(R.id.listView_main_list);
        mEditTextSearchKeyword1 = (EditText) findViewById(R.id.editText_main_searchKeyword1);
        mEditTextSearchKeyword2 = (EditText) findViewById(R.id.editText_main_searchKeyword2);


        Button button_search = (Button) findViewById(R.id.button_main_search);
        button_search.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {

                mArrayList.clear();


                GetData task = new GetData();
                task.execute( mEditTextSearchKeyword1.getText().toString(), mEditTextSearchKeyword2.getText().toString());
            }
        });


        mArrayList = new ArrayList<>();


    }


    private class GetData extends AsyncTask<String, Void, String>{

        ProgressDialog progressDialog;
        String errorString = null;

        @Override
        protected void onPreExecute() {
            super.onPreExecute();

            progressDialog = ProgressDialog.show(MainActivity.this,
                    "Please Wait", null, true, true);
        }


        @Override
        protected void onPostExecute(String result) {
            super.onPostExecute(result);

            progressDialog.dismiss();
            mTextViewResult.setText(result);
            Log.d(TAG, "response - " + result);

            if (result == null){

                mTextViewResult.setText(errorString);
            }
            else {

                mJsonString = result;
                showResult();
            }
        }


        @Override
        protected String doInBackground(String... params) {

            String searchKeyword1 = params[0];
            String searchKeyword2 = params[1];

            String serverURL = "http://서버IP/query.php";
            String postParameters = "country=" + searchKeyword1 + "&name=" + searchKeyword2;


            try {

                URL url = new URL(serverURL);
                HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();


                httpURLConnection.setReadTimeout(5000);
                httpURLConnection.setConnectTimeout(5000);
                httpURLConnection.setRequestMethod("POST");
                httpURLConnection.setDoInput(true);
                httpURLConnection.connect();


                OutputStream outputStream = httpURLConnection.getOutputStream();
                outputStream.write(postParameters.getBytes("UTF-8"));
                outputStream.flush();
                outputStream.close();


                int responseStatusCode = httpURLConnection.getResponseCode();
                Log.d(TAG, "response code - " + responseStatusCode);

                InputStream inputStream;
                if(responseStatusCode == HttpURLConnection.HTTP_OK) {
                    inputStream = httpURLConnection.getInputStream();
                }
                else{
                    inputStream = httpURLConnection.getErrorStream();
                }


                InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "UTF-8");
                BufferedReader bufferedReader = new BufferedReader(inputStreamReader);

                StringBuilder sb = new StringBuilder();
                String line;

                while((line = bufferedReader.readLine()) != null){
                    sb.append(line);
                }


                bufferedReader.close();


                return sb.toString().trim();


            } catch (Exception e) {

                Log.d(TAG, "InsertData: Error ", e);
                errorString = e.toString();

                return null;
            }

        }
    }


    private void showResult(){
        try {
            JSONObject jsonObject = new JSONObject(mJsonString);
            JSONArray jsonArray = jsonObject.getJSONArray(TAG_JSON);

            for(int i=0;i<jsonArray.length();i++){

                JSONObject item = jsonArray.getJSONObject(i);

                String id = item.getString(TAG_ID);
                String name = item.getString(TAG_NAME);
                String address = item.getString(TAG_ADDRESS);

                HashMap<String,String> hashMap = new HashMap<>();

                hashMap.put(TAG_ID, id);
                hashMap.put(TAG_NAME, name);
                hashMap.put(TAG_ADDRESS, address);

                mArrayList.add(hashMap);
            }

            ListAdapter adapter = new SimpleAdapter(
                    MainActivity.this, mArrayList, R.layout.item_list,
                    new String[]{TAG_ID,TAG_NAME, TAG_ADDRESS},
                    new int[]{R.id.textView_list_id, R.id.textView_list_name, R.id.textView_list_address}
            );

            mListViewList.setAdapter(adapter);

        } catch (JSONException e) {

            Log.d(TAG, "showResult : ", e);
        }

    }

}



 

6.  실행결과 입니다. 검색할 나라와 이름을 입력하고 SEARCH 버튼을 클릭하면 PHP 코드를 이용하여 데이터베이스 서버에 질의하고 결과를 가져옵니다.




 

중앙의 리스트뷰에는 검색 결과를 파싱하여 보여주며, 하단의 텍스트뷰에서는 JSON 데이터를 보여줍니다.

 



 

검색 결과가 없는 경우에는 PHP에서 보내준 에러메시지를 보여줍니다.


 

일정 시간 내에 서버로 접속이 안되는 경우 시간 초과 예외로 처리하고 있습니다.

java.net.SocketTimeoutException: failed to connect 메시지를 보여줍니다. 


 

3. 코드 설명

검색어가 하나인 경우를 예로 들어 설명하고 있습니다.


 

(자바 코드) 버튼을 클릭하면 검색창에 있는 내용을 아규먼트로하여 GetData AsyncTask를 실행합니다.

 

button_search.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {

mArrayList.clear();


GetData task = new GetData();
task.execute( mEditTextSearchKeyword.getText().toString());
}
});

 

 

 

(자바 코드) 검색한 나라이름(searchKeyword)을 POST 방식 HTTP 통신의 아규먼트로 하여 서버에 있는 PHP 파일을 실행합니다.

 

String serverURL = "http://서버IP/query.php";
String postParameters = "country=" + searchKeyword;

. . . . . . . . . . . . .

outputStream.write(postParameters.getBytes("UTF-8"));

 

 

 

(PHP 코드) POST 방식으로 전달받은 값을 사용하여 SELECT문을 실행합니다.

 

if ($country != "" ){

    $sql="select * from person where country='$country'";
    $stmt = $con->prepare($sql);
    $stmt->execute();

 

 

 

(PHP 코드) 질의 결과 데이터가 없으면 에러를 출력하고 데이터를 얻으면 배열을 생성합니다. 

 

    if ($stmt->rowCount() == 0){

        echo "'";
        echo $country;
        echo "'은 찾을 수 없습니다.";
    }
else{

  $data = array();

        while($row=$stmt->fetch(PDO::FETCH_ASSOC)){

        extract($row);

            array_push($data,
                array('id'=>$row["id"],
                'name'=>$row["name"],
                'country'=>$row["country"]
            ));
        }

 


 

(PHP 코드) 안드로이드에 전달하기 위해 JSON 포맷으로 변경 후 에코합니다. 

 

if (!$android) {
echo "<pre>";
print_r($data);
echo '</pre>';
}else
{
header('Content-Type: application/json; charset=utf8');
$json = json_encode(array("webnautes"=>$data), JSON_PRETTY_PRINT+JSON_UNESCAPED_UNICODE);
echo $json;
}



 

(자바코드) StringBuilder를 사용하여 PHP가 에코한 문자열을 저장하고 스트링으로 변환하여 리턴합니다. 

 

InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "UTF-8");
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);

StringBuilder sb = new StringBuilder();
String line;

while((line = bufferedReader.readLine()) != null){
sb.append(line);
}

bufferedReader.close();

return sb.toString().trim();



 

(자바 코드) 에러가 있는 경우 에러메시지를 보여주고 아니면 JSON을 파싱하여 화면에 보여주는 showResult 메소드를 호출합니다.

 

      @Override
protected void onPostExecute(String result) {
super.onPostExecute(result);

progressDialog.dismiss();
mTextViewResult.setText(result);
Log.d(TAG, "response - " + result);

if (result == null){

mTextViewResult.setText(errorString);
}
else {

mJsonString = result;
showResult();
}
}


 

(자바 코드)  안드로이드 앱에서 받은 JSON 포맷의 데이터입니다.

간단한 규칙이 있는데 중괄호 {} 는 JSONObject  대괄호 [] JSONArray입니다.

 

{
    "webnautes": [
        {
            "id": "1",
            "name": "홍길동",
            "country": "조선"
        },
        {
            "id": "2",
            "name": "잔다르크",
            "country": "프랑스"
        }
    ]
}

 

          

 

(자바 코드)  첫번째 괄호는 중괄호 {} 이므로 JSONObject입니다.

 

JSONObject jsonObject = new JSONObject(mJsonString);

 

 

 

(자바 코드)  jsonObject에서 TAG_JSON 키를 갖는 JSONArray를 가져옵니다.

 

JSONArray jsonArray = jsonObject.getJSONArray(TAG_JSON);

 

 

(자바 코드) 이제 다음같은 구조를 jsonArray가 갖고 있게 됩니다. 

 

[
        {
            "id": "1",
            "name": "홍길동",
            "country": "조선"
        },
        {
            "id": "2",
            "name": "잔다르크",
            "country": "프랑스"
        }
    ]

 

 

 

(자바 코드)  JsonArray에는 JSONObject가 데이터 갯수만큼 포함되어 있습니다. 

인덱스를 사용하여 JsonArray에서 JSONObject를 하나씩 가져옵니다. 

 

for(int i=0;i<jsonArray.length();i++){
JSONObject item = jsonArray.getJSONObject(i);

 

 

 

(자바 코드)  JSONObject에서 키 id, name, country의 값을 가져옵니다.

 

String id = item.getString(TAG_ID);
String name = item.getString(TAG_NAME);
String country = item.getString(TAG_COUNTRY);

 

 

 

(자바 코드) 데이터를 새로 생성한 PersonalData 클래스의 멤버변수에 입력하고 ArrayList에 추가합니다.

 

PersonalData personalData = new PersonalData();

personalData.setMember_id(id);
personalData.setMember_name(name);
personalData.setMember_country(country);

mArrayList.add(personalData);

 


 

(자바코드) SimpleAdapter를 사용하여 화면에 파싱된 데이터를 보여줍니다. 

 

            ListAdapter adapter = new SimpleAdapter(
                    MainActivity.this, mArrayList, R.layout.item_list,
                    new String[]{TAG_ID,TAG_NAME, TAG_COUNTRY},
                    new int[]{R.id.textView_list_id, R.id.textView_list_name, R.id.textView_list_address}
            );

            mListViewList.setAdapter(adapter);

 

 

4. 관련 포스팅

 

Android PHP MySQL 예제 - 데이터베이스에 데이터 입력하기

http://webnautes.tistory.com/828 

 

Android PHP MySQL 예제 - 데이터베이스에서 데이터를 JSON 형식으로 가져오기

http://webnautes.tistory.com/829

 

Android PHP MySQL 예제  - 데이터베이스에 데이터 저장 및 JSON 형식으로 가져오는 예제 프로젝트

http://webnautes.tistory.com/1189  


 

[출처] https://webnautes.tistory.com/1159

 

 

본 웹사이트는 광고를 포함하고 있습니다.
광고 클릭에서 발생하는 수익금은 모두 웹사이트 서버의 유지 및 관리, 그리고 기술 콘텐츠 향상을 위해 쓰여집니다.
번호 제목 글쓴이 날짜 조회 수
121 [android studio] 안드로이드 스튜디오 패키지명 변경 방법 file 졸리운_곰 2024.01.28 1
120 [React Native] 리액트 네이티브 안드로이드 기기 빌드 에러 졸리운_곰 2023.12.17 1
119 [android studio] 안드로이드 앱 내부 배포 시 Play프로텍트에 인증받고 배포하기 file 졸리운_곰 2023.03.23 3
118 [android studio] [Java][Android] 안드로이드 다국어 지원 file 졸리운_곰 2023.03.21 5
117 [android studio] [안드로이드 스튜디오] 다국어 지원 strings.xml 파일 생성 방법 file 졸리운_곰 2023.03.21 12
116 [android studio] 구글 플레이 스토어 등록 어떻게? 2편 - 키스토어 생성과 릴리즈 빌드 하기 file 졸리운_곰 2023.03.21 5
115 [android studio] 구글 플레이 스토어 등록 어떻게? 1편 - 준비해야 할 것들 졸리운_곰 2023.03.21 5
114 [android studio] 웹페이지를 apk 앱으로 | 쉽게 따라하는 웹앱 만들기 file 졸리운_곰 2023.03.21 11
113 [android studio] 안드로이드 아이콘이 2개 생성될 때 졸리운_곰 2023.03.21 2
112 [android studio] Convert Any Website to Android App using Android Studio file 졸리운_곰 2023.03.18 1
111 [android studio] How to Convert Any Website to Android App in Android Studio? file 졸리운_곰 2023.03.18 5
110 [phonegap][cordova] [안드로이드] 코도바 앱(App) 개발 환경 세팅 file 졸리운_곰 2023.02.05 10
109 [android studio] 에러 해결: android gradle plugin requires java 11 to run. you are currently using java 1.8. file 졸리운_곰 2022.11.17 4
108 [android sdk] 안드로이드에서 JWT 사용하기 졸리운_곰 2022.07.15 22
107 [Android Studio] Android Native App 에서 mysql , php 연결 : PHP MySQL REST API for Android file 졸리운_곰 2021.12.02 104
106 Android PHP MySQL 예제 - 데이터베이스에서 데이터를 JSON 형식으로 가져오기 file 졸리운_곰 2021.07.24 208
» Android PHP MySQL 예제 - 데이터베이스 질의(query) 결과 출력하기 file 졸리운_곰 2021.07.24 539
104 [android] 안드로이드에서 mysql 데이터베이스 입력, 접속 / Android PHP MySQL 예제 - 데이터베이스에 데이터 입력하기 file 졸리운_곰 2021.07.24 117
103 Android 에서 Opencv 설치하고 간단한 예제 실행해보기!! file 졸리운_곰 2020.10.31 333
102 안드로이드 나인 패치(9-Patch) 이미지 버튼. (Android Nine-Patch Image Button) file 졸리운_곰 2020.10.10 147
대표 김성준 주소 : 경기 용인 분당수지 U타워 등록번호 : 142-07-27414
통신판매업 신고 : 제2012-용인수지-0185호 출판업 신고 : 수지구청 제 123호 개인정보보호최고책임자 : 김성준 sjkim70@stechstar.com
대표전화 : 010-4589-2193 [fax] 02-6280-1294 COPYRIGHT(C) stechstar.com ALL RIGHTS RESERVED