💡 게시판 - 파일 업로드

2026. 7. 20. 21:33·Project/나의 작은 프로젝트

이 글은 Velog에서 이전한 글입니다. Velog 원문 보기

이번에는 게시판의 파일 업로드에 관해서 작성을 하겠다. 이번 글은 업로드만 다루고 파일 다운로드에 관해서는 더 공부를 하고 작성을 하겠다.


우선 다음의 2가지가 필요하다

  • 파일이 저장된 경로와
  • 파일의 이름

mariaDB에 컬럼을 추가하겠다.

filename : 파일의 이름에 해당하는 컬럼
filePath : 파일의 저장된 경로에 해당하는 컬럼

DB의 Table을 수정했으니 Entity 또한 수정을 하겠다.

Board

@Entity
@Data
public class Board extends TimeEntity{

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    private String title;
    private String content;
    private String author;

    // 파일 업로드를 위한 필드 추가
    private String filename;
    private String filepath;

    //수정을 위한 생성자
    public Board(String title, String content, String author) {
        this.title = title;
        this.content = content;
        this.author = author;
    }

    //기본 생성자 추가!
    public Board() {

    }
}

DB의 테이블에 filename, filepath를 추가했기에 Entity인 Board에도 private Strinf filename, private String filepath를 추가한다.

Entity까지 수정을 했으니 게시글 작성 페이지를 수정해서 파일 업로드 부분을 만들어주겠다.

boardWrite.html

<body>
<div class="container">
    <h1>게시글 작성</h1>
    <form th:action="@{/board/write}" method="post" enctype="multipart/form-data"> <!--추가된 부분-->
        <div class="form-group">
            <label for="title">제목</label>
            <input type="text" id="title" name="title" required>
        </div>
        <div class="form-group">
            <label for="author">작성자</label>
            <input type="text" id="author" name="author" required>
        </div>
        <div class="form-group">
            <label for="content">내용</label>
            <textarea id="content" name="content" rows="8" required></textarea>
        </div>
        <!--새로 추가된 부분-->
        <input type="file" name="file">
        <!---->
        <button type="submit" class="btn">작성 하기</button>
    </form>
</div>
</body>

파일 업로드를 해주기 위해서는 속성을 추가해줘야한다.
boardWrite의 form에 enctype="multipart/form-data이 추가되었다.
또한, 입력창인 <input type="file" name="file">추가되었다. 이제 실행을 해서 확인을 해보자.


게시글 작성 페이지


게시글 작성 페이지로 오면 위 사진 처럼 파일을 선택할 수 있는 태그가 추가된 것을 확인할 수 있다.
그러나 아직 파일을 선택해서 작성을 해도 DB에 저장되지 않기 때문에 코드를 추가하고 업로드한 파일을 저장할 디렉토리를 하나 만들겠다.

resources/static/files

우선 파일을 저장할 디렉토리를 하나 만들어준다.


BoardService/save 수정 전

public Board save(Board board) {
     return boardRepository.save(board);
}

BoardService/save 수정 후

public void save(Board board, MultipartFile file) throws Exception {

    //저장할 경로를 지정
    String projectPath = System.getProperty("user.dir") + "/src/main/resource/static/files";

    // 랜덤 식별자 생성
    UUID uuid = UUID.randomUUID();

    // uuid + _ + 파일의 원래 이름
    String fileName = uuid + "_" + file.getOriginalFilename(); 

    //파일을 생성할 것인데 경로는 projectPath, 이름은 filename로 담긴다는 뜻
    File saveFile = new File(projectPath, fileName);

    file.transferTo(saveFile);

    board.setFilename(fileName); //DB에 filename 저장
    board.setFilepath("/files/" + fileName); //DB에 파일 저장 경로 저장

    boardRepository.save(board)    
}

게시글을 작성하는 코드인 save 메소드에 MultipartFile file 매개변수를 추가한다. 이는 파일을 받는 역할을 한다.

이때 주의할 것이 있다. 저장할 경로를 지정할 때 윈도우와 맥의 경우 다른 부분이 존재한다.

  • 윈도우
    • "\\src\\main\\resource\\static\\files";
  • 맥
    • "/src/main/resource/static/files";

게시글 작성 메서드인 save는 컨트롤러와 게시글 수정에서도 사용이 된다. save에 매개변수를 추가했으니 컨트롤러와 수정 부분도 수정을 해주겠다.

BoardControll

@PostMapping("/board/write")
public String boardWrite(Board board, Model model, MultipartFile file) 
throws Exception {

    boardService.save(board, file);
    model.addAttribute("message", "글 작성이 완료되었습니다.");
    model.addAttribute("searchUrl", "/board/list");

    return "message'
}

매개 변수 MultipartFile file을 추가했다.


BoardService/update

public void update(Integer id, Board updateBoard, MultipartFile file) 
throws Exception {

    Board board = boardRepository.findById(id).get();
    board.setTitle(updateBoard.getTitle());
    board.setAuthor(updateBoard.getAuthor());
    board.setContent(updateBoard.getContent());

    save(board, file);
}

BoardController/postUpdate

@PostMapping("/board/post/update/{id}")
public String postUpdate(@PathVariable Integer id, Board board, 
Model model, MultipartFile file) throws Exception {

    boardService.update(id, board, file);

    model.addAttribute("message", "게시글 수정이 완료되었습니다.");
    model.addAttribute("searchUrl", "/board/post/" + id);

    return "message";
}

수정이 필요한 파일을 모두 수정을 했다. 이제 실행을 해서 기능이 잘 동작하는지 확인해보자.


게시글 작성 페이지

우선 '파일 업로드 테스트' 글을 작성하며 아래의 귀여운 강아지 사진을 첨부하겠다.

 

우선적으로 DB에 잘 저장이 되었는지 확인을 해보자.


가장 아래가 방금 작성한 글인데 filename과 filepath 등이 저장된 것이 보인다.

DB까지 확인을 했으니 이제 files 폴더를 확인해보자. 게시글의 파일은 모두 files 폴더에 저장을 하고 불러온다.

files 폴더를 보니 DB의 filename과 일치하는 이름을 사진 사진이 폴더에 존재한다.

마지막으로 게시판 상세 페이지에서 확인을 해보자.

게시글 상세 페이지


게시글 상세 페이지이다. 파일 업로드 기능이 정상적으로 구현이 되었다면 '사진'을 클릭했을 때 귀여운 강아지가 보여야한다. 이제 클릭 해보겠다.


성공적으로 강아지 사진이 보인다! 파일 업로드 기능이 정상적으로 구현됐다.


여러모로 부족한 점이 많다.

  • 파일 다운로드 기능이 없다.
  • 사진을 보기 위해서는 서버 재실행이 필요하다.
  • 사진을 클릭해서 보는 것이 아닌 게시글 상세 페이지에 보이고 싶다.
  • 수정 페이지에서 사진 수정이 불가하다.

위에 적은 것처럼 아직 부족한 것이 많다. 이 부분들은 차후 하나하나 수정할 계획이다.


다음 글은 수정 페이지에서 사진 수정이 가능하도록 변경하는 글을 작성하겠습니다. 글에서 부족한 부분이 많을 것 같습니다. 모든 지적을 환영합니다!!

더 자세한 코드는 깃허브를 참고해주세요!

깃허브: https://github.com/pp8817/ToyProjectBoard

'Project > 나의 작은 프로젝트' 카테고리의 다른 글

💡 게시판 - 파일 업로드 3(개선)  (0) 2026.07.20
💡 게시판 - 파일 업로드 2  (0) 2026.07.20
💡 게시판 - 검색 기능  (0) 2026.07.20
💡 게시판 - 페이징 처리  (0) 2026.07.20
💡 게시판 - JPA Auditiong으로 작성 시간 추가  (0) 2026.07.20
'Project/나의 작은 프로젝트' 카테고리의 다른 글
  • 💡 게시판 - 파일 업로드 3(개선)
  • 💡 게시판 - 파일 업로드 2
  • 💡 게시판 - 검색 기능
  • 💡 게시판 - 페이징 처리
pp8817
pp8817
공부한 내용, 개발 관련 지식, 트러블 슈팅 등을 기록합니다. 이전 블로그: https://velog.io/@pp8817/posts
  • pp8817
    끄적이는 개발 log
    pp8817
  • 전체
    오늘
    어제
    • 분류 전체보기 (273)
      • Project (71)
        • 척척학사 (29)
        • Book (23)
        • Saynow (3)
        • YAPP 27기 (4)
        • 나의 작은 프로젝트 (10)
        • Landit (2)
      • Backend (88)
        • Spring (13)
        • Spring MVC (13)
        • Spring Security (4)
        • JPA (26)
        • Database (19)
        • HTTP·Web (13)
        • Architecture (0)
      • Language·CS (59)
        • Java·Kotlin (5)
        • CS Interview (17)
        • Backend Interview (5)
        • Concepts (32)
      • Algorithm (25)
        • Algorithm (24)
        • 소마 알고리즘 스터디 (1)
      • Infra (8)
      • Troubleshooting (11)
      • Retrospective (6)
      • Etc (5)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    나의 작은 프로젝트
    트러블슈팅
    BOJ
    척척학사
    Algorithm
    개념 정리!
    Python
    java
    Book
    HTTP WEB 기본 지식
    CS Interview
    interview
    Spring
    http
    Project
    object
    OS
    게시판
    jpa
    Spring MVC
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.6
pp8817
💡 게시판 - 파일 업로드
상단으로

티스토리툴바