본문 바로가기
프로젝트/게시판 만들기

[Spring boot] 게시판 만들기 (3주차 : 게시글 상세 페이지, 게시글 삭제 및 수정, 메시지 띄우기, 파일 업로드)

by zzingni 2025. 5. 3.

 

※ [한코딩] 게시판 만들기 유튜브를 참고하여 진행하는 프로젝트입니다.

 

 

 

개발 환경


사용언어 : Java

프레임 워크 : Spring boot

통합 개발 환경 : IntelliJ

데이터베이스 : MariaDB

뷰 템플릿(템플릿 엔진) : Thymeleaf

 

 

프로젝트 진행 순서


 

 

 

[Spring boot] 게시판 만들기 (1주차 : 개발 환경 세팅, 프로젝트 생성)

※ [한코딩] 게시판 만들기 유튜브를 참고하여 진행하는 프로젝트입니다.   개발 환경사용언어 : Java프레임 워크 : Spring boot통합 개발 환경 : IntelliJ데이터베이스 : MariaDB뷰 템플릿(템플릿 엔진)

zprograming.tistory.com

 

1. 개발 환경 세팅

 - IntelliJ Community 다운로드

 - MariaDB 다운로드

 - MySQL Workbench 다운로드

 

2. 프로젝트 생성

 - IntelliJ Community에서 Spring Boot 프로젝트 생성 (https://start.spring.io/)

 - MariaDB Database(스키마) 생성 

 

 

 

[Spring boot] 게시판 만들기 (2주차 : DB 테이블 생성, 게시글 작성폼 생성, 글 작성 처리, 게시글 리

※ [한코딩] 게시판 만들기 유튜브를 참고하여 진행하는 프로젝트입니다.   개발 환경사용언어 : Java프레임 워크 : Spring boot통합 개발 환경 : IntelliJ데이터베이스 : MariaDB뷰 템플릿(템플릿 엔진)

zprograming.tistory.com

 

3. 게시물 작성

- db에 board 테이블 및 필드 생성

- 게시글 작성 폼 생성

 

4. 게시물 리스팅

 

 

5. 게시물 삭제

- 게시글 상세 페이지 

 

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymleaf.org">
<head>
    <meta charset="UTF-8">
    <title>게시글 상세 페이지</title>
</head>
<body>
    <h1 th:text="${board.title}">제목입니다.</h1>
    <p th:text="${board.content}">내용이 들어갈 부분입니다.</p>
    <a th:href="@{/board/delete(id=${board.id})}">글삭제</a>
    <p></p>
    <a th:href="@{/board/modify/{id}(id=${board.id})}">수정</a>
</body>
</html>

 

게시글 상세페이지를 출력하는 html 파일을 작성한다.

 

    // 특정 게시글 불러오기
    public Board boardView(Integer id) {
        return boardRepository.findById(id).get();
    }
    @GetMapping("/board/view") // localhost8090:/board/view?id=1
    public String boardView(Model model, @RequestParam("id") Integer id){
        model.addAttribute("board", boardService.boardView(id));
        return "boardview";
    }

 

boardService에서 특정 게시글을 선택하면 불러올 수 있는 코드를 작성하고, 컨트롤러 board/view에서 마찬가지로 id를 매개변수로 가져와 처리할 수 있는 코드를 작성한다.

 

<td th:text="${board.id}">1</td>
                    <td>
                        <a th:text="${board.title}" th:href="@{/board/view(id=${board.id})}"></a>
                    </td>

 

리스트에서 제목을 눌렀을 경우 이동을 해야 하기 때문에, 그 부분을 처리하기 위해 boardlist.html 파일도 코드를 수정해준다.

 

 

- 게시글 삭제

    // 특정 게시글 삭제
    public void boardDelete(Integer id) {
        boardRepository.deleteById(id);
    }

 

boardService에서 게시글을 삭제하는 메서드를 작성한다.

    @GetMapping("/board/delete")
    public String boardDelete(@RequestParam("id") Integer id) {
        boardService.boardDelete((id));
        return "redirect:/board/list";
    }

 

컨트롤러에서도 삭제를 처리할 수 있는 코드를 작성한다.

게시글을 삭제하면 게시글 리스트로 돌아가기 때문에 redirect를 사용하여 return 한다.

 

 

 

6. 게시물 수정

 

- 게시글 수정

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymleaf.org">
<head>
  <meta charset="UTF-8">
  <title>게시물 수정 폼</title>
</head>
<style>
  .layout {
      width : 500px;
      margin : 0 auto;
      margin-top : 40px;
  }
  .layout input {
      width : 100%;
      box-sizing : border-box;
  }

  .layout textarea {
      width : 100%;
      margin-top : 10px;
      min-height : 300px;
  }

</style>
<body>
<div class="layout">
  <form th:action="@{/board/update/{id}(id=${board.id})}" method="post">
    <input name="title" type = "text" th:value="${board.title}">
    <textarea name="content" th:text="${board.content}"></textarea>
    <button type="submit">수정</button>
  </form>
</div>
</body>
</html>

 

수정시 나오는 페이지를 위해 modify.html 작성한다. (write.html과 동일)

    @GetMapping("/board/modify/{id}")
    public String boardModify(Model model, @PathVariable("id") Integer id) {
        model.addAttribute("board", boardService.boardView(id));
        return "boardmodify";
    }

 

컨트롤러에서 modify 링크와 mapping 시켜준다.

 

   @PostMapping("/board/update/{id}")
    public String boardUpdate(@PathVariable("id") Integer id, Board board) {

        Board boardTemp = boardService.boardView(id);
        boardTemp.setTitle(board.getTitle());
        boardTemp.setContent(board.getContent());

        boardService.write(boardTemp);
        return "redirect:/board/list";
    }

 

 

수정된 내용을 업데이트 해주는 부분도 컨트롤러에 작성한다.

 

내용이 정상적으로 수정되어 반영된다!

 

- 메시지 띄우기

<!DOCTYPE html>
<html lang="en" xmlns:th="http://thymleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<script th:inline="javascript">

  /*<![CDATA[*/

  var message = [[${message}]];
  alert(message);

  location.replace([[${searchUrl}]])

  /*]]>*/
</script>
<body>

</body>
</html>

 

코드가 정상적으로 등록되었다는 메시지를 처리하기 위해 message.html 파일을 만든다.

    @PostMapping("/board/writepro")
    public String boardWritePro(Board board, Model model) {

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

 

컨트롤러의 writepro 부분을 message를 리턴해주는 코드로 변경한다.

 

 

글을 작성하면 글 작성이 완료되었다는 메세지가 정상적으로 출력된다.

 

 

 

7. 파일 업로드

 

 

 

Trouble Shooting


 

1. 게시글 상세 페이지 에러 

/view?=1 로 접속시 자꾸 에러가 발생 ... 

 

에러메세지

ERROR 31664 --- [board] [nio-8090-exec-5] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed: java.lang.IllegalArgumentException: Name for argument of type [java.lang.Integer] not specified, and parameter name information not available via reflection. Ensure that the compiler uses the '-parameters' flag.] with root cause
 
 
 

원인은 1. 데이터베이스 날아감  2. 코드 오류 두가지였다.

 

DROP PROCEDURE IF EXISTS testDataInsert;

DELIMITER //

CREATE PROCEDURE testDataInsert()
BEGIN
    DECLARE i INT DEFAULT 1;
    WHILE i <= 120 DO
        INSERT INTO board(title, content)
        VALUES(CONCAT('제목', i), CONCAT('내용', i));
        SET i = i + 1;
    END WHILE;
END //

DELIMITER ;

 

우선 board 테이블을 다시 생성하고 기존 프로시저를 삭제 후 데이터를 다시 심어줬다.

 

@GetMapping("/board/view")
public String boardView(Model model, Integer id) {
    model.addAttribute("board", boardService.boardView(id));
    return "boardview";
}


이게 오류가 발생한 코드이다.

java 컴파일 시 -parameters 옵션 없이 컴파일하면, 메서드 파라미터 이름(id)이 class 파일에 저장되지 않아 스프링이 그 이름을 인식하지 못한다고 한다. 

  @GetMapping("/board/view") // localhost8090:/board/view?id=1
    public String boardView(Model model, @RequestParam("id") Integer id){
        model.addAttribute("board", boardService.boardView(id));
        return "boardview";
    }

 

@RequestParm을 붙여 다시 실행하니 정상적으로 동작했다.

 

 

2. 파일다운로드 버튼 클릭시 404 error 발생

File saveFile = new File(projectPath, fileName);

 

영상에서는 BoardService.java 파일의 이 부분 코드에서 두번째 매개변수를 "name" 으로 설정하는데,

fileName 변수로 지정해줘야 이미지 파일이 정상적으로 files 폴더 안에 저장된다.

 

 

package com.study.board.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/files/**")
                .addResourceLocations("file:" + System.getProperty("user.dir") + "/src/main/resources/static/files/");
    }
}

 

 

그 후 board 경로 밑에 config 패키지 생성 > WebConfig.java파일 작성한다.

 

 

3주차 소감


workbench가 자꾸 날 괴롭힌다...