Blog

[Spring-LDW] 게시글 수정 및 삭제 화면 만들기

Category
Author
citeFred
citeFred
PinOnMain
1 more property
스프링 부트와 AWS로 혼자 구현하는 웹 서비스  : 인텔리제이, JPA, JUnit 테스트, 그레이들, 소셜 로그인, AWS 인프라로 무중단 배포까지 이동욱 저
Table of Content

게시글 수정(UPDATE) 화면 구성하기

posts-update.mustache

{{>layout/header}} <h1>게시글 수정</h1> <div class="col-md-12"> <div class="col-md-4"> <form> <div class="form-group"> <label for="title">글 번호</label> <input type="text" class="form-control" id="id" value="{{post.id}}" readonly> </div> <div class="form-group"> <label for="title">제목</label> <input type="text" class="form-control" id="title" value="{{post.title}}"> </div> <div class="form-group"> <label for="author"> 작성자 </label> <input type="text" class="form-control" id="author" value="{{post.author}}" readonly> </div> <div class="form-group"> <label for="content"> 내용 </label> <textarea class="form-control" id="content">{{post.content}}</textarea> </div> </form> <a href="/" role="button" class="btn btn-secondary">취소</a> <button type="button" class="btn btn-primary" id="btn-update">수정 완료</button> <button type="button" class="btn btn-danger" id="btn-delete">삭제</button> </div> </div> {{>layout/footer}}
HTML
복사

{{post.id}}

머스테치는 객체의 필드 접근 시 점(도트 구분자)로 구분
Post 클래스의 id 필드에 대한 접근은 post.id로 접근

readonly

input 태그에 읽기만 가능한 속성
id, author 처럼 수정할 수 없는 값을 받도록 하기 위함
경우에 따라 hidden field 속성으로 어떤 임시, 고정값들은 노출하지 않도록 하기도 할 수 있음

index.js

var main = { init : function () { var _this = this; ... $('#btn-update').on('click', function () { _this.update(); }); }, save : function () { var data = { ... }); }, update : function () { var data = { title: $('#title').val(), content: $('#content').val() }; var id = $('#id').val(); $.ajax({ type: 'PUT', url: '/api/v1/posts/'+id, dataType: 'json', contentType:'application/json; charset=utf-8', data: JSON.stringify(data) }).done(function() { alert('글이 수정되었습니다.'); window.location.href = '/'; }).fail(function (error) { alert(JSON.stringify(error)); }); } }; main.init();
JavaScript
복사

$('#btn-update').on('click', function () { … }

btn-update id(#, 클래스는 .)를 가진 요소를 클릭(온클릭 이벤트) 했을때 update 함수를 실행하도록 설정

type : ‘PUT’

HTTP 메소드 중 PUT메소드로 REST규약에 따라 설정한것 (API 컨트롤러도 @PutMapping으로 선언되어 있음)
생성(Create) - POST
조회(Read) - GET
수정(Update) - PUT
삭제(Delete) - DELETE

IndexController.java

package com.citefred.ldwspring.web; import com.citefred.ldwspring.service.PostsService; import com.citefred.ldwspring.web.dto.PostsResponseDto; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PutMapping; @RequiredArgsConstructor @Controller public class IndexController { private final PostsService postsService; ... @PutMapping("/posts/update/{id}") public String postsUpdate(@PathVariable Long id, Model model){ PostsResponseDto dto = postsService.findById(id); model.addAttribute("posts", dto); return "posts-update"; } }
Java
복사

@RequestParam과 @PathVariable

Controller 단에서 위 두 어노테이션은 uri를 통해 전달된 값을 파라미터로 받아오는 역할
@RequestParam는 Query String으로부터 값을 얻는다. key=value 형식, 여러개 사용 가능
http://localhost:8000/board?page=1&listSize=10
@PathVariable은 URL 자체에서 일부(단일) 값을 얻는 데 사용, 특정 게시글을 지정하는 등 목적
http://localhost:8000/board/1
필요에 따라서는 두 방법을 혼합해서 사용

글 수정 뷰 페이지+API 작동 테스트

where id = 1 을 통해서 1번 글의 게시글 수정 폼이 조회 된 것을 확인 할 수 있다.
수정 폼에 수정된 값들을 입력하고 버튼을 누르면
js에 작성된 버튼의 온클릭 이벤트에서 update요청인 PUT 메소드 방식의 API요청이 진행되고
DB의 게시글이 수정되는 것을 확인 할 수 있다.

게시글 삭제(DELETE) 화면 구성하기

posts-update.mustache

{{>layout/header}} <h1>게시글 수정</h1> <div class="col-md-12"> <div class="col-md-4"> <form> <div class="form-group"> <label for="title">글 번호</label> <input type="text" class="form-control" id="id" value="{{post.id}}" readonly> ... </form> <a href="/" role="button" class="btn btn-secondary">취소</a> <button type="button" class="btn btn-danger" id="btn-delete">삭제</button> </div> </div> {{>layout/footer}}
HTML
복사
삭제는 게시글을 확인하는 상태로 하는 경우가 많기 때문에 수정 폼에서 삭제 버튼을 추가하여 구현했다.

index.js

var main = { init : function () { var _this = this; ... $('#btn-delete').on('click', function () { _this.delete(); }); }, save : function () { var data = { ... }); }, update : function () { ... }); }, delete : function () { var id = $('#id').val(); $.ajax({ type: 'DELETE', url: '/api/v1/posts/'+id, dataType: 'json', contentType:'application/json; charset=utf-8' }).done(function() { alert('글이 삭제되었습니다.'); window.location.href = '/'; }).fail(function (error) { alert(JSON.stringify(error)); }); } }; main.init();
JavaScript
복사
삭제 기능의 ajax 요청 함수를 작성한다. 동일하게 버튼에 온클릭 이벤트로 DELETE 방식 요청을 API 주소로 요청한다.

PostsService.java

package com.citefred.ldwspring.service; import com.citefred.ldwspring.domain.posts.Posts; import com.citefred.ldwspring.domain.posts.PostsRepository; import com.citefred.ldwspring.web.dto.PostsListResponseDto; import com.citefred.ldwspring.web.dto.PostsResponseDto; import com.citefred.ldwspring.web.dto.PostsSaveRequestDto; import com.citefred.ldwspring.web.dto.PostsUpdateRequestDto; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.List; import java.util.stream.Collectors; @RequiredArgsConstructor @Service public class PostsService { private final PostsRepository postsRepository; ... @Transactional public void delete(Long id){ Posts posts = postsRepository.findById(id) .orElseThrow(() -> new IllegalArgumentException("해당 게시글이 없습니다. id=" + id)); postsRepository.delete(posts); } }
Java
복사

postsRepository.delete(posts);

JpaRepository에서 delete메소드를 지원하고 있다.
존재하는 게시글인지 확인 후 해당 게시글 조회 후 그 게시글을 삭제

PostsApiController.java

package com.citefred.ldwspring.web; import com.citefred.ldwspring.service.PostsService; import com.citefred.ldwspring.web.dto.PostsResponseDto; import com.citefred.ldwspring.web.dto.PostsSaveRequestDto; import com.citefred.ldwspring.web.dto.PostsUpdateRequestDto; import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.*; @RequiredArgsConstructor @RestController public class PostsApiController { private final PostsService postsService; ... @DeleteMapping("/api/v1/posts/{id}") public Long delete(@PathVariable Long id){ postsService.delete(id); return id; } }
Java
복사

@DeleteMapping("/api/v1/posts/{id}")

삭제 기능 API 기능 추가

글 삭제 뷰 페이지+API 작동 테스트

게시글을 삭제할 수 있도록 테스트 글 작성
2번 게시글을 대상으로 삭제 요청
2번 테스트 글이 삭제된 갱신된 글 목록
Search
 | Main Page | Category |  Tags | About Me | Contact | Portfolio