Object 보조스트림

- Data 로 모든 타입의 데이터를 보낼 수는 없다
- 그래서 최상위 객체인 Object 를 다룰 수 있는 보조 스트림이 필요하다.
- Object 보조 스트림에는 객체 , 배열 , 컬렉션 등 다양한 데이터 형태가 들어갈 수 있다.
- Class로 만든 객체의 경우에는 직렬화 ( serialize ) 를 하지 않으면 전달 되지 않는다.
직렬화 / 비직렬화
- 직렬화 ( serialize ) 는 Object 라는 큰 덩어리를 잘개 쪼개서 보내는 작업이다.
- 반대로 역직렬화 ( Unserialize ) 는 조각낸 덩어리들을 합치는 작업이다.
- 이렇게 쪼개고 합칠 때 필요한 규격이 Serializable 인터페이스이다.
- Serializable 은 아무 내용이 없는 마커 인터페이스로서 직렬화를 고려하여 작성한 클래스인지 판단하는 기준으로 사용한다.
- 만약 이 Serializable 을 구현하지 않으면 직렬화를 하지 못하고 에러가 발생한다.
- Serializable 로 인해 구현할 메서드는 없지만 Object 보조 스트림의 writeObject() 메서드 안에 Serializable 을 체크하는 메서드가 if문으로 존재하여 Serializable 이 없다면 에러로 처리하는 것이다.
마커 인터페이스 : 빈껍데기 인터페이스.
이러한 마커 인터페이스는 객체의 타입과 관련된 정보를 제공한다.
이 인터페이스를 사용함으로서 컴파일러와 JVM 은 객체에 대한 추가적인 정보를 얻을 수 있다.
게시판 만들기
- Object 보조 스트림을 이용하면 정보를 모두 담아 파일로 저장할 수 있기 때문에 Java 자료구조를 영구적으로 저장시킬 수 있다.
- 서버가 종료되어도 Java 객체의 내용을 보존할 수 있게 된다.
- 이를 이용하여 게시판을 만들어 보자.
1. Bean 생성

- subject, user_name, content 데이터를 한 곳에 담고자 한다.
- 이때 데이터를 담을 클래스인 Bean 을 생성한다.
- getter / setter 로 담긴 데이터는 bean 규약에 의해 private 로 만들어진다.
- 이때 만들어진 bean 은 Serializable 인터페이스를 구현하고 있어 직렬화에 사용한다.
2. jsp 파일로 view 생성
- 목차 ( list.jsp )

- 글쓰기 링크를 누르면 writeForm.jsp 파일 경로로 이동한다.
- 전송받은 list 파라미터의 값 ( 여기서는
ArrayList<BoardBean> ) 을 통해 크기가 0이면
작성된 글이 없다고 표시해준다.
- 반대로 크기가 0이 아니면 반복문을 통해 게시글의 목차가 표시될 수 있게 구성하였다.
- 또
<a href=""> 를 통해 url에 요청값과 파라미터 클릭시 보낼 수 있도록 구성하였다.
- 글쓰기 ( writeForm.jsp )

- form 태그로 작성한 내용들을 파라미터에 담아 보낸다.
- 작성한 글 내용 보기 ( detail.jsp )

- 전송받은 board 파라미터 값 ( 여기서는
BoardBean 객체 ) 을 통해 user_name, subject, content 를 보여준다.
- 버튼을 누르면 location.href='./' 로 인해
http://localhost:8080/34_Board/ 로 이동한다.
3. Controller 생성

- Get 과 Post 두가지 방식을 모두 받기 때문에 dual 이라는 메서드를 생성하여 모든 요청을 받도록 하였다.
- 실질적으로 일처리를 하는 BoardModel 클래스 객체를 생성했다.
- "/ " 요청시

- switch 를 이용하여 들어오는 요청마다 어떤 동작을 하는지 구분하였다.
- 이때 어떤 요청값도 받지 않았으면 "/ " 의 경우가 된다.
- "/ " 경우에는 model 객체의 getList( ) 메서드로 생성된 값을 ArrayList list에 담는다.
- 담은 list 를 "list" 이름으로 저장한다.
- 그리고 list.jsp 페이지로 이동하면서 Attribute를 전송한다.
- 이와 같은 과정 때문에 URL 이
http://localhost:8080/34_Board/ 일 시에는 list.jsp 페이지가 뜬다.
정작 http://localhost:8080/34_Board/list.jsp 경로로 이동하면 글 목록이 다 사라진 상태가 된다.
이는 list.jsp 의 원래 초기 모습인 경로로 들어간 것이다.
- "/ write " 요청시

- 글쓰기 페이지에서 보내서 받은 파라미터를 한꺼번에 넣기 위해 HashMap에 담았다.
- HashMap 을 write( ) 메서드 안의 매개변수로 보낸다.
- resp.sendRedirect( ) 로 요청값 "/" 의 경우가 되도록 이동한다.
여기서 변수 ctx 의 값은 /34_Board 로 http://localhost:8080/34_Board/ 로 이동한다.
- 이때 "/" 요청의 경우로 가기 때문에 list.jsp 페이지로 이동하면서 리스트가 생성된다.
- "/ detail " 요청시

- list.jsp 에서 href="detail?idx=${stat.index}" 를 통해 idx 파라미터 값을 받는다. ( 여기서는
ArrayList<BoardBean> 의 인덱스값 )
- model 객체의 detail( ) 메서드를 통하여 변수 idx 를 매개변수로, 반환한 BoardBean 객체를 변수 board 에 넣는다.
- 담은 board 를 "board" 이름으로 저장한다.
- detail.jsp 로 이동하면서 Attribute 를 전송한다.
- "/ remove " 요청시

- list.jsp 에서 href="remove?idx=${stat.index}" 를 통해 idx 파라미터 값을 받는다.
- model 객체의 remove( ) 메서드를 통해 게시글을 삭제한다.
- resp.sendRedirect( ) 로 요청값 "/" 을 보내도록 이동한다.
4. Model 생성

- BoardBean 타입의 객체를 받기 위해 ArrayList list 를 준비한다.
- getList( ) 메서드를 만들고 readFile( ) 메서드를 호출한다.
- 그리고 readFile( ) 로 호출해서 받은 ArrayList 를 반환한다.
( InputStream 으로 읽어낸 ArrayList 객체를 반환 )

- write( ) 메서드를 만들어 파라미터값을 저장한 HashMap 을 매개변수로 사용한다.
- BoardBean 클래스의 객체를 생성한다.
- BoardBean 클래스 안에 HashMap의 get( ) 메서드를 이용한 value 값 정보를 넣어준다.
- 그리고 이 정보들이 들어간 BoardBean 객체를 ArrayList 에 저장한다.
- writeFile( ) 를 호출한다.
( 글을 추가함으로 인해 파일에 보내줄 정보에 변화가 생겨서 )
![업로드중..]()
- detail( ) 메서드를 만들어서 ArrayList 의 get(int index) 메서드에 인덱스값을 보내 해당 BoardBean 객체를 반환한다.
- 이때 파라미터 값은 "숫자" 로 문자열이기 때문에 숫자로 형변환한다.

- remove( ) 메서드를 만들어서 ArrayList의 remove(int index) 메서드에 인덱스 값을 보내 해당 BoardBean 객체를 삭제한다.
- writeFile( ) 메서드를 호출한다.
( 글을 삭제함으로 인해 파일에 보내줄 정보에 변화가 생겨서 )

- writeFile( ) , readFile( ) 를 만들어 Object 보조스트림으로 파일을 따로 생성하여 서버가 닫혀도 정보가 사라지지 않도록 한다.
DB 의 저장역할을 File 객체와 Object 보조스트림으로 구현한 것이다.
- 주스트림 + 보조스트림 ( ObjectOutputStream ) 를 준비한다.
- 이때 생기는 FileNotFoundException 을 try-catch 로 처리한다.
FileOutputStream(경로) Stream 객체 생성시 경로에 따라 파일이 새로 생성되거나 덮어쓰면서 생성한다. 이때 덮어쓰지 않기 위해서는 (경로,true) 로 추가할지 여부를 적어주면 된다.
다만 여기서는 true로 덮어쓴다고 할 시 로직이 꼬여 새로 추가가 되지 않는 오류가 발생한다.
- Object 보조스트릠의 writeObject(); 를 통해 직렬화가 된 BoardBean 객체가 담긴 ArrayList 객체 데이터를 내보낸다.
- 다 보냈으면 flush( ) , close( ) 를 통해 자원을 닫는다.

- File 객체를 생성하여
"C:/img/temp/bbs.dat" 경로에 파일의 존재 유무를 확인한다.
- 파일 존재 유무를 확인하기 위한 File 객체를 생성하고 경로를 지정해준다.
- 파일이 존재하면 주스트림 + 보조스트림 ( ObjectInputStream ) 를 준비한다.
- 마찬가지로 FileNotFoundException 을 try-catch 로 처리한다.
- readObject( ) 를 통해 파일 안의 ArrayList 객체 정보를 가져온다.
이때 Object 객체 타입으로 보내주기 때문에 ArrayList 로 형변환이 필요하다.
- 다 읽어냈으면 close( ) 로 자원을 닫는다.
- 만약 파일이 존재하지 않으면 맨 처음 접속시에는
public static ArrayList<BoardBean> list = null; 상태이기 때문에
NullPointException 이 떨어지므로 ArrayList 객체를 생성해준다.
최초 접속시에는 ArrayList 객체만 존재하고 그 안에 내용물은 안넣은 상태이기 때문에 list.jsp 페이지의 <c:if test="${list.size() == 0}"> 조건이 되어 아직 작성된 글이 없습니다 문구가 뜬다.