Skip to content

Files

Latest commit

author
SieunSong
Aug 30, 2018
a968950 ยท Aug 30, 2018

History

History
571 lines (425 loc) ยท 18 KB

JSON_sieun.md

File metadata and controls

571 lines (425 loc) ยท 18 KB

JSON

๋ฐœํ‘œ์ฃผ์ œ : JSON

๋ฐœํ‘œ์ผ์ž : 2018-08-06 (์›”)

๋ฐœํ‘œ์ž : ์†ก์‹œ์€

[TOC]

0. ์ฐธ๊ณ ๋ฌธ์„œ

๋  ๋•Œ๊นŒ์ง€ ์•ˆ๋“œ๋กœ์ด๋“œ[์˜ค์ค€์„ ์ง€์Œ] : 22์žฅ ๋„คํŠธ์›Œํฌ ํ†ต์‹ 

1. HTTP ํ†ต์‹ 

์ž๋ฐ”์—์„œ์˜ ๋„คํŠธ์›Œํฌ ํ†ต์‹ ์€ HttpURLConnection ๊ฐ์ฒด๋ฅผ ํ†ตํ•œ ๋ฐฉ๋ฒ•์ด ์ผ๋ฐ˜์ ์ด๋‹ค.

1.1. ์‹ค์Šต

  • AndroidManifest.xml ํŒŒ์ผ์— INTERNET ๊ถŒํ•œ์„ ์ถ”๊ฐ€ํ•œ๋‹ค.
<uses-permission android:name="android.permission.INTERNET"/>
  • ์†Œ์Šค๋ฅผ ์ฝ์–ด์˜ค๋Š” ํด๋ž˜์Šค ์ž‘์„ฑ

์•ˆ๋“œ๋กœ์ด๋“œ์—์„œ๋Š” ์ž๋ฐ”์™€ ๋‹ค๋ฅด๊ฒŒ ๋„คํŠธ์›Œํฌ ํ†ต์‹ ์€ ๋ฐ˜๋“œ์‹œ ์ž‘์—… ์Šค๋ ˆ๋“œ์—์„œ ์ˆ˜ํ–‰ํ•ด์•ผ ํ•˜๋Š” ์ œ์•ฝ์ด ์žˆ๋‹ค. ๋”ฐ๋ผ์„œ ๋น„๋™๊ธฐ ๋„คํŠธ์›Œํฌ ํ†ต์‹ ์„ ํ•˜๋Š” AsycnTask ๋ฅผ ์ž‘์„ฑํ•ด์•ผ ํ•œ๋‹ค.

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // ์†Œ์Šค๋ฅผ ํ™•์ธํ•˜๊ณ  ์‹ถ์€ ์‚ฌ์ดํŠธ ์ฃผ์†Œ
        new HttpAsyncTask().execute("http://[์ฃผ์†Œ]");
    }

    private static class HttpAsyncTask extends AsyncTask<String, void, String> {
        @Override
        protected String doInBackground(String... params) {
            String result = null;
            String strUrl = params[0];
            try {
                // URL ๊ฐ์ฒด ์ƒ์„ฑ
                URL url = new URL(strUrl);
                // URL ์„ ์—ฐ๊ฒฐํ•œ ๊ฐ์ฒด ์ƒ์„ฑ
                HttpURLConnection connection = (HttpURLConnection) url.openConnection();
                connection.setRequestMethod("GET");     // GET ๋ฐฉ์‹ ํ†ต์‹ 
                connection.setDoOutput(true);           // ์“ฐ๊ธฐ ๋ชจ๋“œ
                connection.setDoInput(true);            // ์ฝ๊ธฐ ๋ชจ๋“œ
                connection.setUseCaches(false);         // ์บ์‹œ ์‚ฌ์šฉ
                connection.setDefaultUseCaches(false);
                // ์ž…๋ ฅ ์ŠคํŠธ๋ฆผ ์—ด๊ธฐ
                InputStream inputStream = connection.getInputStream();
                // ๋ฌธ์ž์—ด ์ €์žฅ ๊ฐ์ฒด
                StringBuilder builder = new StringBuilder();
                // UTF-8 ๋ฐฉ์‹์œผ๋กœ ์ž…๋ ฅ๋ฐ›์€ ์ŠคํŠธ๋ฆผ์„ ์ฝ์–ด๋“ค์ด๋Š” ๋ฒ„ํผ ๊ฐ์ฒด
                BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
                // ํ•œ ์ค„์”ฉ ๋ฌธ์ž์—ด์„ ์ฝ์–ด๋“ค์ด๊ธฐ
                String line;
                while ((line = reader.readLine()) != null) {
                    builder.append(line + "\n");
                }
                // ๊ฒฐ๊ณผ
                result = builder.toString();
            } catch (MalformedURLException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return result;
        }

        @Override
        protected void onPostExecute(String s) {
            super.onPostExecute(s);
            if (s != null) {
                Log.d("HttpAsyncTask", s);
            }
        }
    }
}

HttpURLConnection์„ ์‚ฌ์šฉํ•˜์—ฌ GET ๋ฐฉ์‹์œผ๋กœ ์†Œ์Šค๋ฅผ ์ฝ์–ด์˜ค๋Š” ๊ธฐ๋ณธ์ ์ธ ์ฝ”๋“œ์ด๋‹ค. GET ๋ฐฉ์‹์œผ๋กœ ์›น์‚ฌ์ดํŠธ์˜ ์ฝ”๋“œ๋ฅผ ์ฝ์–ด๋“ค์—ฌ ๋กœ๊ทธ๋กœ ์ถœ๋ ฅํ•˜๋Š” ๊ฐ„๋‹จํ•œ ์ฝ”๋“œ์ง€๋งŒ, ๊ฝค ๋ณต์žกํ•ด ๋ณด์ธ๋‹ค. ์‹ค์ œ๋กœ ์ž๋ฐ”์˜ ๋„คํŠธ์›Œํฌ API๋Š” ์‚ฌ์šฉํ•˜๊ธฐ๊ฐ€ ๊ทธ๋ ‡๊ฒŒ ํŽธํ•˜์ง€๋Š” ์•Š๋‹ค.

2. OkHttp ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ

Http/1.1 ํ†ต์‹ ์˜ ๋ฌธ์ œ์  ์ค‘ ํ•˜๋‚˜๋Š” ์—ฐ๊ฒฐ๋‹น ํ•œ ๋ฒˆ์— ํ•˜๋‚˜์˜ ์š”์ฒญ๊ณผ ์‘๋‹ต๋งŒ ํ—ˆ์šฉํ•œ๋‹ค๋Š” ์ ์ด๋‹ค. ์—ฌ๋Ÿฌ ์š”์ฒญ์„ ๋ณ‘๋ ฌ๋กœ ์ฒ˜๋ฆฌํ•˜๋ ค๋ฉด ๋ธŒ๋ผ์šฐ์ €๋‚˜ ๋‹ค๋ฅธ ํด๋ผ์ด์–ธํŠธ์—์„œ๋Š” ์—ฌ๋Ÿฌ ๊ฐœ์˜ ์†Œ์ผ“์„ ์—ด์–ด์•ผ ํ•˜๋Š”๋ฐ, ์ด๊ฒƒ์€ ํด๋ผ์ด์–ธํŠธ์—์„œ๋Š” ํฐ ๋ฌธ์ œ๊ฐ€ ์•„๋‹ˆ์ง€๋งŒ, ์„œ๋ฒ„ ๊ด€์ ์—์„œ๋Š” ์‹ฌ๊ฐํ•œ ๋ฌธ์ œ์ด๋‹ค. ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด์„œ ๊ตฌ๊ธ€์ด HTTP ํ”„๋กœํ† ์ฝœ ๊ฐœ์„  ์ž‘์—…์„ ์‹œ์ž‘ํ•˜์˜€๊ณ , SPDY(์Šคํ”ผ๋””)๋ผ ๋ถˆ๋ฆฌ๋Š” ์ƒˆ๋กœ์šด ํ”„๋กœํ† ์ฝœ์„ ๊ตฌํ˜„ํ•˜์˜€๋‹ค. SPDY๋Š” HTTP/1.1์— ๋น„ํ•ด ์ƒ๋‹นํ•œ ์„ฑ๋Šฅ ํ–ฅ์ƒ๊ณผ ํšจ์œจ์„ฑ์„ ๋ณด์—ฌ์ฃผ์—ˆ๊ณ , 2015๋…„ ํ‘œ์ค€์ด ๋œ HTTP/2์˜ ๊ธฐ๋ฐ˜์ด ๋œ๋‹ค. OkHttp๋Š” Square์‚ฌ์—์„œ ๊ฐœ๋ฐœํ•œ Http/2์™€ SPDY๋ฅผ ์ง€์›ํ•˜๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ด๋‹ค.

2.1. ์‹ค์Šต

  • build.gradleํŒŒ์ผ์— ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์˜์กด์„ฑ ์ถ”๊ฐ€
dependencies {
	...
    implementation 'com.squareup.okhttp3:okhttp:3.8.1'
}
  • OKHttp ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ ์šฉ
public class MainActivity extends AppCompatActivity {
    private static final String TAG = MainActivity.class.getSimpleName();
    @Override
    protected void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // ์†Œ์Šค๋ฅผ ํ™•์ธํ•˜๊ณ  ์‹ถ์€ ์‚ฌ์ดํŠธ ์ฃผ์†Œ
        new HttpAsyncTask().execute("http://[์ฃผ์†Œ]");
    }
    private static class HttpAsyncTask extends AsyncTask<String, void, String> {
        // OkHttp ํด๋ผ์ด์–ธํŠธ
        OkHttpClient client = new OkHttpClient();
        @Override
        protected String doInBackground(String... params) {
            String result = null;
            String strUrl = params[0];
            try {
                // ์š”์ฒญ
                Request request = new Request.Builder()
                        .url(strUrl)
                        .build();
                // ์‘๋‹ต
                Response response = client.newCall(request).execute();
                Log.d(TAG, "onCreate: " + response.body().string());
            } catch (IOException e) {
                e.printStackTrace();
            }
            return result;
        }
        @Override
        protected void onPostExecute(String s){
            super.onPostExecute(s);
            if (s != null){
                Log.d("HttpAsyncTask", s);
            }
        }
    }
}
  • ๋กœ๊ทธ์บฃ์— ์†Œ์Šค๊ฐ€ ํ‘œ์‹œ๋˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•œ๋‹ค.

OKHttp์˜ ๋™์ž‘ ๋ฐฉ์‹์€ okHttpClient ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•œ ํ›„ newCall() ๋ฉ”์„œ๋“œ์— ์š”์ฒญ ์ •๋ณด๋ฅผ Request ๊ฐ์ฒด๋กœ ์ •์˜ํ•˜์—ฌ ์ „๋‹ฌํ•œ๋‹ค. execute() ๋ฉ”์„œ๋“œ๋Š” ๋™๊ธฐ ๋ฐฉ์‹์œผ๋กœ ๋„คํŠธ์›Œํฌ์— ์ ‘์†ํ•˜๊ณ  ๊ฒฐ๊ณผ๋ฅผ Response ๊ฐ์ฒด๋กœ ์‘๋‹ต๋ฐ›๋Š”๋‹ค. ์‘๋‹ต์—๋Š” Header์™€ Body ๋“ฑ์˜ ์ •๋ณด๊ฐ€ ๋‹ด๊ฒจ ์žˆ๋‹ค.

์ด์ฒ˜๋Ÿผ OKHttp๋Š” ๊ฐ„๋‹จํ•˜๊ฒŒ GET/POST ๋ฐฉ์‹์œผ๋กœ HTTP ํ†ต์‹ ์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค€๋‹ค. ๋™๊ธฐ/๋น„๋™๊ธฐ ๋ฐฉ์‹์„ ๋ชจ๋‘ ์ง€์›ํ•˜๋ฉฐ, ์ฝ”๋“œ๋„ ๊ฐ„๊ฒฐํ•ด์ง„๋‹ค. ์•ˆ๋“œ๋กœ์ด๋“œ 2.3 ์ด์ƒ์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์ž๋ฐ” SDK 7 ์ด์ƒ์—์„œ ๋™์ž‘ํ•œ๋‹ค.

3. JSON ํŒŒ์‹ฑ

3.1. ์ •์˜

Json(Javascript Object Notation) : javascript ์–ธ์–ด์—์„œ ์‚ฌ์šฉ๋˜๊ธฐ ์‹œ์ž‘ํ•œ ๊ฒฝ๋Ÿ‰ ๋ฐ์ดํ„ฐ ๊ตํ™˜ ํ˜•์‹

https://github.com/taeiim/Android-Study/blob/master/study/week10/json์˜%20ํ˜•ํƒœ.PNG

  • ์œ„์™€ ๊ฐ™์€ ํ˜•ํƒœ์˜ ๋ฐ์ดํ„ฐ๋ฅผ Json์ด๋ผ๊ณ  ํ•œ๋‹ค.
  • Json ํฌ๋งท์—์„œ []๋Š” ๋ฐฐ์—ด์„ ๋‚˜ํƒ€๋‚ด๋ฉฐ, {}๋Š” ๊ฐ์ฒด๋ฅผ ๋‚˜ํƒ€๋‚ธ๋‹ค.
  • ์ž๋ฃŒ๊ตฌ์กฐ์˜ Map๊ณผ ๊ฐ™์€ ๊ตฌ์กฐ์ด๋‹ค.
  • ์•ˆ๋“œ๋กœ์ด๋“œ์—์„œ JSON ๊ฐ์ฒด๋ฅผ ๋‹ค๋ฃจ๋ ค๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.
    • JSONObject JSON ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ด์„ ์ˆ˜ ์žˆ๋Š” ๊ฐ์ฒด
    • JSONArray JSONObject๋ฅผ ์—ฌ๋Ÿฌ ๊ฐœ ๋‹ด์„ ์ˆ˜ ์žˆ๋Š” ๋ฆฌ์ŠคํŠธ ๊ฐ์ฒด

3.2. ํŠน์ง•

  • Json์€ XML๊ณผ ๋”๋ถˆ์–ด ๋ฐ์ดํ„ฐ ํ˜•์‹์œผ๋กœ ๊ฐ€์žฅ ๋งŽ์ด ์‚ฌ์šฉ๋˜๊ณ  ์žˆ์œผ๋ฉฐ, XML๋ณด๋‹ค ๊ฐ„๊ฒฐํ•˜๊ณ  ์ดํ•ดํ•˜๊ธฐ ์‰ฝ๋‹ค.
  • Json์€ ์‹ค์ œ ๋ฐ์ดํ„ฐ์— ์ง‘์ค‘ํ•˜๋ฏ€๋กœ ์ „์†ก๋˜๋Š” ๋ฐ์ดํ„ฐ์˜ ์šฉ๋Ÿ‰์ด ์ ๋‹ค.
  • ๋ฐ์ดํ„ฐ๋ฅผ ๋ถ„์„ํ•ด์„œ ์‚ฌ์šฉํ•˜๊ธฐ ํŽธํ•œ ํŒŒ์‹ฑ๋„ ๋น„๊ต์  ์‰ฝ๋‹ค.

3.3. ์‹ค์Šต

  • ๋ชจ๋ธํด๋ž˜์Šค ์ž‘์„ฑ
public class Weather {
    private String country;
    private String weather;
    private String temperature;

    public Weather(String country, String weather, String temperature){
        this.country = country;
        this.weather = weather;
        this.temperature = temperature;
    }

    public String getCountry() {
        return country;
    }

    public void setCountry(String country) {
        this.country = country;
    }

    public String getWeather() {
        return weather;
    }

    public void setWeather(String weather) {
        this.weather = weather;
    }

    public String getTemperature() {
        return temperature;
    }

    public void setTemperature(String temperature) {
        this.temperature = temperature;
    }
    
    @Override
    public String toString() {
        final StringBuffer sb = new StringBuffer("Weather{");
        sb.append("country='").append(country).append('\'');
        sb.append(", weather=").append(weather).append('\'');
        sb.append(", temperature=").append(temperature).append('\'');
        sb.append('}');
        return sb.toString();
    }
}
  • JSONObject ๋Œ€์‹  Weather ํด๋ž˜์Šค๋ฅผ ์ด์šฉํ•˜์—ฌ ๋‚ ์”จ ๋ฐ์ดํ„ฐ ๋‹ค๋ฃจ๊ธฐ
public class MainActivity extends AppCompatActivity {
    private static final String TAG = MainActivity.class.getSimpleName();
    @Override
    protected void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // ์†Œ์Šค๋ฅผ ํ™•์ธํ•˜๊ณ  ์‹ถ์€ ์‚ฌ์ดํŠธ ์ฃผ์†Œ
        new HttpAsyncTask().execute("http://[์ฃผ์†Œ]");
    }
    private class HttpAsyncTask extends AsyncTask<String, Void, List<Weather>> {
        // OKHttp ํด๋ผ์ด์–ธํŠธ
        OKHttpClient client = new OKHttpClient();
        @Override
        protected List<Weather> doInBackground(String... params) {
            List<Weather> weatherList = new ArrayList<>();
            String strUrl = params[0];
            try {
                // ์š”์ฒญ
                Request request = new Request.Builder()
                    .url(strUrl)
                    .build();
                // ์‘๋‹ต
                Response response = client.newCall(request).execute();
                JSONArray jsonArray = new JSONArray(resonse.body().string());
                for(int i = 0; l < jsonArray.length(); i++) {
                    JSONObject jsonObject = jsonArray.getJSONObject(i);
                    String country = jsonObject.getString("country");
                    String weather = jsonObject.getString("weather");
                    String temperature = jsonObject.getString("temperature");
                    Weather w = new Weather(country, weather, temperature);
                    weatherList.add(w);
                }
                Log.d(TAG, "onCreate : " + weatherList.toString());
            } catch (IOException e) {
                e.printStackTrace();
            } catch (JSONException e) {
                e.printStackTrace();
            } 
            return weatherList;
        }
        @Override
        protected void onPostExecute(List<Weather> weatherList) {
            super.onPostExecute(weatherList);
            if (weatherList != null) {
                Log.d("HttpAsyncTask", weatherList.toString());
            }
        }
    }
}
  • Weather์˜ ๋ฆฌ์ŠคํŠธ๋ฅผ ๋‹ด์„ ์ˆ˜ ์žˆ๋Š” ์–ด๋Œ‘ํ„ฐ๋ฅผ ์ž‘์„ฑํ•˜๊ณ , ์ด ์–ด๋Œ‘ํ„ฐ๋ฅผ ๋ฆฌ์ŠคํŠธ๋ทฐ์— ์ „๋‹ฌํ•œ๋‹ค.
public class WeatherAdapter extends BaseAdapter {
    private final List<Weather> mList;

    public WeatherAdapter(List<Weather> list) {
        mList = list;
    }

    @Override
    public int getCount() {
        return mList.size();
    }

    @Override
    public Object getItem(int position) {
        return mList.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder;
        if (convertView == null) {
            convertView = LayoutInflater.from(parent.getContext())
                    .inflate(R.layout.item_weather, parent, false);
            holder = new ViewHolder();
            holder.country = (TextView) convertView.findViewById(R.id.country_text);
            holder.weather = (TextView) convertView.findViewById(R.id.weather_text);
            holder.temperature = (TextView) convertView.findViewById(R.id.temperature_text);
            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }
        Weather weather = (Weather) getItem(position);
        holder.country.setText(weather.getCountry());
        holder.weather.setText(weather.getWeather());
        holder.temperature.setText(weather.gettemperature());
        return convertView;
    }

    // ๋ทฐ ํ™€๋” ํŒจํ„ด
    static class ViewHolder {
        TextView country;
        TextView weather;
        TextView temperature;
    }
}
  • HttpAsyncTask์˜ onPostExecute() ๋ฉ”์„œ๋“œ์—์„œ ๋ฆฌ์ŠคํŠธ๋ทฐ๋ฅผ ์กฐ์ž‘ํ•˜๊ธฐ ์œ„ํ•ด ์ฝ”๋“œ ์ˆ˜์ •
... ์ƒ๋žต ...
@Override
        protected void onPostExecute(List<Weather> weatherList){
            super.onPostExecute(weatherList);
            if (weatherList != null){
                Log.d("HttpAsyncTask", weaterList.toString());
                WeatherAdapter adapter = new WeatherAdapter(weatherList);
                mWeaterListView.setAdapter(adapter);
            }
        }
... ์ƒ๋žต ...
}

4. GSON

Gson์€ ๊ตฌ๊ธ€์—์„œ ๊ฐœ๋ฐœํ•œ JSON ๋ฐ์ดํ„ฐ์™€ ์ž๋ฐ” ์˜ค๋ธŒ์ ํŠธ๋ฅผ ์ƒํ˜ธ ๋ณ€ํ™˜ํ•  ์ˆ˜ ์žˆ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ด๋‹ค.

4.1. ํŠน์ง•

  • ์ž๋ฐ”์—์„œ JSON์„ ๋‹ค๋ฃจ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋Š” ๊ทธ ์™ธ์—๋„ Jackson, JSONIC ๋“ฑ ๋‹ค์–‘ํ•˜๋‹ค.

  • Gson์€ ๋‚ด๋ถ€์ ์œผ๋กœ ์ž๋ฐ”์˜ ๋ฆฌํ”Œ๋ž™์…˜์ด๋ผ๋Š” ๊ธฐ๋ฒ•์„ ์‚ฌ์šฉํ•˜๋Š”๋ฐ, ๋ฆฌํ”Œ๋ž™์…˜์€ ์‹คํ–‰์‹œ๊ฐ„ ๋น„์šฉ์ด ๋งŽ์ด ๋“œ๋Š” ๊ธฐ๋ฒ•์ด๋ฏ€๋กœ ์‹คํ–‰์‹œ๊ฐ„์— ๋ฏผ๊ฐํ•œ ์•ฑ์„ ๊ฐœ๋ฐœํ•  ๋•Œ๋Š” ์ ํ•ฉํ•˜์ง€ ์•Š๋‹ค.

4.2. ์‹ค์Šต

  • ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์˜์กด์„ฑ ์ถ”๊ฐ€
dependencies {
    ... ์ƒ๋žต ...
    implementation 'com.google.code.gson:gson:2.8.1'
}
  • MainActivity.java ํŒŒ์ผ ๋‚ด์˜ HttpAsyncTask ํด๋ž˜์Šค์—์„œ JSON ๋ฐ์ดํ„ฐ๋ฅผ ํŒŒ์‹ฑํ•˜๋Š” ๋ถ€๋ถ„์„ Gson์œผ๋กœ ์ˆ˜์ •
private static class HttpAsyncTask extends AsyncTask<String, void, List<Weather>> {
        // OkHttp ํด๋ผ์ด์–ธํŠธ
        OkHttpClient client = new OkHttpClient();
        @Override
        protected String doInBackground(String... params) {
            // JSON ๋ฐ์ดํ„ฐ๊ฐ€ ๋ณ€ํ™˜ ๋  ๊ฐ์ฒด
            List<Weather> weatherList = new ArrayList<>();
            String strUrl = params[0];
            try {
                // ์š”์ฒญ
                Request request = new Request.Builder()
                        .url(strUrl)
                        .build();
                // ์‘๋‹ต
                Response response = client.newCall(request).execute();
                Gson gson = new Gson();
                // Gson ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—์„œ ์ด๋Ÿฌํ•œ ๋ฆฌ์ŠคํŠธ ํƒ€์ž…์„ ์ž๋™์œผ๋กœ ์ž๋ฐ” ๊ฐ์ฒด๋กœ ๋ณ€ํ™˜ํ•˜๋ ค๋ฉด
                // ํƒ€์ž… ๊ฐ์ฒด๋ฅผ ์ง€์ •ํ•ด ์ค˜์•ผ ํ•œ๋‹ค. Type ํด๋ž˜์Šค๋Š” ์—ฌ๋Ÿฌ ํŒจํ‚ค์ง€์— ์žˆ๋Š” ๋ฐ ๊ทธ ์ค‘
                // import java.lang.reflect.Type์„ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค.
                Type listType = new TypeToken<ArrayList<Weather>>() {}.getType();
                // Type์„ fromJson() ๋ฉ”์„œ๋“œ์— ํ•จ๊ป˜ ์ „๋‹ฌํ•˜๋ฉด ์ž๋™์œผ๋กœ ๋ณ€ํ™˜๋œ๋‹ค.
                weatherList = gson.fromJson(response.body().string(), listType);
                Log.d(TAG, "onCreate: " + response.body().string());
            } catch (IOException e) {
                e.printStackTrace();
            }
            return result;
        }
    ... ์ƒ๋žต ...
}

5. Retrofit

Retrofit ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋Š” ๋‚ด๋ถ€์ ์œผ๋กœ๋Š” OKHttp๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด์„œ Gson ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๊ฒฐํ•ฉํ•˜์—ฌ ๋ชจ๋ธ ํด๋ž˜์Šค๋‚˜ List<๋ชจ๋ธ> ํ˜•ํƒœ์˜ ๊ฒฐ๊ณผ๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ด๋‹ค.

5.1. ์‹ค์Šต

  • build.gradle ํŒŒ์ผ์— ์ข…์†์„ฑ ์ถ”๊ฐ€
dependencies {
    ... ์ƒ๋žต ...
    implementation 'com.squareup.retrofit2:retrofit:2.3.0'
    implementation 'com.squareup.retrofit2:converter-gson:2.3.0'
}
  • ์ธํ„ฐํŽ˜์ด์Šค ์ž‘์„ฑ


3.4. ์‘์šฉ

์ด ํด๋ž˜์Šค๋“ค์€ ํŽ˜์ด์Šค๋ถ๊ณผ ๊ฐ™์€ SNS์— ์˜ฌ๋ฆฌ๋Š” ๊ธ€๊ณผ ์‚ฌ์šฉ์ž, ๋Œ“๊ธ€์„ ํ‘œํ˜„ํ•œ๋‹ค.

Post๋Š” User์™€ Comment์˜ List๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค. ๋ณธ ์˜ˆ์ œ๋Š” ์†Œ์Šค๋ฅผ ๊ฐ„๋‹จํ•˜๊ฒŒ ๋ณด์ด๊ณ ์ž getter์™€ setter๋ฅผ ์ƒ๋žตํ•˜๊ณ  ํ•„๋“œ์˜ ๋ฉค๋ฒ„ ๋ณ€์ˆ˜๋“ค์„ public์œผ๋กœ ์„ ์–ธํ•˜์˜€๋‹ค.

  • ์‚ฌ์šฉ์ž ํด๋ž˜์Šค
public class User {
    public String email;
    public String fullname;
    
    public User(String email, String fullname){
        this.email = email;
        this.fullname = fullname;
    }
}
  • ํฌ์ŠคํŠธ ํด๋ž˜์Šค
public class Post {
    public String title;
    public String content;
    public User author;
    public List<Comment> comments;

    public Post(User author, String title, String content) {
        this.comments = new ArrayList<Comment>();
        this.author = author;
        this.title = title;
        this.content = content;
    }
}
  • ๋Œ“๊ธ€ ํด๋ž˜์Šค
public class Comment {
    public String author;
    public String content;
    
    public Comment(String author, String content){
        this.author = author;
        this.content = content;
    }
}
  • ๋ชจ๋ธ ํด๋ž˜์Šค๋ฅผ JSON์œผ๋กœ ๋ณ€ํ™˜

์ž๋ฐ”๋กœ๋ถ€ํ„ฐ JSON์œผ๋กœ ๋ณ€ํ™˜ํ•  ๋•Œ toJson() ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค. ๊ธฐ๋ณธ์ ์œผ๋กœ null์ธ ํ•„๋“œ๋Š” JSON์— ํฌํ•จ๋˜์ง€ ์•Š๋Š”๋‹ค.

public class ToJsonSample {
    public static void main(String[] args) {
        Gson gson = new Gson();
        User user1 = new User("[email protected]", null);   // fullname์— null์„ ์„ค์ •
        User user2 = new User("[email protected]", "jeff");
        List<User> userList = new ArrayList<>();
        userList.add(user1);
        userList.add(user2);
        // Java ๊ฐ์ฒด๋กœ๋ถ€ํ„ฐ JSON์œผ๋กœ ๋ณ€ํ™˜
        System.out.println("์‚ฌ์šฉ์ž : " + gson.toJson(user1));
        // Java ๊ฐ์ฒด๋กœ๋ถ€ํ„ฐ JSON์œผ๋กœ ๋ณ€ํ™˜ : List
        System.out.println("์‚ฌ์šฉ์ž ๋ชฉ๋ก : " + gson.toJson(userList));
        Post newPost = new Post(userList.get(0), "PostTitle", "postContent");
        Comment comment = new Comment("comment_author", "comment_comment");
        newPost.comments.add(comment);
        newPost.comments.add(comment);
        // Java ๊ฐ์ฒด๋กœ๋ถ€ํ„ฐ JSON์œผ๋กœ ๋ณ€ํ™˜ : ํ•„๋“œ์— List๋ฅผ ํฌํ•จํ•˜๋Š” ๊ฐ์ฒด
        System.out.println("๋Œ“๊ธ€์„ ํฌํ•จํ•œ ์ƒˆ ๊ธ€ : " + gson.toJson(newPost));
    }
}
  • JSON์„ ๋ชจ๋ธ ํด๋ž˜์Šค๋กœ ๋ณ€ํ™˜

JSON์„ ์ž๋ฐ” ๊ฐ์ฒด๋กœ ๋ณ€ํ™˜ํ•  ๋•Œ๋Š” fromJson() ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.