본문 바로가기

스프링부트와 AWS로 구현하는 웹서비스

[스프링부트/AWS] 4장 게시글 수정, 삭제 화면 만들기 3

- 게시글 수정 화면 만들기

게시글 수정 API는 이미 만들어 두었습니다.(freewebdev.tistory.com/53)

 

1) PostsApiController 확인

...
public class PostsApiController {
...
	@PutMapping("/api/v1/posts/{id}")
    public Long update(@PathVariable Long id, @RequestBody PostsUpdateRequestDto requestDto){
        return postsService.update(id, requestDto);
    }
 ...

2) 수정화면 생성(posts-update.mustache)

{{>layout/header}}
<h1>게시글 수정</h1>
<div class="col-md-12">
    <div class="col-md-4">
        <form>
            <div class="form-group">
                <label for="id">글번호</label>
                <input type="text" class="form-control" id="id" value="{{post.id}}" readonly> <!-- 1) -->
            </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><!-- 2) -->
            </div>
            <div class="form-group">
                <label for="content">내용</label>
                <input type="text" class="form-control" id="content" value="{{post.content}}">
            </div>
        </form>
        <a href="/" role="button" class="btn btn-secondary">취소</a>
        <button type="button" class="btn btn-primary" id="btn-update">수정완료</button>
    </div>
</div>
{{>layout/footer}}

(1) {{post.id}}

  • 머스테치는 객체의 필드 접근 시 점(Dot)으로 구분합니다.
  • 즉, Post클래스의 id에 대한 접근은 post.id로 사용할 수 있습니다.

(2) readonly

  • input 태그에 읽기 가능만 허용하는 속성입니다.
  • id와 author는 수정할 수 없도록 읽기만 허용하도록 추가합니다.

 

※ IntelliJ에서 jQuery Plugins 설치

file - setting 또는 Ctrl + Alt + S
jQuery 검색 후 Download and Install
Ctrl + Space로 확인 가능

 

 

3) 수정하기 기능 추가(index.js에 update function 추가)

var main = {
    init : function () {
        var _this = this;
        ...

        $('#btn-update').on('click', function (){ // (1)
            _this.update();
        })
    }
    ,save : function () {
       ...
    }
    ,update : function(){   // (2)
        var data = {
            title: $('#title').val()
            ,content: $('#content').val()
        }

        var id = $('#id').val()

        $.ajax({
            type : 'PUT'    // 3)
            ,url : '/api/v1/posts/' + id    // 4)
            ,dataType : 'json'
            ,contentType : 'application/json; charset=utf-8'
            ,data : JSON.stringify(data)
        }).done(function () {
            window.location.href = '/';
        }).fail(function (error) {
            alert(JSON.stringify(error));
        })
    }
};

main.init();

(1) $('#btn-update').on('click')

  • btn-update랑 id를 가진 HTML 엘리먼트에 click 이벤트가 발생할 때 update function을 실행하도록 이벤트를 등록합니다.

(2) update : function()

  • 신규로 추가될 update function 입니다.

(3) type : 'PUT'

  • 여러 HTTP Method 중 PUT 메소드를 선택합니다.
  • PostsApiContoller에 있는 API에서 이미 @PutMapping으로 선언했기 때문에 PUT을 사용해야 합니다. 참고로 이는 REST 규약에 맞게 설정된 것입니다.
  • REST에서 CRUD는 다음과 같이 HTTP Method에 매핑됩니다.
    • 생성(Create) - POST
    • 읽기(Read) - GET
    • 수정(Update) - PUT
    • 삭제(Delete) - DELETE

(4) url : '/api/v1/posts/' + id

  • 어느 게시글을 수정할지 URL Path로 구분하기 위해 Path에 id를 추가합니다.

 

4) 수정페이지로 이동할 수 있도록 수정(index.mustache에 있는 List HTML 수정)

{{#posts}} 
	<tr>
		<td>{{id}}</td> 
		<td>
			<a href="/posts/update/{{id}}"> <!-- 1) -->
				{{title}}
			</a>
		</td>
		<td>{{author}}</td>
		<td>{{createdDate}}</td>
		<td>{{modifiedDate}}</td>
	</tr>
{{/posts}}

(1)  <a href="/posts/update/{{id}}">

  • 타이틀(title)에 a tag를 추가합니다.
  • 타이틀을 클릭하면 해당 게시글의 수정화면으로 이동합니다.

 

5) 수정페이지 이동 메소드(Java) 추가(IndexController.java)

...
@RequiredArgsConstructor
@Controller
public class IndexController {
...
	@GetMapping("/posts/update/{id}")
    public String postsUpdate(@PathVariable Long id, Model model){
        PostsResponseDto dto = postsService.findById(id);
        model.addAttribute("post",dto);
        return "posts-update";
    }
}

 

6) 페이지 확인(http://localhost:8080/)

* 글등록으로 한건 등록 후 진행(인메모리 디비이기 때문)

※ 실행도중 error가 발생한다면 디버그 모드로 에러 찾기

중단점 클릭 후 Debug 모드로 실행

- 게시글 삭제 만들기

게시글 삭제 API는 이미 만들어 두었습니다.(freewebdev.tistory.com/53)

 

1) 수정화면에 삭제버튼 추가(post-update.mustache)

<div class="col-md-12">
    <div class="col-md-4">
        <form>
            <div class="form-group">
                <label for="id">글번호</label>
                <input type="text" class="form-control" id="id" value="{{post.id}}" readonly> <!-- 1) -->
            </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><!-- 2) -->
            </div>
            <div class="form-group">
                <label for="content">내용</label>
                <input type="text" class="form-control" id="content" value="{{post.content}}">
            </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>

2) 삭제이벤트 JS 생성(index.js)

...
	$('#btn-delete').on('click', function (){
            _this.delete();
        })
...
	,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));
        })
    ...

3) 삭제 API 생성(PostsService)

...
    @Transactional
    public void delete(Long id){
        Posts posts = postsRepository.findById(id)
                .orElseThrow(() -> new IllegalArgumentException("해당 게시글이 없없습니다. id=" + id));

        postsRepository.delete(posts); // (1)
    }
   ...

(1) postsREpository.delete(posts)

  • JpaRepository에서 이미 delete 메소드를 지원하고 있습니다.
  • 엔티티를 파라미터로 삭제할 수도 있고, deleteById 메소드를 이용하면 id로 삭제할 수도 있습니다.
  • 존재하는 Posts인지 확인을 위해 엔티티 조회 후 그대로 삭제합니다.

4) delete 메소드 컨트롤러에 추가(PostsApiController)

    ...
    @DeleteMapping("/api/v1/posts/{id}")
    public Long delete(@PathVariable Long id){
        postsService.delete(id);
        return id;
    }
    ...

5) 성공 메세지 확인

 

 

출처 : 

jojoldu.tistory.com/463

 

[스프링 부트와 AWS로 혼자 구현하는 웹 서비스] 출간 후기

(출판사: 프리렉, 쪽수: 416, 정가: 22,000원) 서적 링크 오프라인 서점에는 2019.12.04 (수) 부터 올라갈 예정입니다. 강남 교보문고나 광화문 교보문고는 주말에도 올라올 순 있겠지만, 혹시 모르니

jojoldu.tistory.com