서버(PHP)통신 with Android_GET_POST_DB_CSV파싱_JSON파싱_Gson라이브러리*

소정·2023년 3월 14일
0

php

목록 보기
3/3

공통

인터넷 퍼미션과 http 사용가능 매니패스트에 쓰기

0. 화면 UI

<?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"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="16dp"
    tools:context=".MainActivity">

    <EditText
        android:id="@+id/et_name"
        android:hint="이름"
        android:inputType="text"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

    <EditText
        android:id="@+id/et_msg"
        android:lines="5"
        android:gravity="top"
        android:inputType="textMultiLine"
        android:hint="input message"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

    <Button
        android:id="@+id/btn_get"
        android:text="get method"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

    <Button
        android:id="@+id/btn_post"
        android:text="post method"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

    <TextView
        android:id="@+id/tv"
        android:padding="8dp"
        android:textColor="@color/black"
        android:text="서버로 부터 응답된 결과"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

    <Button
        android:id="@+id/btn_load"
        android:text="load data"
        android:backgroundTint="@color/black"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

</LinearLayout>

[1]Get 방식

  1. 서버로 보낼 데이터 준비

  2. Get방식으로 보낼 서버의 주소 준비

  3. url 뒤에 붙어갈 값 인코딩해서 서버뒤에 붙여주기

  4. 서버와 연결작업
    4-1) 해임달(URL) 준비
    4-2) HttpURLConnection : outputStream까지 하는 Http 통신용 객체 준비 & 3가지 set

    • setRequestMethod("GET"); = 무조건 대문자로 적어야함(equls문으로 되어 있어서)
    • setDoInput(true); = 서버의 에코 응답을 받아야해서
    • setUseCaches(false); = Caches 는 작은 서랍 공간인데 이걸 쓰면 값이 이전게 넘어갈 수 있어서 false 권장
    • GET방식은 이미 url에 데이터가 추가되어 가기때문에 별도로 setDoOutput이 필요하지 않는다
  5. 서버로 부터 응답된 결과 받기

    • getInputStream() -> new InputStreamReader(is) -> new BufferedReader(isr)
      라인으로 받기위해 변형

MainActivity.java

package com.bsj0420.ex82httprequst;

import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.os.Bundle;
import android.widget.EditText;

import com.bsj0420.ex82httprequst.databinding.ActivityMainBinding;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;

public class MainActivity extends AppCompatActivity {

    ActivityMainBinding mainBinding;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //setContentView(R.layout.activity_main);

        mainBinding = ActivityMainBinding.inflate(getLayoutInflater());
        setContentView(mainBinding.getRoot());

        mainBinding.btnGet.setOnClickListener(v->clickGet());

    }

    private void clickGet() {
        //네트워크 작업 Thread
        new Thread(){
            @Override
            public void run() {

                //1. 서버로 보낼 데이터 준비
                String name = mainBinding.etName.getText().toString();
                String msg = mainBinding.etMsg.getText().toString();
                
                //2. Get방식으로 보낼 서버의 주소
                String serverAddress ="http://mrhisj23.dothome.co.kr/Android/getTest.php";
                
                //3. Get방식은 보낼 데이터(name, message)를 url주소 뒤에 붙여서 보내는 방식
                //단, url에는 한글 및 특수문자 사용 불가 - 한글을 Url에 사용될 수 있도록 암호화(코드화 인코딩)
                try {
                    name = URLEncoder.encode(name, "utf-8");
                    msg = URLEncoder.encode(msg, "utf-8");
                } catch (UnsupportedEncodingException e) {
                    throw new RuntimeException(e);
                }
                String getAddress = serverAddress + "?name="+name +"&msg="+msg;
                
                //4. 서버와 연결작업
                try {
                    //4-1)
                    URL url = new URL(getAddress); //url은 받아 들이는 것(인풋)만 할 수 있음
                    //url.openStream() // URL은 inputStream만 열수 있음
                    // 4-2) 그래서 outputStream까지 하는 Http 통신용 객체를 이용해야함

                    HttpURLConnection connection = (HttpURLConnection)url.openConnection();
                    connection.setRequestMethod("GET"); //무조건 대문자로 적어야함(equls문으로 되어 있어서)
                    connection.setDoInput(true);    //서버의 에코 응답을 받아야해서
                    //connection.setDoOutput(); // 얜 안써도 됨 이미 주소 뒤에 값 붙어서 가기 떄문에 안써도 됨
                    connection.setUseCaches(false); //Caches 는 작은 서랍 공간인데 이걸 쓰면 값이 이전게 넘어갈 수 있어서 false 권장

                    //GET방식은 이미 url에 데이터가 추가되어 별도로 setDoOutput이 필요하지 않는다

                    //5. 서버로 부터 응답된 결과를 받아보기 위해
                    InputStream is = connection.getInputStream();
                    InputStreamReader isr = new InputStreamReader(is);
                    BufferedReader reader = new BufferedReader(isr); //글씨 한줄씩

                    StringBuffer buffer = new StringBuffer();
                    while (true) {
                        String line = reader.readLine();
                        if(line==null) break;

                        buffer.append(line+"\n");
                    }

                    runOnUiThread(() -> {
                        mainBinding.tv.setText(buffer.toString());
                    });
                    
                } catch (MalformedURLException e) {
                    throw new RuntimeException(e);
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }

            }
        }.start();
    }
}

php에서 데이터 받기

<?php

    header("Content-Type:text/plain; charset=utf-8");

    //안드로이드로부터 get방식으로 전달된 데이터 받기
    $name = $_GET['name'];
    $message = $_GET['msg'];

    //잘 받았는지 안드로이 쪽으로 응답해주기(echo)
    echo "이름 : $name \n";
    echo "메세지 : $message";
?>



[2]POST 방식

MainActivity.java

  1. 서버로 보낼 데이터 부르기
  2. Post방식으로 데이터 보낼 서버 주소 준비
  3. 서버와 통신
    3-1) 해임달(URL) 준비
    3-2) Http통신을 객체를 만들기 & 4가지 set
    3-3) 보낸 데이터를 POST방식으로 쓰기 위해 [key=value]규칙에 맞게 하나의 문자열로 결합
  4. 데이터를 아웃풋 스트림을 이용해서 직접 내보내기
  5. 서버(postText.php)에서 에코한 응답문자열 읽어오기
package com.bsj0420.ex82httprequst;

import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.os.Bundle;
import android.widget.EditText;

import com.bsj0420.ex82httprequst.databinding.ActivityMainBinding;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;

public class MainActivity extends AppCompatActivity {

    ActivityMainBinding mainBinding;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //setContentView(R.layout.activity_main);

        mainBinding = ActivityMainBinding.inflate(getLayoutInflater());
        setContentView(mainBinding.getRoot());
        
        mainBinding.btnPost.setOnClickListener(v->clickPost());

    }

    private void clickPost() {

        new Thread(){
            @Override
            public void run() {

                //1.서버로 보낼 데이터 부르기
                String name= mainBinding.etName.getText().toString();
                String msg= mainBinding.etMsg.getText().toString();

                //2.Post방식으로 데이터 보낼 서버 주소 준비
                String serverAdress = "http://mrhisj23.dothome.co.kr/Android/postTest.php";

                //3.서버와 통신
                //3-1. 해임달(URL) 준비
                try {
                    URL url = new URL(serverAdress);
                    
                    //3-2. Http통신을 객체를 만들기 & 4가지 set
                    HttpURLConnection connection = (HttpURLConnection)url.openConnection();
                    connection.setRequestMethod("POST");
                    connection.setDoInput(true);
                    connection.setDoOutput(true);
                    connection.setUseCaches(false);
                    
                    //3-3. 보낸 데이터를 POST방식으로 쓰기 위해 [key=value]규칙에 맞게 하나의 문자열로 결합
                    String data = "name="+name+"&msg="+msg;

                    //4. 데이터를 아웃풋 스트림을 이용해서 직접 내보내기
                    OutputStream os = connection.getOutputStream();
                    OutputStreamWriter writer = new OutputStreamWriter(os); //

                    writer.write(data,0,data.length()); //1024를 넘지 않는 사이즈로 만드는 게 좋다
                    writer.flush();
                    writer.close();

                    //5. 서버(postText.php)에서 에코한 응답문자열 읽어오기
                    InputStream is = connection.getInputStream();
                    InputStreamReader isr = new InputStreamReader(is);
                    BufferedReader reader = new BufferedReader(isr);

                    StringBuffer buffer = new StringBuffer();

                    while (true) {
                        String line = reader.readLine();
                        if(line==null) break;

                        buffer.append(line+"\n");
                    }

                    runOnUiThread(()->{
                        mainBinding.tv.setText(buffer.toString());
                    });

                } catch (MalformedURLException e) {
                    throw new RuntimeException(e);
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }

            }
        }.start();

    }

}

php에서 데이터 받기

<?php
    header('Content-Type:text/plain; charset=utf-8'); //안드로이드랑 연결할 땐 text/plain

    //안드로이드로부터 POST방식으로 저달 된 데이터 받기
    $name = $_POST['name'];
    $message = $_POST['msg'];

    //잘 받았는 지 안드로이드로 [응답: response]
    echo "$name : $message";
?>



[3]DB에 저장 by POST

MainActivity.java

  1. 서버로 보낼 데이터 부르기
  2. Post방식으로 데이터 보낼 서버 주소 준비
  3. 서버와 통신
    3-1) 해임달(URL) 준비
    3-2) Http통신을 객체를 만들기 & 4가지 set
    3-3) 보낸 데이터를 POST방식으로 쓰기 위해 [key=value]규칙에 맞게 하나의 문자열로 결합
  4. 데이터를 아웃풋 스트림을 이용해서 직접 내보내기
  5. 서버(postText.php)에서 에코한 응답문자열 읽어오기
package com.bsj0420.ex82httprequst;

import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.os.Bundle;
import android.widget.EditText;

import com.bsj0420.ex82httprequst.databinding.ActivityMainBinding;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;

public class MainActivity extends AppCompatActivity {

    ActivityMainBinding mainBinding;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //setContentView(R.layout.activity_main);

        mainBinding = ActivityMainBinding.inflate(getLayoutInflater());
        setContentView(mainBinding.getRoot());
        
        mainBinding.btnPost.setOnClickListener(v->clickPost());

    }

    private void clickPost() {

        new Thread(){
            @Override
            public void run() {

                //1.서버로 보낼 데이터 부르기
                String name= mainBinding.etName.getText().toString();
                String msg= mainBinding.etMsg.getText().toString();

                //2.Post방식으로 데이터 보낼 서버 주소 준비
                String serverAdress = "http://mrhisj23.dothome.co.kr/Android/postTest.php";

                //3.서버와 통신
                //3-1. 해임달(URL) 준비
                try {
                    URL url = new URL(serverAdress);
                    
                    //3-2. Http통신을 객체를 만들기 & 4가지 set
                    HttpURLConnection connection = (HttpURLConnection)url.openConnection();
                    connection.setRequestMethod("POST");
                    connection.setDoInput(true);
                    connection.setDoOutput(true);
                    connection.setUseCaches(false);
                    
                    //3-3. 보낸 데이터를 POST방식으로 쓰기 위해 [key=value]규칙에 맞게 하나의 문자열로 결합
                    String data = "name="+name+"&msg="+msg;

                    //4. 데이터를 아웃풋 스트림을 이용해서 직접 내보내기
                    OutputStream os = connection.getOutputStream();
                    OutputStreamWriter writer = new OutputStreamWriter(os); //

                    writer.write(data,0,data.length()); //1024를 넘지 않는 사이즈로 만드는 게 좋다
                    writer.flush();
                    writer.close();

                    //5. 서버(postText.php)에서 에코한 응답문자열 읽어오기
                    InputStream is = connection.getInputStream();
                    InputStreamReader isr = new InputStreamReader(is);
                    BufferedReader reader = new BufferedReader(isr);

                    StringBuffer buffer = new StringBuffer();

                    while (true) {
                        String line = reader.readLine();
                        if(line==null) break;

                        buffer.append(line+"\n");
                    }

                    runOnUiThread(()->{
                        mainBinding.tv.setText(buffer.toString());
                    });

                } catch (MalformedURLException e) {
                    throw new RuntimeException(e);
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }

            }
        }.start();

    }

}

php에서 db에 저장 by insert

① 디비 서버에 접속 (주소,아이디,비번,디비이름)
② 한글깨짐 방지
③ 원하는 CRUD 작업의 쿼리문 작성
④ 실행
⑤ db 연결 닫기

<?php
    header('Content-Type:text/plain; charset=utf-8'); //안드로이드랑 연결할 땐 text/plain

    //안드로이드로부터 POST방식으로 저달 된 데이터 받기
    $name = $_POST['name'];
    $message = $_POST['msg'];

    //잘 받았는 지 안드로이드로 [응답: response]
    echo "$name : $message";

    //게시글이 저장되 시간 
    $now = date("Y-m-d H:i:s");

    //Mysql DB board2 테이블에 데이터 저장
    //1. 디비 서버에 접속 (주소,아이디,비번,디비이름)
    $db = mysqli_connect('localhost','아이디','비번','디비이름');

    //2. 한글깨짐 방지
    mysqli_query($db,'set names utf8');
    
    //3. 원하는 CRUD 작업의 쿼리문
    $sql = "INSERT INTO board2 (name, msg, date) VALUES ('$name', '$message', '$now')";

    //4. 실행
    $result = mysqli_query($db, $sql);

    if ($result) echo "\n성공";
    else echo "\n실패";

    //5. db 연결 닫기
    mysqli_close($db);

?>



[4] DB값 CSV 파싱


MainActivity.java

버튼 클릭하면 Board.class로 이동

package com.bsj0420.ex82httprequst;

import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.os.Bundle;
import android.widget.EditText;

import com.bsj0420.ex82httprequst.databinding.ActivityMainBinding;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;

public class MainActivity extends AppCompatActivity {

    ActivityMainBinding mainBinding;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //setContentView(R.layout.activity_main);

        mainBinding = ActivityMainBinding.inflate(getLayoutInflater());
        setContentView(mainBinding.getRoot());
        
        //DB에 있는 데이터 읽어오기
        mainBinding.btnLoad.setOnClickListener(v->{
            Intent intent = new Intent(this, BoardActivity.class);
            startActivity(intent);
            intent = null;
        });

    }

}

activity_board.xml

리사이클뷰에 DB 데이터 불러오기

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="16dp"
    tools:context=".BoardActivity">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recycler"
        app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</RelativeLayout>

rectcler_item.xml

DB에서 불러 온 데이터 붙일 뷰

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:padding="16dp"
    android:layout_marginTop="8dp"
    android:layout_marginBottom="8dp">

    <TextView
        android:id="@+id/tv_no"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:hint="1"
        android:textColor="@color/purple_700"
        android:textStyle="bold"
        android:textSize="20sp"
        android:padding="8dp"/>

    <TextView
        android:id="@+id/tv_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@+id/tv_no"
        android:hint="name"
        android:textColor="@color/purple_700"
        android:textStyle="bold"
        android:textSize="20sp"
        android:padding="8dp"/>

    <TextView
        android:id="@+id/tv_msg"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/tv_no"
        android:hint="메세지"
        android:textColor="@color/black"
        android:padding="8dp"/>

    <TextView
        android:id="@+id/tv_date"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:hint="2023-03-14 13:23:11"
        android:textSize="12sp"
        android:textColor="@color/black"
        android:padding="8dp"/>

</RelativeLayout>

item.java

ArrayList가 끌고 다닐 item 객체

package com.bsj0420.ex82httprequst;

import java.sql.Timestamp;

public class Item {

    int no;
    String name;
    String msg;
    String date;

    public Item() {
    }

    public Item(int no, String name, String msg, String date) {
        this.no = no;
        this.name = name;
        this.msg = msg;
        this.date = date;
    }
}

Adapter.java

리사이클러 뷰에 붙을 item_layout.xml을 inflate 하는 부분

package com.bsj0420.ex82httprequst;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import com.bsj0420.ex82httprequst.databinding.RecyclerItemBinding;

import java.util.ArrayList;

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.VH> {

    Context context;
    ArrayList<Item> items;

    public MyAdapter(Context context, ArrayList<Item> items) {
        this.context = context;
        this.items = items;
    }

    @NonNull
    @Override
    public VH onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View itemView = LayoutInflater.from(context).inflate(R.layout.recycler_item,parent,false);
        return new VH(itemView);
    }

    @Override
    public void onBindViewHolder(@NonNull VH holder, int position) {
        Item item = items.get(position);

        holder.binding.tvNo.setText(item.no+"");
        holder.binding.tvName.setText(item.name);
        holder.binding.tvMsg.setText(item.msg);
        holder.binding.tvDate.setText(item.date);
    }

    @Override
    public int getItemCount() {
        return items.size();
    }

    class VH extends RecyclerView.ViewHolder {

        RecyclerItemBinding binding;

        public VH(@NonNull View itemView) {
            super(itemView);

            binding = RecyclerItemBinding.bind(itemView);

        }
    }

}

BoardActivity.java

구분자 기준으로 split 하여 데이터를 파싱한다!!!

package com.bsj0420.ex82httprequst;

import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.os.Bundle;
import android.util.Log;

import com.bsj0420.ex82httprequst.databinding.ActivityBoardBinding;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;

public class BoardActivity extends AppCompatActivity {

    ActivityBoardBinding binding;

    //대량의 데이타
    ArrayList<Item> items = new ArrayList<>();
    MyAdapter adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //setContentView(R.layout.activity_board);

        binding = ActivityBoardBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());

        adapter = new MyAdapter(this,items);
        binding.recycler.setAdapter(adapter);

    }

    @Override
    protected void onResume() {
        super.onResume();
        //onCreate는 한번만 불러지니까 여기에서 데이타 부른다
        loadData(); //서버에서 데이타 불러오도록
    }

    private void loadData() {

        //테스트 데이터 추가해보기
        //items.add(new Item(0,"sam","aaaaa","2023"));
        //adapter.notifyDataSetChanged(); //데이타가 바뀐거 알려주기

        //서버 DB에 저장된 데이터 읽어오기
        //네트워크 작업

        new Thread(){

            @Override
            public void run() {
                //서버 db값을 에코 해주는 php 문서 실행
                String serverAdress = "http://mrhisj23.dothome.co.kr/Android/loadDB.php";

                try {
                    URL url = new URL(serverAdress);

                    HttpURLConnection connection = (HttpURLConnection)url.openConnection();

                    connection.setRequestMethod("GET");
                    connection.setDoInput(true);
                    connection.setUseCaches(false);

                    InputStream is = connection.getInputStream();

                    InputStreamReader isr = new InputStreamReader(is);
                    BufferedReader reader = new BufferedReader(isr);

                    StringBuffer buffer = new StringBuffer();

                    while (true) {
                        String line = reader.readLine();
                        if(line == null) break;

                        buffer.append(line+"\n");
                    }

                    //잘 읽어 왔는지 확인용
//                    runOnUiThread(() -> {
//                        new AlertDialog.Builder(BoardActivity.this).setMessage(buffer.toString()).create().show();
//                    });
                    
                    //CSV 파싱 기법
                    //서버에서 에코 된 문자열 데이터에서 "&" 문자 기준으로 문자열 분리
                    //한줄 단위(item) 으로 데이타 분리
                    String[] rows = buffer.toString().split("&");

                    Log.i("TAG",rows.length + "");

                    //한줄 데이터의 , 구분자를 분리하여 값을 분석하기
                    for(String row : rows){
                        String[] datas =row.split(",");

                        if(datas.length != 4) continue; //컴럼이 4개가 안되면 넘어가라

                        int no = Integer.parseInt(datas[0]);
                        String name = datas[1];
                        String msg = datas[2];
                        String date = datas[3];

                        items.add(new Item(no,name,msg,date));
                    }

                    runOnUiThread(()->{
                        adapter.notifyDataSetChanged(); //리사이클러뷰에 화면 갱신
                    });

                } catch (MalformedURLException e) {
                    throw new RuntimeException(e);
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }

        }.start();

    }
}

php by selectAll

<?php

    header('Content-Type:text/plain; charset=utf-8');

    //DB값 읽기
    $db = mysqli_connect('localhost','아이디','비번','디비이름');

    mysqli_query($db, "set names utf8");

    $sql = 'SELECT * FROM board2';

    $result = mysqli_query($db,$sql);

    //총 레코드 수
    $rowNum = mysqli_num_rows($result);

    //그 로우의 개수만큼 한줄씩 데이터를 배열로 읽어와서 에코

    for($i=0; $i<$rowNum; $i++){
        $row = mysqli_fetch_array($result, MYSQLI_ASSOC); //연관배열로 읽어옴

        $no = $row['no'];
        $name = $row['name'];
        $msg = $row['msg'];
        $date = $row['date'];

        //콤마로 값들을 구분하는 구분자를 붙이기[csv파일 형식]
        echo $no .','. $name .','. $msg .','. $date . '&';

    }

    mysqli_close($db);

?>



[5]JSON 파싱

  • JSON의 시작이 {} 되어 있으면 JSONObject
  • JSON의 시작이 [{}, {}, {}] 되어 있으면 JSONArray

1. php 에서 파싱하는 방법

<?php

    header('Content-Type:application/json; charset=utf-8'); 

    //DB값 읽기
    $db = mysqli_connect('localhost','아이디','비번','디비이름');

    mysqli_query($db, "set names utf8");

    $sql = 'SELECT * FROM board2';

    $result = mysqli_query($db,$sql);

    //총 레코드 수
    $rowNum = mysqli_num_rows($result);

    $rows = array(); //빈 배열
    for($i=0; $i<$rowNum; $i++){
        $row = mysqli_fetch_array($result, MYSQLI_ASSOC);

        $rows[$i] = $row; //빈 배열에 배열을 넣음 - 2차원 배열로 변경

    }
    //곧바로 연관배열을 json 문법으로 변환하는 기능 있다 : json_encode
    echo json_encode($rows); //=> [{}, {}] 로 보임

?>

2. Json 파싱 예제

  • php연동 후 파싱해야 하지만 그냥 가볍게 사용방법 확인을 위해 안드로이드 스튜디오에서 test용 json만들고 실습해보기

assets 폴더

내 맘대로 폴더 만들 수 있는 곳

2-1) json parsing

assets 폴더에 테스트용 file 생성

{"name" : "sam", "msg" :  "hello", "age" : 20, "address" : {"nation": "korea", "city": "seoul"}}

Main.java

package com.bsj0420.ex83jsonparsing;

import androidx.appcompat.app.AppCompatActivity;

import android.content.res.AssetManager;
import android.os.Bundle;

import com.bsj0420.ex83jsonparsing.databinding.ActivityMainBinding;

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

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;

public class MainActivity extends AppCompatActivity {

    ActivityMainBinding binding;

    ArrayList<Item> items = new ArrayList<>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //setContentView(R.layout.activity_main);

        binding = ActivityMainBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());

        binding.btn.setOnClickListener(v->clickBtn());

    }

    private void clickBtn() {

        //assets 폴더의 파일을 가져오기 위해 창고 관리자 소환
        AssetManager assetManager = getAssets();

        //assets/aaa.json 파일 읽어오기 위한 InputStream
        try {
            InputStream is = assetManager.open("aaa.json");
            InputStreamReader isr = new InputStreamReader(is);
            BufferedReader reader = new BufferedReader(isr);

            StringBuffer buffer = new StringBuffer();
            while (true) {
                String line = reader.readLine();
                if(line==null) break;

                buffer.append(line+"\n");
            }

            String jsonStr = buffer.toString();
            //읽어온 제이슨 문자열 확인
            //binding.tv.setText(jsonStr);

            //제이슨 문자열 분석(parse)
            //JSONObject : 시작이 {} 면 bject
            //JSONArray; //시작이 []면 어레이
            JSONObject jo = new JSONObject(jsonStr);
            String name = jo.getString("name");
            String msg = jo.getString("msg");
            int age = jo.getInt("age");

            JSONObject address=jo.getJSONObject("address");
            String nation = address.getString("nation");
            String city = address.getString("city");

            binding.tv.setText(name + "\n" + msg);


        } catch (IOException e) {
            throw new RuntimeException(e);
        } catch (JSONException e) {
            throw new RuntimeException(e);
        }

    }
}

2-2) json array parsing


assets 폴더에 테스트용 file 생성

[
  {"no": 1, "name": "sam", "msg": "hello"},
  {"no": 2, "name": "robin", "msg": "nice"},
  {"no": 3, "name": "hong", "msg": "Good"}
]

jsonArray를 하나로 담기 위한 class 준비

package com.bsj0420.ex83jsonparsing;

public class Item {

    int no;
    String name;
    String msg;

    public Item() {
    }

    public Item(int no, String name, String msg) {
        this.no = no;
        this.name = name;
        this.msg = msg;
    }
}

Main.java

package com.bsj0420.ex83jsonparsing;

import androidx.appcompat.app.AppCompatActivity;

import android.content.res.AssetManager;
import android.os.Bundle;

import com.bsj0420.ex83jsonparsing.databinding.ActivityMainBinding;

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

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;

public class MainActivity extends AppCompatActivity {

    ActivityMainBinding binding;

    ArrayList<Item> items = new ArrayList<>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //setContentView(R.layout.activity_main);

        binding = ActivityMainBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());

        binding.btnArr.setOnClickListener(v->clickBtnArr());

    }

    private void clickBtnArr() {

        AssetManager assetManager = getAssets();
        try {
            InputStream is = assetManager.open("array.json");
            InputStreamReader isr = new InputStreamReader(is);
            BufferedReader reader = new BufferedReader(isr);

            StringBuffer buffer = new StringBuffer();
            while (true) {
                String line = reader.readLine();
                if(line==null) break;

                buffer.append(line+"\n");
            }

            binding.tv.setText(buffer.toString());

            //분석
            JSONArray array = new JSONArray(buffer.toString());

            for(int i=0; i < array.length(); i++){
                JSONObject jo = array.getJSONObject(i);

                int no = jo.getInt("no");
                String name = jo.getString("name");
                String msg = jo.getString("msg");

                items.add(new Item(no,name,msg));
            }

            //확인
            binding.tv.setText("아이템 개수: " + items.size());

        } catch (IOException e) {
            throw new RuntimeException(e);
        } catch (JSONException e) {
            throw new RuntimeException(e);
        }

    }
}



[6] Gson 라이브러리 ★★★★★

  • 제이슨 문자열을 분석하여 '객체'로 생성

  • 변수 이름과 json의 key값이 같아야함

  • Gson 라이브러리 추가

1) gson library parse

package com.bsj0420.ex84gsonlib;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;

import com.bsj0420.ex84gsonlib.databinding.ActivityMainBinding;
import com.google.gson.Gson;

public class MainActivity extends AppCompatActivity {

    ActivityMainBinding binding;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //setContentView(R.layout.activity_main);

        binding = ActivityMainBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());

        binding.btn.setOnClickListener(v-> clickBtn());

    }


    private void clickBtn() {
        //Gson이라는 라이브러리 이용하여 편하게 제이슨 문자열을 분석하여 '객체'로 생성

        //json 문자열 test용 으로 만들기
        String jsonStr = "{'name':'sam' , 'age':20}";
    
        //GSON 이용하기
        //name, age를 멤버로 가지는  Person 클래스 객체로 분석하여 변환
        Gson gson = new Gson();
        Person person = gson.fromJson(jsonStr, Person.class); //(값,클래스 정보)

        binding.tv.setText(person.name + " : " + person.age);
    }
}

2) Object to JSON

package com.bsj0420.ex84gsonlib;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;

import com.bsj0420.ex84gsonlib.databinding.ActivityMainBinding;
import com.google.gson.Gson;

public class MainActivity extends AppCompatActivity {

    ActivityMainBinding binding;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //setContentView(R.layout.activity_main);

        binding = ActivityMainBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());

        binding.btn2.setOnClickListener(v-> clickBtn2());

    }

    private void clickBtn2() {
        //Person 객체를 json 문자열
        Person person = new Person("robin",25);
        Gson gson = new Gson();

        String jsonStr = gson.toJson(person);
        binding.tv.setText(jsonStr);

    }


}

3) JSONArray to Object Array

package com.bsj0420.ex84gsonlib;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;

import com.bsj0420.ex84gsonlib.databinding.ActivityMainBinding;
import com.google.gson.Gson;

public class MainActivity extends AppCompatActivity {

    ActivityMainBinding binding;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //setContentView(R.layout.activity_main);

        binding = ActivityMainBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());

        binding.btn3.setOnClickListener(v-> clickBtn3());
    }

    private void clickBtn3() {
        //제이슨 어레이를 Person object Array로  변환
        String jsonStr = "[{'name':'kim', 'age': 21},{'name':'lee', 'age': 28}]";

        Gson gson = new Gson();
        Person[] people = gson.fromJson(jsonStr, Person[].class);

        binding.tv.setText("객체 수 : "+ people.length);

    }
profile
보조기억장치

0개의 댓글