📌 오늘 학습한 주제
- Java I/O 입출력 스트림 및 객체 직렬화/역직렬화 (
ObjectInputStream, ObjectOutputStream)
- AutoCloseable 및 Try-with-resources 구문을 활용한 안전한 스트림 자원 해제 (
IOStreamApp.java)
- Front Controller 패턴 기반의 단일 진입점 라우팅 아키텍처 (
BlogFrontController.java)
- 계층별 기능 분리: 파일 입출력 및 수정 전담 컨트롤러 구현 (
FileController.java, UpdateController.java)
💡 오늘 배운 것 — 나만의 언어로
① 오늘의 목표
- Java I/O 스트림을 통한 텍스트 및 객체 데이터 파일 입출력(직렬화) 메커니즘을 마스터하고, Front Controller 패턴을 적용해 웹 엔드포인트 요청을 각 전담 컨트롤러로 분기하는 라우팅 시스템 구축하기
② 학습할 내용
- I/O 스트림 및 직렬화 (
IOStreamApp.java): 바이트 스트림과 문자 스트림(BufferedReader, BufferedWriter)의 차이를 익히고, DTO 객체 리스트를 ObjectOutputStream과 ObjectInputStream을 이용해 파일(.txt)로 영속화하고 다시 복원하는 직렬화(Serialization) 기법을 학습했다.
- Front Controller 패턴 (
BlogFrontController.java): 클라이언트의 모든 요청(list, read, insert, update, delete, file)을 단일 창구인 BlogFrontController에서 수신한 후, BlogBeanFactory에서 해당 엔드포인트 전담 컨트롤러를 찾아 형변환 후 비즈니스 로직을 위임하는 아키텍처를 구현했다.
- 파일 및 수정 컨트롤러 분리 (
FileController.java, UpdateController.java): 파일 저장/로드를 담당하는 FileController와 DTO 빌더 패턴을 적용해 수정 데이터를 넘겨주는 UpdateController를 독립적으로 모듈화했다.
💻 오늘 핵심 코드
1. 객체 직렬화 및 파일 입출력 (IOStreamApp.java)
String path = "./object.txt";
try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(new File(path)))) {
oos.writeObject(blogs);
System.out.println("debug >>>> object.txt save ok");
} catch (Exception e) {
e.printStackTrace();
}
try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(new File(path)))) {
List<BlogResponseDTO> list = (List<BlogResponseDTO>) ois.readObject();
list.forEach(System.out::println);
} catch (Exception e) {
e.printStackTrace();
}
2. Front Controller 단일 진입점 라우팅 (BlogFrontController.java)
package features.blogs.facade;
import features.blogs.controller.*;
import features.blogs.domain.dto.BlogResponseDTO;
import features.blogs.factory.BlogBeanFactory;
import features.blogs.util.ResponseEntity;
import java.util.List;
public class BlogFrontController {
private BlogBeanFactory factory;
public BlogFrontController() {
factory = BlogBeanFactory.getInstance();
}
public ResponseEntity<List<BlogResponseDTO>> list(String endPoint) {
Object controller = factory.getBean(endPoint);
return ((ListController) controller).list();
}
public boolean file(String endPoint, String action) {
FileController controller = (FileController) factory.getBean(endPoint);
if ("save".equals(action)) {
return controller.save();
} else {
return controller.load();
}
}
}
3. 게시글 수정 전담 컨트롤러 (UpdateController.java)
package features.blogs.controller;
import features.blogs.domain.dto.BlogRequestDTO;
import features.blogs.service.BlogReactService;
public class UpdateController {
private BlogReactService service;
public UpdateController(BlogReactService service) {
this.service = service;
}
public int update(int blogId, String title, String content) {
return service.update(BlogRequestDTO.builder()
.title(title)
.content(content)
.blogId(blogId)
.build());
}
}
🛠️ 실습 / 결과물 & 참고 자료
③ 실습 / 결과물
- 강의 실습코드:
IOStreamApp.java, BlogFrontController.java, FileController.java, UpdateController.java 연동을 통해 객체 직렬화/역직렬화 및 Front Controller를 경유한 CRUD/파일 액션 엔드포인트 분기 실행 확인.
④ 참고 자료
- Oracle Java Documentation: Java I/O Streams & Object Serialization
- Design Patterns: Front Controller Pattern in Enterprise Java
🔍 문제와 해결
- 막힌 부분: 스트림 자원을 사용한 뒤
close() 처리를 누락해 파일 락(Lock)이나 리소스 누수가 발생할 수 있는 위험성 점검.
- 해결 방법:
AutoCloseable 인터페이스를 지원하는 Try-with-resources 구문(try(...))을 전면 적용하여 예외 발생 여부와 상관없이 스트림이 안전하게 닫히도록 개선함.
🎯 다음에 할 일