JSON

Jan 30, 2024
JSON

[ JSON (JavaScript Object Notation) ]

1-1. JSON 이란?

notion image
notion image
그림에서 붉은 글자 파트 영어가 json. = 공용어! 즉, json은 공용어! 사용하기 편하게 자기의 언어로 바꿔서(번역해서) 사용.
💡
JSON을 내 오브젝트로 바꾸는 방법만 알면 현시대의 통신은 끝!
 

 
자바 스크립트 객체를 표현하는 데이터 형식 (= 자바 스크립트의 Object(객체) 표기법) (= 자바 스크립트처럼 생긴 데이터 표기법) 가볍기 때문에 주로 데이터 전송 및 통신 목적으로 사용된다. (서버와 클라이언트 간에 데이터를 주고받을 때, 일반적으로 JSON 형식을 사용) (json은 경량. 제일 가벼움)
💡
[ application/json ] 이라고 헤더에 꼭!!! 적어줘야 한다. MIME ’나 지금 제이슨 던져~~!’ 하고 알려줘야 함!
 

 
객체는 중괄호({})로 묶여 있으며, 키와 값의 쌍으로 구성된다. 키는 문자열, 값은 문자열·숫자·불리언·배열·다른 객체 등 다양한 데이터 형식을 가질 수 있다.
notion image
키 값 = String / 값 = int, String, boolean 타입으로 이루어져 있는 JSON
 

1-2. os레벨로 내려가려면 그냥 무조건 문자열로 변환

let user = { id : 1, username:"ssar", hobby: ["축구", "농구"], //동일한 데이터 타입이 연속적임. 즉, 이건 벡터. 배열, list 이 배열의 하나의 타입이 String이란 것 board { id: 1, title: "제목" } //오브젝트. 자바로 치면 클래스 consol.log(user.hobby[0]);
해당 코드는 js에서 작성한 건데, 이 오브젝트가 자바에 들어올 땐 모두 '문자로 변환' 되어서 들어간다.
 

★ 기본 상식 ^^
통신으로 무슨 데이터가 날아가든 다 문자열로 넘어간다. os레벨로 내려가려면 그냥 무조건 문자열로 변환이 된다. 모든게. (바이트로 내려가잖아. 바이트가 연속적으로 내려가잖아. 문자열이 내려가는거임) int도 boolean도 배열도 다른 객체도 문자열로 죄다 변해서 내려감 상대방이 읽을 때, (= 버퍼에 담긴 데이터를 while로 읽을 때) 문자열로 읽어온다. 때문에 자바에서 해당 코드를 읽으려면 오브젝트로 변환시켜야 하는데 파싱이 불가능하다!! 자바가 꾸역꾸역 오브젝트로 변환시킨다고 해도 자바가 이해할 수 없다! (= 문자니까 .getId 로 불러오는 행위들이 안된다!) 그렇기에!! JSON 데이터를 파싱하여 자바 객체로 변환해서 써야한다!!!
💡
파싱 (그냥… 통역같은 걸로 생각하면 될 듯?) 컴퓨터가 텍스트를 이해하고 처리하기 위해 필요한 작업 파싱은 텍스트를 작은 조각들로 나누고, 각 조각의 의미와 관계를 이해하는 과정. 이를 통해 우리는 텍스트로부터 정보를 추출하거나, 특정한 패턴을 찾아내는 등 다양한 작업을 할 수 있다.
 

 
notion image
//이런 식으로 전부 문자로 바뀌어서 들어온다는 말이다.
 

1-3. JSON 파싱 예시 + 라이브러리 Jackson 다운받기

[ 문제 ]

notion image
notion image
요 다운로드 데이터를 파싱해서 변수 3개에 담아오세요 ^^
 

[ 전체 코드 ]

package com.metacoding.myhttp; import com.fasterxml.jackson.databind.ObjectMapper; import java.io.BufferedReader; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; public class MyApp { public static void main(String[] args) { try { URL url = new URL("https://jsonplaceholder.typicode.com/todos/1"); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); BufferedReader br = new BufferedReader( new InputStreamReader(conn.getInputStream()) ); String download = ""; while (true) { String line = br.readLine(); if (line == null) break; //readLine을 다 읽으면 멈춘다는 말 download = download + line; //일케하면 다운로드에 모든 라인을 담을 수 있다는 말 } //System.out.println(download); ObjectMapper om = new ObjectMapper(); Todo todo = om.readValue(download, Todo.class); //생성자가 알아서 찾아줌 System.out.println(todo.getTitle()); } catch (Exception e) { throw new RuntimeException(e); } } }
1. URL은 JSON 데이터를 가져올 대상 주소 2. HttpURLConnection 클래스는 Java에서 HTTP 프로토콜을 사용하여 웹 서버와의 통신을 담당하는 클래스. 이 클래스를 사용하면 URL을 통해 웹 서버에 접속하고, 데이터를 요청하거나 받아올 수 있다.
 

 
package com.metacoding.myhttp; public class Todo { private int userId; private int id; private String title; private boolean completed; public Todo() { } public Todo(int userId, int id, String title, boolean completed) { this.userId = userId; this.id = id; this.title = title; this.completed = completed; } public int getUserId() { return userId; } public int getId() { return id; } public String getTitle() { return title; } public boolean isCompleted() { return completed; } }
 

1. Jackson 라이브러리 적용

https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind
notion image
우리가 추가한 라이브러리 jsckson은 json을 위한 것. 애가 있어서 ObjectMapper를 쓸 수 있다.
 

 
notion image
💡
프로젝트 만들 때, 이렇게 안 만들면 build.gradle 안 만들어짐!
 

2. 파싱 담기

notion image
필드는 상태를 변경한다는 개념으로 쓰는게 아니라 파싱을 담는 항아리로 쓰인다.
 

[ Jackson 라이브러리는 반드시 디폴트 생성자가 필요 ]

notion image
실행하면!!
notion image
notion image
디폴트 생성자가 없어서 오류가 나는 것 확인!! Todo 클래스에 빈 생성자를 넣어주고 실행해 보니!
notion image
notion image
정상적으로 실행 완료!!
 

 
notion image
이 라이브러리는 데이터를 옮겨줄 때, 이런 식으로 빈 생성자를 만들어서 옮겨준다. 그래서 JSON을 자바로 변환할 때, 디폴트 생성자가 필요!!
Todo todo = om.readValue(download, Todo.class); 이 오브젝트에 생성자가!! 필요!
 

 
💡
ObjectMapper은 todo 클래스에 빈생성자를 구분해서 객체를 만들어내면 private 변수에 public도 아닌데 직접적으로 접근해서 값을 넣어줌. 이게 바로 리플렉스 기술! (아직은 몰라도 됨)
 

http 통신 실습 1

문제

아래의 데이터를 httpurlconnection으로 다운 받고, 버퍼에 담은 후, 오브젝트 매핑을 사용해 타이틀만 나오게 해라
// 20240112101332 // https://jsonplaceholder.typicode.com/posts/1 { "userId": 1, "id": 1, "title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit", "body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto" }
중괄호부터 중괄호로 끝나는 이런걸 ‘JSON 타입’ int, String 같이, 여러 타입을 담을 수 있는건? > class!
 

전체 코드

package com.metacoding.myhttp; import com.fasterxml.jackson.databind.ObjectMapper; import java.io.BufferedReader; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; public class MyApp2 { public static void main(String[] args) { try { URL url = new URL("https://jsonplaceholder.typicode.com/posts/1"); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()) ); String download = ""; while (true) { String line = br.readLine(); if (line == null) break; download = download + line; //누적코드 } -------------- //여기까지 써놓고, 다운로드가 먼저 잘 되는지 확인해야 한다!! 제발! //피범벅 확인이 안된다!! ObjectMapper om = new ObjectMapper(); Post post = om.readValue(download, Post.class); System.out.println("------------------"); System.out.println("check : " + post.getTitle()); } catch (Exception e) { throw new RuntimeException(e); } } }
 

 
<응용ver> 빈생성자만 있으면 알아서 파싱 때려주니까, 풀생성자 필요 없네? 풀생성자가 없으면 기본 생성자도 명시적으로 만들 필요 없겠네?
package com.metacoding.myhttp; public class Post { private int userId; private int id; private String title; private String body; public int getUserId() { return userId; } public int getId() { return id; } public String getTitle() { return title; } public String getBody() { return body; } }
 

+) 어노테이션을 사용하면
package com.metacoding.myhttp; @Getter public class Post { private int userId; private int id; private String title; private String body; }
💡
getter도 삭제할 수 있다.
 

http 통신 실습 2 (숙제)

notion image
객체 타입은 받을때 private Address address 그리고 아래에 Address class를 작성 > app.quicktype.io 에 가면 자동으로 만들어줌
 
 

xml과 JSON 비교

[ xml 예시 ]
<user> <id>1</id> <username>”ssar”</username> </user>
💡
<> 이거 때문에 용량이 커짐. 그래서 안씀!
 
[ JSON 예시 ]
{ “id” : 1, “username” : “ssar” }
💡
딱 봐도 용량 차이 많이 나죠?
 
💡
코드 수정하면 무조건 ctrl + s 해주기. 안그러면 추후 오류가 남
 
 
Share article

codingb