Backend
home
🖋️

7일차

생성일
2024/07/16 15:34
태그
본 프로젝트는 “스프링부트 3 백엔드 개발자 되기” 서적을 참고하여 진행하였음

트러블슈팅

스프링 부트 3.2 버전 매개변수 이름 인식 문제
스프링 부트 3.2부터 매개변수 이름을 인식하지 못하는 문제가 있는데 자바 컴파일러에 -parameter 옵션을 넣어주어야 애노테이션의 이름을 생략할 수 있다.
해당 케이스 같은 경우 빌드 시 Gradle이 아닌 IntelliJ IDEA 로 설정되어 있어서 발생한 문제였다.
Gradle을 사용해서 빌드하고 실행한다. 이렇게 하면 parameter 추가할 필요 없다.
만약에 IntelliJ IDEA 로 유지를 하고 사용해야 한다면 애너테이션 옆에 -parameter 옵션을 추가해주어야 한다.
스프링 부트 3.2 전까지는 바이트코드를 파싱해서 매개변수 이름을 추론하려고 시도했으나 스프링 부트 3.2부터는 이런 시도를 하지 않는다. 그래서 에러가 발생한 것이다.
에러 해결 후 정상적으로 글 상세 화면이 잘 나오는 것을 확인할 수 있다.

삭제 기능 구현

글 상세 화면에서 [삭제] 버튼을 눌러 글을 삭제하는 기능 구현
// 삭제 기능 - resources/static/js/article.js const deleteButton = document.getElementById('delete-btn'); if (deleteButton) { deleteButton.addEventListener('click', event => { let id = document.getElementById('article-id').value; fetch(`/api/articles/${id}`, { method: 'DELETE' }) .then(() => { alert('삭제가 완료되었습니다.'); location.replace('/articles'); }) }) }
JavaScript
복사
해당 자바스크립트 코드는 HTML에서 id를 delete-btn으로 설정한 엘리먼트를 찾아 그 엘리먼트에서 클릭 이벤트가 발생하면 fetch() 메서드를 통해 /api/articles/ DELETE 요청을 보내는 역할을 한다. fetch() 메서드에 이어지는 then() 메서드는 fetch()가 잘 완료되면 연이어 실행되는 메서드이다. alert() 메서드는 then() 메서드가 실행되는 시점에 웹 브라우저 화면으로 삭제가 완료되었음을 알리는 팝업을 띄워주고, location.replace() 메서드는 실행 시 사용자의 웹 브라우저 화면을 현재 주소에 기반하여 옮겨준다.
테스트 확인 - 삭제 알람 및 DB에서 삭제된 내용 확인

수정/생성 기능 추가

수정 로직 - URL에 ?id=123과 같이 수정할 글의 id를 쿼리 파라미터에 추가해 요청한다.
뷰에서는 쿼리 파라미터의 id 여부에 따라 [수정]과 [생성] 중 적절한 버튼을 보여줘야 한다.
쿼리 파라미터
HTTP 요청에서 URL의 끝에 ‘?’로 시작하는 키 값으로 이루어진 문자열이며 ‘&’로 구분한다.
키 : id, 값: 123
쿼리 파라미터가 있는 경우 컨트롤러 메서드 수정이 필요한데 엔티티를 조회하여 기존 글 데이터를 모델에 넣어 화면에 보여줘야 한다.
만약에 쿼리 파라미터가 없다면 새 글이므로 화면에 아무것도 보여줄 필요가 없다.
생성 로직
수정 화면 보여주기 위한 컨트롤러 작성
// BlogViewController.java @GetMapping("/new-article") // id 키를 가진 쿼리 파라미터 값을 id 변수에 매핑(id가 없을 수도 있다) public String newArticle(@RequestParam(required = false) Long id, Model model) { if (id == null) { // id가 없으면 생성 model.addAttribute("article", new ArticleViewResponse()); } else { // id가 없으면 수정 Article article = blogService.findById(id); model.addAttribute("article", new ArticleViewResponse(article)); } return "newArticle"; }
Java
복사
수정/생성 뷰
newArticle.html
<!doctype html> <html xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>블로그 글</title> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css"/> </head> <body> <div class="p-5 mb-5 text-center</> bg-light"> <h1 class="mb-3">My Blog</h1> <h4 class="mb-3">블로그에 오신 것을 환영합니다.</h4> </div> <div class="container mt-5"> <div class="row"> <div class="col-lg-8"> <article> <input type="hidden" id="article-id" th:value="${article.id}"> <header class="mb-4"> <input type="text" class="form-control" placeholder="제목" id="title" th:value="${article.title}"> </header> <section class="mb-5"> <textarea class="form-control h-25" rows="10" placeholder="내용" id="content" th:text="${article.content}"></textarea> </section> <button th:if="${article.id} != null" type="button" id="modify-btn" class="btn btn-primary btn-sm">수정</button> <button th:if="${article.id} == null" type="button" id="create-btn" class="btn btn-primary btn-sm">등록</button> </article> </div> </div> </div> </body> </html>
HTML
복사
article.js
// 수정 기능 // id가 modify-btn인 엘리먼트 조회 const modifyButton = document.getElementById('modify-btn'); if (modifyButton) { // 클릭 이벤트가 감지되면 수정 API 요청 modifyButton.addEventListener('click', event => { let params = new URLSearchParams(location.search); let id = params.get('id'); fetch(`/api/articles/${id}`, { // fetch 메서드를 통해 수정 API로 /api/articles/ PUT 요청 보냄 method: 'PUT', headers: { "Content-Type": "application/json", // 요청 형식 지가 }, body: JSON.stringify({ // title과 content를 가져옴 title: document.getElementById('title').value, content: document.getElementById('content').value }) }) .then(() => { alert('수정이 완료되었습니다.'); location.replace(`articles/${id}`); }); }); }
JavaScript
복사
테스트 확인 - 수정 알람 및 DB에서 수정된 내용 확인