# TIL - 2026.08.21

ssls·4일 전

📌 오늘 학습한 주제

  • 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 객체 리스트를 ObjectOutputStreamObjectInputStream을 이용해 파일(.txt)로 영속화하고 다시 복원하는 직렬화(Serialization) 기법을 학습했다.
  • Front Controller 패턴 (BlogFrontController.java): 클라이언트의 모든 요청(list, read, insert, update, delete, file)을 단일 창구인 BlogFrontController에서 수신한 후, BlogBeanFactory에서 해당 엔드포인트 전담 컨트롤러를 찾아 형변환 후 비즈니스 로직을 위임하는 아키텍처를 구현했다.
  • 파일 및 수정 컨트롤러 분리 (FileController.java, UpdateController.java): 파일 저장/로드를 담당하는 FileController와 DTO 빌더 패턴을 적용해 수정 데이터를 넘겨주는 UpdateController를 독립적으로 모듈화했다.

💻 오늘 핵심 코드

1. 객체 직렬화 및 파일 입출력 (IOStreamApp.java)

// DTO 리스트 객체 파일 직렬화 및 역직렬화
String path = "./object.txt";

// 1. 직렬화 (파일 저장)
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();
}

// 2. 역직렬화 (파일 읽기)
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(...))을 전면 적용하여 예외 발생 여부와 상관없이 스트림이 안전하게 닫히도록 개선함.

🎯 다음에 할 일

  • 직렬화 대상 DTO 클래스에 Serializable 인터페이스 구현 및 serialVersionUID 선언 의미 정립하기
  • 파일 입출력 로직을 실제 JDBC/데이터베이스 연동 DAO 구조로 확장 전환해보기
profile
성장중

0개의 댓글