2022.08.11/자바 정리/JSON/GSON/네트워킹

Jimin·2022년 8월 15일
0

비트캠프

목록 보기
21/60
post-thumbnail

039. JSON 형식으로 데이터 입출력하기: Gson 라이브러리 사용

  • JSON 형식으로 데이터를 읽고 쓰는 법
  • Google 에서 제공해주는 JSON 라이브러리인 Gson 사용법

040. 네트워킹을 이용한 파일 공유: client/server app. 아키텍처로 전환

  • 네트워크를 통해 파일을 공유하고 데이터 입출력을 처리하는 방법
    • 데이터를 파일에 저장하고 꺼내는 기능을 별도의 애플리케이션으로 분리한다.
    • 기존의 프로그램은 네트워크를 통해 파일 서버에 접속하여 데이터 입출력을 처리한다.

CSV의 한계와 대안 형식

  • 번호, 이름, 이메일 암호, 등록일
    • 한 줄의 문자열로 데이터 표현
    • 컴마(,)로 항목을 구분
    • 텍스트 형식 → 전용 편집기의 도움 없이 읽고 쓸 수 있다.

⇒ 다른 데이터를 포함하는 데이터를 표현하기 힘들다. 즉, CSV 형식은, 계층 구조로 된 데이터를 표현하기 어렵다.

  • 계층 구조의 데이터 예시
    [책 정보]
    • 제목
    • 내용
    • 저자들
      • 저자 1
        - 이름
        - 이메일
        - 연락처
      • 저자 2
        - 이름
        - 이메일
        - 연락처
    • 출판사
      • 출판사 명
      • 홈페이지
      • 전화번호
      • 팩스
  • 위의 책 정보 예사와 같이 책 데이터 안에 저자들의, 출판사의 데이터가 있을 경우, CSV형식으로 표현하기 어렵다.
  • 실무에서 다루는 데이터는 게시글처럼 단순한 선형(linear) 구조로만 되어 있지 않다.
    위의 예제의 "책 정보"처럼 다른 데이터를 포함하는 계층 구조로 된 경우가 많다.
  • 따라서, 계층 구조의 데이터를 표현할 수 있고, 텍스트 형식으로 되어 있어 OS나 프로그래밍 언어에 종속되지 않는 공개된 데이터 포맷을 가진 XML이나 JSON을 많이 사용한다.

XML 형식

  • XML: eXtensible Markup Language
<book>
  <title> --- </title>
  <description>---</description>
  <authors>
    <author>
      <name>---</name>
      <email>---</email>
      <tel>---</tel>
    </author>
    <author>
      <name>---</name>
      <email>---</email>
      <tel>---</tel>
    </author>
  </authors>
  <press>
    <name>---</name>
    <homepage>---</homepage>
    <tel>---</tel>
  </press>
</book>
  • <book>---</book>: 데이터를 설명하는 데이터
    • = meta data(부가 데이터)
    • = markup(출판용어)
    • = tag
    • = element
    • <book>: 시작 태그
    • ---: content
    • </book>: 끝 태그
  • <book><authors><name>입장에서 조상(ancestor) 태그이다.
  • <author><name>입장에서 부모 태그이다.
  • <name><author>입장에서 자식태그이고, <book><authors>입장에서는 자손(descendant) 태그이다.
  • XML
    • 계층적인 구조의 데이터 표현
    • 각 데이터의 의미를 표시

      데이터 조회 및 추출이 용이

      Application에서 데이터를 제어하기가 쉽다.

      인간이 아닌 프로그램에서 데이터를 다루기 쉽다.
    • 텍스트 형식

      OS나 프로그래밍 언어에 상관없이 데이터를 주고 받기 쉽다.

      프로그램끼리 데이터 교환이 용이하다.
    • 단점: 데이터보다 부가 데이터가 더 클 수 있다. ⇒ 파일 크기가 매우 커진다.

JSON 형식

JSON(Java Script Object Notation): 자바스크립트에서 객체를 표기하는 문법을 차용해서 데이터를 표현하는 문법으로 만든 것.

  • JSON 기본 형식
{
  "title": "----",
  "description": "----",
  "authors": [{"name": "----","email": "----", "tel": "----"},
              {"name": "----","email": "----", "tel": "----"}],
  "press": {"name": "----",
            "homepage": "----",
            "tel": "----"}
}
  • 계층형 데이터 표현이 쉽다.
  • 프로퍼티명(=XML의 태그명)을 통해 데이터의 의미를 표시할 수 있다.
    • XML보다 부가 데이터의 크기가 작다.
  • 텍스트 형식 ⇒ 프로그램에 상관없이 데이터 교환이 가능하다.
    • XML보다 간결하다.
  • http://json.org 에 가면 더 자세한 내용을 확인할 수 있다.

Json 형식으로 데이터 저장하고 로딩하기: Gson 라이브러리 사용

  • JSON 형식으로 데이터를 읽고 쓰는 법.
  • Google에서 제공해주는 JSON 라이브러리인 Gson 사용하기

Google-gson 라이브러리

board-app project

1단계 - 프로젝트에 google-gson 라이브러리를 포함한다.

  • board-app/app/build.gradle 변경
    • search.maven.org 사이트에서 gson 라이브러리를 찾는다.
    • dependencies{} 블록에 gson라이브러리 설정을 추가한다.
dependencies {
    implementation 'com.google.code.gson:gson:2.9.1'
    testImplementation 'junit:junit:4.13.2'
    implementation 'com.google.guava:guava:30.1.1-jre'
}
  • 이클립스의 프로젝트 설정 파일(.classpath)에 라이브러리 정보를 추가한다.
    • 콘솔(CLI)에서 gradle eclipse 명령을
    • 이클립스 프로젝트를 리프레시 한다.

2단계 - XxxDao에 Gson 라이브러리를 적용한다.

  • com.bitcamp.board.dao.XxxDao class 변경
    • save(), load() 메서드에 Gson 라이브러리를 사용하여 JSON 데이터를 다룬다.
  • BoardDao class
// 게시글 목록을 관리하는 역할
//
public class BoardDao {

  ...

  public void load() throws Exception {
    try (BufferedReader in = new BufferedReader(new FileReader(filename))) {

      // 파일에서 JSON 문자열을 모두 읽어 StringBuilder에  담는다.
      StringBuilder stringBuilder = new StringBuilder();
      String str;
      while ((str = in.readLine()) != null) {
        stringBuilder.append(str);
      }

      // StringBuilde에  보관된 JSON 문자열을 가지고 Board[]을 생성한다./
      Board[] arr = new Gson().fromJson(stringBuilder.toString(), Board[].class);

      // Board[]배열의 저장된 객체를 List로 옮긴다.
      for(int i=0;i<arr.length;i++) {
        list.add(arr[i]);
      }
    }
  }

  public void save() throws Exception {
    try (FileWriter out = new FileWriter(filename)) {
      Board[] boards = list.toArray(new Board[0]); // 현재 list에 들어 있는 보드 객체들 받아오기
      //String json = new Gson().toJson(boards); // 이렇게 코딩 안하고, 그냥 바로 넣어버린다.
      out.write( new Gson().toJson(boards));
    }
  }

  ...
  
}
  • MemberDao class
// 회원 목록을 관리하는 역할
//
public class MemberDao {

  ...

  public void load() throws Exception {
    try(BufferedReader in = new BufferedReader(new FileReader(fileName))){
      StringBuilder stringBuilder = new StringBuilder();
      String str;
      while ((str = in.readLine()) != null) {
        stringBuilder.append(str);
      }
      Member[] members = new Gson().fromJson(stringBuilder.toString(),Member[].class);

      for(int i=0;i<members.length;i++) {
        list.add(members[i]);
      }

    }
  }

  public void save() throws Exception{ 
    try(FileWriter out = new FileWriter(fileName)){
      Member[] members = list.toArray(new Member[0]);
      out.write(new Gson().toJson(members));
    }
  }

  ...
  
 }

네트워킹을 이용한 파일 공유 방법: client/server app. 아키텍처로 전환

  • 네트워크를 통해 파일을 공유하고 데이터 입출력을 처리하는 방법
    • 데이터를 파일에 저장하고 꺼내는 기능을 별도의 어플리케이션으로 분리한다.
    • 기존의 프로그램은 네트워크를 통해 파일 서버에 접속하여 데이터 입출력을 처리한다.

1. 데이터를 저장하고 꺼내는 이전 방식

  • 사용자 각각이 (App을 실행하는)자신의 컴퓨터에 파일을 보관 → 데이터 공유가 안된다.
    ⇒ 업무 수행이 힘들다.

2. 해결책1 - HDD 공유 → 파일공유

  • 외부 컴퓨터에 파일을 놓은 후 공유
    → 여러 App.이 같은 파일을 접근
    → 파일을 내용을 변경/삭제/추가할 경우
    ⇒ 다른 App.이 저장한 내용을 덮어쓸 수 있다.

3. 해결책2 - 데이터 관리자를 통해 접근 → 직접 접근 제한 → 다른 사람이 작업한 내용을 덮어 쓰는 것을 방지

  • 데이터가 필요하면 데이터 관리 App에 요청한다.
  • 데이터 관리 App은 요청한 작업을 수행한 후 결과를 응답한다.
    ⇒ 이를 통해 데이터 등록/조회/변경/삭제를 한 곳에서 통제한다.
    ⇒ App끼리 서로 데이터를 덮어쓰는 상황을 방지할 수 있고,
    효과적으로 데이터를 공유할 수 있다.

용어 정리: Client와 Server

C/S Application(Client/Server Application): Application을 이원화 한 것

Client/Server App. 예;

  1. 카톡 App ↔ 카톡 서버
  2. LoL 서버 ↔ LoL서버
  3. 메인 App ↔ 메일 수신 서버(POP3,IMAP)
    메인 App ↔ 메일 전송 서버(SendMail)
  4. 검색 웹 페이지(웹브라우저) ↔ 검색 서버
  5. 유튜브 App ↔ 유뷰트 서버
  6. Git Client ↔ Git Server ↔ 서버 저장소

Client/Server Application Architecture 장점

  • 다중 사용자에게 동시 서비스 제공 가능
    • 다중 Client(사용자)의 요청을 한 곳에서 처리 ⇒ 데이터 공유 가능

Client/Server Application 구현 기술


java.net.Socket 이용 → 두 application이 데이터를 주고 받을 수 있도록 연결한다.

데이터 입출력(I/O)를 위해서 java.io.* ← Stream 클래스의 도움 받기

  • printStream
  • DataInputStream/DataOutputStream
  • ObjectInputStream/ObjectOutputStream

기존 board-app 프로젝트를 Client/Server 구조로 변경

  • board-app(root project) - app(main sub project)
    → app-client → board-app-client
    → app-server → board-app-server

board-app project

1단계 - client/server 프로젝트로 분리한다.

  • board-app-client 프로젝트 폴더를 준비한다.
  • board-app-server 프로젝트 폴더를 준비한다.

2단계 - client 프로젝트를 Eclipse IDE로 임포트 한다.

  • gradle eclipse명령을 수행하여 이클립스 설정 파일을 준비한다.
  • 이클립스에서 임포트한다.
  • Eclipse IDE에서 사용할 프로젝트 정보 설정하기
eclipse {
    project {
        name = "board-app-client" 
        // 프로젝트 이름을 지정하지 않으면 build.gradle 파일이 있는 
        // 폴더 이름을 프로젝트 이름을 사용한다.
    }
    ...
}
eclipse {
    project {
        name = "board-app-server" 
        // 프로젝트 이름을 지정하지 않으면 build.gradle 파일이 있는 
        // 폴더 이름을 프로젝트 이름을 사용한다.
    }
    ...
}

3단계 - ClientApp클래스를 생성한다.

  • ClientApp class 생성

single project와 multi-sub project

1. Single Project 디렉토리 구조

  • gradle-project/(← 메인 프로젝트 폴더)
    • settings.gradle(← 프로젝트 공통 설정)
    • build.gradle (← 프로젝트 설정)

2. Multi-sub project 디렉토리 구조

  • gradle-project/ (← root project/ ↓ sub project)
    • app/ (← sub project)
      • build.gradle (← 서브 프로젝트 전용 설정)
    • sub1/ (← sub project)
      • build.gradle
    • sub2/ (← sub project)
      • build.gradle
    • settings.gradle (← 모든 서브 프로젝트가 공유하는 공유 설정)
profile
https://github.com/Dingadung

0개의 댓글