2023.08.16 ~ 8.17 수업
◎ JSON을 배우기 전 짚고 넘어가기
REST API로 요청을 보내고 응답을 받으면 JSON 형태로 데이터를 가져온다
REST API란 쉽게 말해서 자원의 이름으로 자원의 상태를 주고받을 수 있는 API이다.
JSON 이나 XML 을 사용해서 데이터(자원)를 주고받는 것이 일반적이다.
RESTful 웹 서비스는 XML 대신 JSON 데이터를 사용하고 생성한다.
Java SE는 JSON을 자바객체로(또는 그 반대로) 변환하는 것을 지원하지 않는다.
그래서 라이브러리를 사용해야한다
Jackson 과 Gson 라이브러리를 주로 사용한다
- 두 개의 라이브러리는 JSON data-binding(JSON 데이터 ↔ Java 객체로 직렬화 & 역직렬화) 지원 라이브러리
- JSON 파싱시 자주 쓰이는 라이브러리
● 데이터를 서버에서 수신할 때 사용되는 형식
1. JSON(JavaScript Object Nation)
자바스크립트에서 객체 표기법으로 데이터 전달
키명을 다 적어야하므로 데이터의 양이 많아 속도가 느려짐
네트워크를 통해 데이터를 주고받는 데 자주 사용되는 경량의 데이터 형식
2. XML(eXtensible Markup Language)
HTML형식처럼 태그로 데이터 표현
HTML태그처럼 미리 지정되어 있지 않고 사용자가 직접 정의
용량을 많이 차지함
<태그>값
3. CVS(Comma Separated Values)
각 항목을 쉼표로 구분해서 데이터 표현
용량은 적고 많은 데이터를 처리하지만 데이터가 무엇을 의미하는지 알기 어렵다
값1, 값2, 값3...
◎ JSON(JavaScript Object Nation)
- 자바스크립트에서 객체 표기법을 나타내는 것
- 경량데이터 교환 형식
- 웹 서버와 데이터를 교환하기 위해 사용
- 데이터 저장 및 전송 용도로 사용하는 텍스트 형식의 데이터
- 네트워크를 통해 서로 다른 시스템들이 데이터를 주고 받을 때 많이 사용(가독성이 좋음)
- 문자열(" ")
- JSON은 {"키": 값} - 키 명에 큰 따옴표 표시
- js는 {키: 값}
- 값은 배열, 또는 객체가 가능 : 객체는 {} 로, 배열은 []로 사용된다
▷ JSON 데이터 유형
- 문자열 : 값은 큰 따옴표로 묶기
- 숫자 : 정수 또는 부동 소수점
- 객체 : JSON 값
- 배열 : JSON 값
- true/false : Boolean
- null : 키워드(null) 사용
※ 날짜 객체는 JSON에서 허용되지 않음
날짜를 문자열로 작성 후 자바스크립트에서 다시 'new Date()'를 통해 생성
json문자열 데이터 객체로 만드는 것
◎ 자바스크립트로 JSON 데이터 다루기
▶ JSON 내장 객체
- JavaScript 객체와 JSON 문자열 간의 상호 변환을 수행해주는 메서드 제공
- JSON.parse() / JSON.stringify()
- 전역에서 접근 가능
* js객체의 타입 : object(객체)
* json데이터의 타입 : string(문자열)
▷ JSON.parse()
- 웹 서버에서 데이터를 수신할 때 데이터는 "문자열" 형태이기 때문에,
JSON데이터로 가져와서 parse()를 통해 자바스크립트 객체로 변경이 필요
- json문자열을 js객체(Object)로 만드는 기능(문자열을 자바스크립트 오브젝트로 변경)
- 자바스크립트 객체로 데이터가 바뀐다
- 각각의 문서 객체에 텍스트 콘텐츠로 데이터 속성을 호출해서 추가
- data를 분석할때 사용
* JSON데이터를 JS객체로 변경하기
<script>
const originData = '{"name" : "진", "age" : 32 , "birth" : 1998 }';
const changeData = JSON.parse(originData);
alert(typeof(changeData));
</script>
-> 자바스크립트 객체로 변경됨
▷ JSON.stringify()
- JSON의 일반적인 사용용도는 웹서버와 데이터를 교환하는 것이다.
- 웹 서버에 데이터를 보낼 때 데이터는 문자열이어야 한다
- 자바스크립트 객체 데이터를 문자열로 변환
- js객체를 JSON데이터로 변경
- JSON은 대문자로 작성
* js객체를 JSON데이터로 변경하기
<script>
const originData = {name : "진", age : 32 , birth : "1998-07-12" }; // JS객체
const changeData = JSON.stringify(originData);
alert(changeData)
alert(typeof(changeData));
</script>
-> JSON 데이터로 변경되어 키 값에 큰 따옴표가 생성됨
-> JSON 객체(문자열)로 변경됨
▶ Web Storage API를 사용한 데이터 저장
- JSON을 사용하면 자바스크립트 개체를 텍스트로 저장할 수 있다
▷ 개념
※ API(Application Programming Interface)
- 라이브러리에 접근하기 위한 규칙을 정의한 것
- 내부구조를 알 필요 없이 단순히 API에 정의된 입력 값을 주고 결과 값을 사용할 수 있음
- 점원과 유사한 역할, 매개체
※ Web Storage API
- 브라우저에서 데이터를 저장하고 검색하기 위한 간단한 구문
- 서버(데이터베이스나 클라우드)에 저장할 필요가 없을 때 사용
- 크기가 작은 쿠키를 대체하기 위한 자바스크립트의 하드디스크 파일
- 기본적으로 키(key)와 값(value)으로 이루어진 데이터를 저장
- 로컬 스토리지(localStorage)와 세션 스토리지(sessionStorage)로 나뉨
- 세션 스토리지는 웹페이지의 세션이 끝날 때 저장된 데이터가 지워지고,
로컬 스토리지는 웹페이지의 세션이 끝나더라도 데이터가 지워지지 않는다.
- 문자형(string) 데이터 타입만 지원
-> JSON 형태로 데이터를 읽고 쓰면 해결
객체나 배열를 저장하기 위해서는 객체를 문자열로 변환해서 저장해야 한다
JSON.stringify() 함수를 사용하여 객체와 배열을 JSON 문자열로 변환
스토리지에 쓸 데이터를 JSON형태로 직렬화(stringify)하고 읽은 데이터를 JSON형태로 역직렬화(parse)
○ localStorage
- 보관 기한이 없는 데이터를 저장할 수 있는 객체
* Storage 메소드
- localStorage가 Storage 타입의 객체이기 때문에 Storage의 메소드를 호출하여 데이터를 관리
setItem(name, value) - key, value 저장
getItem(name) - value 읽어 오기, 검색
removeItem(name) - item 삭제
key(index) - index로 key값 찾기
clear() - 도메인 내의 localStorage 값 삭제
length - 전체 item 갯수, key-value 쌍의 갯수
<script>
// 데이터 저장
const myObj = {name : "진"};
const myJson = JSON.stringify(myObj);
localStorage.setItem("testJSON", myJson);
// 데이터 읽기
let text = localStorage.getItem("testJSON");
let obj = JSON.parse(text);
alert(obj.name);
</script>
○ sessionStorage
- 하나의 세션만을 위한 데이터를 저장
- 사용자가 브라우저 탭이나 창을 닫으면 객체에 저장된 데이터는 사라진다
▷ 예외
※ JSON에서 날짜 객체는 허용되지 않음
* 사용법
- 날짜를 문자로 반환하기 : JSON.stringify()
- 자바스크립트는 날짜 객체 허용 : new Date() 사용
<script>
const originData = {name : "디데이", today : new Date() };
const changeData = JSON.stringify(originData);
alert(changeData)
</script>
-> 날짜 형식이 JSON(문자열)으로 변경되어 큰 따옴표로 표시됨
* 데이터 변환 시 함수는(키와 값) 모두 제거됨, 속성(값)만 JSON으로 변경 됨
- 문자열로 값을 변환하고 싶다면 미리 문자열로 변경
- 변환을 하면 함수로 되돌아가지 않는다
<script>
const originData = {name : "진", age : function() {return 30;} };
const changeData1 = JSON.stringify(originData);
alert(changeData1)
originData.age = originData.age.toString();
const changeData2 = JSON.stringify(originData);
alert(changeData2)
</script>
◎ 스프링부트로 JSON 다루기
▶ JSON 데이터 작성하는 법
1. 이스케이프 시퀀스(\) : 원시적 방법으로 권장하지 않음
-> 복잡하고 오타의 위험 존재
// 어노테이션은 클래스의 메타데이터라고하여 내부적으로 클래스이다
// 어노테이션과 같은 이름의 클래스 생성 불가
@RestController // 응답결과는 스트링(JSON or Text)
public class JSONRestController {
@GetMapping("/info")
// info라는 주소로 요청을 하면 projectInfo메서드를 호출해라
public String projectInfo() {
// 1. 이스케이프 시퀀스(\) : 원시적 방법으로 권장하지 않음
return "{ \"project name\" : \"preword\", \"created date\" : \"2022-07-31\" }";
}
2. 템플릿 문자열 사용(자바 17ver ~) : 권장하지 않음
-> 오타의 위험 존재
@RestController
public class JSONRestController {
@GetMapping("/info")
public String projectInfo() {
// 2. 템플릿 문자열 사용(자바 17ver ~) : 권장하지 않음
return """
{
"project name" : "preword",
"created date" : "2022-07-31"
}
""";
}
}
3. Jackson : 권장
@RestController
public class JSONRestController {
// 3. Jackson
@GetMapping("/infoJackson")
public Object projectInfoJackson() {
Project project = new Project();
project.setProjectName("preword");
project.setAuthor("홍길동");
// project.setAuthor(null); // @JsonInclude 적용 대상
project.setCreatedDate(new Date());
return project;
}
}
◎ JSON 라이브러리
- JSON 파싱시 자주 쓰이는 라이브러리
- Jackson / Gson
▶ Jackson
- 어노테이션을 사용하여 클래스 변수를 자동으로 JSON형태로 변환
- JSON 데이터 구조를 처리해주는 라이브러리
- Java Object를 JSON으로 변환하거나 JSON 문자열을 Java Object로 변환
* 필수 작업
- 컨트롤러 클래스에 @RestController 또는 클래스에 @Controller + 함수(메서드)에 @ResponseBody
- model 클래스에 getter / setter
※ JSON Property 주요 어노테이션
@JsonIgnore
- 필드 단위에서 json으로 직렬화, 역직렬화시 제외시킬 목적
- 반환 값에 포함하지 않음(제외되어 출력)
▷ 컨트롤러
@GetMapping("/infoJackson")
public Object projectInfoJackson() {
Project project = new Project();
project.setProjectName("preword");
project.setAuthor("홍길동");
project.setCreatedDate(new Date());
return project;
}
▷ 모델 클래스(엔티티)
private String projectName;
private String author;
@JsonIgnore
private Date createdDate;
-> createdDate 는 출력되지 않음
@JsonInclude
- 클래스 위에 작성
- 반환 값 설정
- 자바 객체를 json 형식 데이터로 직렬화할때 옵션을 통해서 원하는 값만 포함
● ALWAYS : 모든 데이터 json 변환, 값에 상관 없이 출력
● NON_NULL : null인 데이터 제외(직렬화된 출력)
● NON_ABSENT : null 과 참조유형의 absent 값은 제외(Optional)
● NON_EMPTY : NULL 값이 아니고 빈 컬렉션, 맵이 아닌 경우 출력
- null 과 참조유형의 absent 값과 maps이 isEmpty(), array length가 0, String length 0 인 데이터 제외
● NON_DEFAULT : 속성의 값이 해당 데이터 형식의 기본값과 다른 경우 출력
- empty데이터와 기본형이 default와 date가 0인 것들을 제외
▷ 컨트롤러
@GetMapping("/infoJackson")
public Object projectInfoJackson() {
Project project = new Project();
project.setProjectName("preword");
// project.setAuthor("홍길동");
project.setAuthor(null); // @JsonInclude 적용 대상
project.setCreatedDate(new Date());
return project;
}
▷ 모델 클래스(엔티티)
@JsonInclude = objectMapper.setSerializationInclusion();
@JsonInclude(JsonInclude.Include.NON_NULL) // null이 아닌 것만 return에 포함
public class Project {
private String projectName;
private String author;
private Date createdDate;
}
-> null 값을 가진 author 필드는 출력되지 않는다
@JsonProperty
- 클래스의 속성명에 별명을 정해줌
- 데이터 전송시, 객체를 JSON 형식으로 변환할 때 Key의 이름을 설정
▷ 컨트롤러
@GetMapping("/infoJackson")
public Object projectInfoJackson() {
Project project = new Project();
project.setProjectName("preword");
project.setAuthor("홍길동");
// project.setAuthor(null); // @JsonInclude 적용 대상
project.setCreatedDate(new Date());
return project;
}
▷ 모델 클래스(엔티티)
public class Project {
private String projectName;
@JsonProperty(value = "project master")
private String author;
// @JsonIgnore
private Date createdDate;
}
-> author 필드가 설정된 이름으로 출력
@JsonFormat
- 날짜, 시간값을 직렬화할 때 형식 지정
- 어노테이션은 Jackson 라이브러리에서 제공하는 어노테이션으로 JSON 형식의 날짜, 시간값을 지정할 때 사용
- pattern : 날짜 형식을 지정
- timezone : 특정 국가나 지역의 현지 시간(local time)을 지정
▷ 컨트롤러
@GetMapping("/infoJackson")
public Object projectInfoJackson() {
Project project = new Project();
project.setProjectName("preword");
project.setAuthor("홍길동");
// project.setAuthor(null); // @JsonInclude 적용 대상
project.setCreatedDate(new Date());
return project;
}
▷ 모델 클래스(엔티티)
public class Project {
private String projectName;
@JsonProperty(value = "project master")
private String author;
@JsonFormat(shape = JsonFormat.Shape.STRING,
pattern= "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Seoul")
private Date createdDate;
}
-> createdDate의 시간표현이 설정한 값으로 출력
▶ Gson
- class를 만들지 않고 직접 JSON을 만들어서 보냄
- JSON형식만 처리
- 가벼운 JSON 데이터를 처리할 때 성능이 좋다
- 스프링 프레임워크에 내장되어있지 않기 때문에 build.gradle에 추가
▷ build.gradle의 dependencies에 코드 추가
- mvn repository : Gson 검색하여 Gradle(Short)의 코드 복사
implementation 'com.google.code.gson:gson:2.10.1'
- 추가 후 gradle Refresh 하기
▷ 컨트롤러
- import 하기
@GetMapping("/infoGson")
public String gsonJson() {
// 1) JsonObject객체 생성(최상위 객체)
JsonObject jo = new JsonObject();
// 2) JSON 요소 추가(키, 값)
jo.addProperty("projectName", "preword");
jo.addProperty("author", "황진이");
jo.addProperty("createdDate", new Date().toString());
JsonArray ja = new JsonArray();
for (int i = 0; i < 5; i++) {
JsonObject jObj = new JsonObject();
jObj.addProperty("prop" + i, i);
ja.add(jObj);
}
jo.add("follower", ja);
// 진짜 JSON문자열이 된다
return jo.toString();
}
* Gson은 자세히 배우지 않음
▶ Jackson 과 Gson
- 두 개의 라이브러리는 JSON data-binding(JSON 데이터 ↔ Java 객체로 직렬화 & 역직렬화) 지원 라이브러리
▷ Jackson의 장점
- 모든 JAX-RS및 스프링프레임워크에 내장
- 광범위한 애너테이션 지원
- 고용량의 JSON데이터를 처리할 때 GSON보다 성능이 좋다
▷ Gson의 장점
- 간단한 경우 사용이 편리
- 자바 엔티티를 통하지 않아도 됨(역직렬화 등)
★ 나의 의문점
1. 파싱이 뭐야 ?
* Parsing
- 언어학에서 parsing은 구문 분석이라고도하며 문장을 그것을 이루고 있는 구성 성분으로 분해하고 그들 사이의 위계 관계를 분석하여 문장의 구조를 결정하는 것
- 문장의 구조를 표현하는 한 방법
- 데이터를 조립해 원하는 데이터를 빼내는 프로그램을 하는것
- 특정문서(XML 따위)를 읽어 들여서 이를 다른 프로그램이나 서브루틴이 사용할 수 있는 내부 의 표현 방식으로 변환시켜 주는 것
쉽게 말해 웹페이지에서 원하는 데이터를 추출하여 가공하기 쉬운 상태로 바꾸는 것으로 데이터를 원하는 모양으로 만들어 낼 수 있다
(참고) Parser : 파서는 파싱을 하는 프로세서. 즉, 파서가 파싱 작업을 하는 것.
2. 이걸 왜 파싱해?
- JSON은 네트워크를 통해 데이터를 주고받는 데 자주 사용되는 경량의 데이터 형식이다
- JSON형태로 온 데이터들을 파싱해주어야한다
- JSON형태로는 데이터들을 이용할 수 없기 때문
-> 데이터를 이용하기 위해 값이 name이고 value가 진이라는 분석이 필요하다
'백엔드 > 웹 개발' 카테고리의 다른 글
AJAX( Asynchronous JavaScript and XML ) (0) | 2023.08.21 |
---|---|
GitHub 사용하기 (0) | 2023.08.17 |
Git 설치 (0) | 2023.08.16 |
Maven 프로젝트 Gradle로 변환하기 (0) | 2023.08.16 |
블로그 화면 구성하기 - 타임리프5 (블로그 글 수정/생성 기능 추가하기) (0) | 2023.08.11 |