[ JSON (JavaScript Object Notation) ]
1-1. JSON 이란?


그림에서 붉은 글자 파트 영어가 json. = 공용어! 즉, json은 공용어! 사용하기 편하게 자기의 언어로 바꿔서(번역해서) 사용.
JSON을 내 오브젝트로 바꾸는 방법만 알면 현시대의 통신은 끝!
자바 스크립트 객체를 표현하는 데이터 형식
(= 자바 스크립트의 Object(객체) 표기법)
(= 자바 스크립트처럼 생긴 데이터 표기법)
가볍기 때문에 주로 데이터 전송 및 통신 목적으로 사용된다.
(서버와 클라이언트 간에 데이터를 주고받을 때, 일반적으로 JSON 형식을 사용)
(json은 경량. 제일 가벼움)
[ application/json ] 이라고 헤더에 꼭!!! 적어줘야 한다. MIME
’나 지금 제이슨 던져~~!’ 하고 알려줘야 함!
객체는 중괄호({})로 묶여 있으며, 키와 값의 쌍으로 구성된다. 키는 문자열, 값은 문자열·숫자·불리언·배열·다른 객체 등 다양한 데이터 형식을 가질 수 있다.

키 값 = 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 데이터를 파싱하여 자바 객체로 변환해서 써야한다!!!
파싱 (그냥… 통역같은 걸로 생각하면 될 듯?)
컴퓨터가 텍스트를 이해하고 처리하기 위해 필요한 작업
파싱은 텍스트를 작은 조각들로 나누고, 각 조각의 의미와 관계를 이해하는 과정.
이를 통해 우리는 텍스트로부터 정보를 추출하거나,
특정한 패턴을 찾아내는 등 다양한 작업을 할 수 있다.

//이런 식으로 전부 문자로 바뀌어서 들어온다는 말이다.
1-3. JSON 파싱 예시 + 라이브러리 Jackson 다운받기
[ 문제 ]


요 다운로드 데이터를 파싱해서 변수 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

우리가 추가한 라이브러리 jsckson은 json을 위한 것.
애가 있어서 ObjectMapper를 쓸 수 있다.

프로젝트 만들 때, 이렇게 안 만들면 build.gradle 안 만들어짐!
2. 파싱 담기

필드는 상태를 변경한다는 개념으로 쓰는게 아니라 파싱을 담는 항아리로 쓰인다.
[ Jackson 라이브러리는 반드시 디폴트 생성자가 필요 ]

실행하면!!


디폴트 생성자가 없어서 오류가 나는 것 확인!!
Todo 클래스에 빈 생성자를 넣어주고 실행해 보니!


정상적으로 실행 완료!!

이 라이브러리는 데이터를 옮겨줄 때, 이런 식으로 빈 생성자를 만들어서 옮겨준다.
그래서 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 (숙제)

객체 타입은 받을때 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