Json 실습 ( 깊은 복사 > 특정 인스턴스를 직렬화 및 역직렬화)

2022. 12. 10. 14:17카테고리 없음

객체 직렬화 

  • 객체 직렬화 정의와  등장 배경

객체 직렬화 정의

-프로그램 실행시 생성되는 인스턴스의 상태를 장치에 저장하거나 네트워크로 전송하는 기능

등장배경

- 인스턴스의 상태를 다른 프로그램이나 네트워크로 전송해야 할 경우가 발생한다.

  • 자바 객체 직렬화 특징

-객체의 상태를 지속시키는 방법을 제공한다.

-스트럼을 통해 다른 장치나 네트워크 에서 사용  가능하게 한다

-객체는 바이트 데이터로 저장되거나 전송

 

  • 자바 객체 직렬화 과정

Java.io.serializable 인터페이스를 구현한다.

-인터페이스를 구현한 클래스의 속성은 모두 직렬화의 대상이 된다.

-직렬화 대상에서 제외시키고 싶은 경우에는 transient 를 이용한다.

 

스트림 클래스를 이용하여 직렬화 또는 역직렬화 한다.

-ObjectOutputStream 의 writeobject() 를 이용하여 직렬화 한다.

-ObjectinputStream의 readobject()를 이용하여 역직렬화 한다.

 

 

ex) 인스턴스 생성

	Employee p = new Employee
: 보통은 main 메소드가 끝나면 인스턴스 기능이 삭제가 된다 . 이렇게 되면 클래스 인스턴스 상태를 보존할 수가 없다.메모리에서 실행되는 인스턴스 상태를 네트워크 혹은 원격지 , 파일 등으로 전송해서 보존 할수 있다.
전송 방법은 객체 직렬화 통해서  파일 저장 , 전송이 가능 하다.

ex)오목을 둘때

 

"a돌의 위치나 속성을 문자로  일일이 전달시 불편 하다 " byte 단위로 전달되기에  class라는 인스턴스에 클래스 인스턴스 속성에 전달시 편리하게 사용할 수  있다. 이렇게 데이터를 묶어서 전달한다.

 

 *Marker interface : serializable 클래스를 보면  속성이 없고 추상메소드 도 없다. 이렇게 선언만 된 인터페이스를 부른다.

Class cast 인셉션 발생: 역직렬화시에는 반드시 동일한 클래스타입, 패키지명 까지 같아야 한다.

 

객체(인스턴스 생성) : Employee클래스 

package ex8;

import java.io.Serializable;

public class Employee  implements Serializable{//직렬화의 대상이 된다. 정보 묶음
	
	String name;
	String addr;
	 transient    String jumin;// 전달하고 싶지 않은 (보완성이 필요한 정보)
	String phone;
	
    //getter,setter로 정보를 담는다.
	public Employee(String name, String addr, String jumin, String phone) {
		super();
		this.name = name;
		this.addr = addr;
		this.jumin = jumin;
		this.phone = phone;
	}
	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getAddr() {
		return addr;
	}
	public void setAddr(String addr) {
		this.addr = addr;
	}
	public String getJumin() {
		return jumin;
	}
	public void setJumin(String jumin) {
		this.jumin = jumin;
	}
	public String getPhone() {
		return phone;
	}
	public void setPhone(String phone) {
		this.phone = phone;
	}

	

}

 

객체를 직렬화 하는 과정 :인스턴스에 값을 넣고  list로 묶어 "serial1"파일에 인스턴스 내용을 저장한다.

package ex8;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.util.ArrayList;

public class SerTest {
	public static void main(String[] args) {//직렬화
		Employee p = new Employee("박지성", "대전", "11111-2222", "123-1123");
		Employee p1 = new Employee("차범근", "서울", "3333-2222", "123-6542");
		
		ArrayList list = new ArrayList();
		list.add(p1);
		list.add(p);
		//직렬화 하는 데이터는 byte형식으로 저장 되다 보니 글씨가 깨진다.
		try {
			ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(new File("serial1")));
			oos.writeObject(list);
			oos.close();
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		
	}

}

serial1 파일 생성
직렬화 결과 , 한글은 byte 단위로 보낼수 없어 깨진다.

 

역질렬화 과정: "serial1" 파일에 정보를 가져온다.  

package ex8;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.util.ArrayList;
import java.util.Iterator;

public class UnserTest {//역직렬화
	public static void main(String [] args) throws Exception {
		
		try {
			ObjectInputStream ois = new ObjectInputStream(new FileInputStream(new File("serial1")));
			ArrayList  list = (ArrayList) ois.readObject();//인스턴스 읽어온다
			
			Iterator ite = list.iterator();
			//arraylist있는 값을 가져온다.
			
			System.out.println("사원 정보 출력");
			System.out.println("======================");
			while(ite.hasNext()) {
				Employee p = (Employee)ite.next();
			System.out.println("이름:" + p.getName());
			System.out.println("주민번호:" + p.getJumin());
			System.out.println("주소:" + p.getAddr()); 
			System.out.println("전화번호:" + p.getPhone());
				
			}
			ois.close();
			
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}

}

 

사원 정보 출력
======================
이름:차범근
주민번호:null
주소:서울
전화번호:123-6542
이름:박지성
주민번호:null
주소:대전
전화번호:123-1123
정상적으로 "serial1" 파일에 저장한 정보를 가져오는 것을 확인 할수 있다.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>


<script type="text/javascript">
	var p_array = [

	{
		"name" : "일길동",
		"age" : 21,
		"addr" : "서울시 마포구 서교동"
	},//0
	{
		"name" : "이길동",
		"age" : 24,
		"addr" : "서울시 마포구 노고산동"
	},//1
	{
		"name" : "삼길동",
		"age" : 25,
		"addr" : "서울시 마포구 동교동"
	},//2
	{
		"name" : "사길동",
		"age" : 27,
		"addr" : "서울시 마포구 합정동"
	},//3
	{
		"name" : "오길동",
		"age" : 30,
		"addr" : "서울시 마포구 망원동"
	} //4
	];

	console.log("이름:" + p_array[0].name + "  나이:" + p_array[0].age);

	//윈도우 초기화 이벤트

	window.onload = function() {

		var html = "<table border='1'>"

		html = html + "<tr><th>순번</th><th>이름</th><th>나이</th><th>주소</th></tr>";

		//for 문 :각각의 행을 만들어서 html에 누적......
		for (var i = 0; i < p_array.length; i++) {

			html = html + "<tr><th>" + (i + 1) + "</th><th>" + p_array[i].name
					+ "</th><th>" + p_array[i].age + "</th><th>"
					+ p_array[i].addr + "</th></tr>";

		}

		html = html + "</table>";

		console.log(html);

		document.getElementById("disp").innerHTML = html;

	};

	
</script>

</head>
<body>
	<div id="disp"></div>


</tr>




</body>
</html>

 

참고:https://www.youtube.com/watch?v=qrQZOPZmt0w

https://www.youtube.com/watch?v=jHML_8kdeoM