Spring Boot 게시판 만들기 9 - 페이지 수정하기

9. 페이지 수정하기

데이터를 수정하기 위해서는 수정하고자 하는 데이터를 찾아야 하기 때문에 id값이 필요하다. input태그의 type속성을 hidden으로해 form을 작성한 후 나머지 데이터와 함께 id값을 넘겨주도록 한다.

post.html

<h2>게시글 작성</h2>
<div class="card" style="padding: 20px; border-radius: 15px; margin: 20px auto;">
<form class=" form-horizontal" method="post" th:action="@{/post}" th:object="${postDto}">
<input type="hidden" th:if="*{id != null and id > 0}" th:field="*{id}"/>

<div class="form-group">
<label>제목</label>
<div class="col-sm-12">
<input type="text" style="border-radius: 5px;" class="form-control" th:field="*{title}" placeholder="제목을 입력해 주세요."/>
</div>
</div>

<div class="form-group">
<label>이름</label>
<div class="col-sm-12">
<input type="text" style="border-radius: 5px;" class="form-control" th:field="*{name}"placeholder="이름을 입력해 주세요."/>
</div>
</div>

<div class="form-group">
<label>내용</label>
<div class="col-sm-12">
<textarea class="form-control" style="height: 300px; border-radius: 5px;" th:field="*{content}"
placeholder="내용을 입력해 주세요."></textarea>
</div>
</div>

<div class="btn_wrap text-center">
<a th:href="@{/}" class="btn btn-default waves-effect waves-light">뒤로가기</a>
<button type="submit" class="btn btn-primary waves-effect waves-light">저장하기</button>
</div>
</form>
</div>

수정페이지로 이동하기

데이터를 수정위해서 URL경로를 통해 수정할 데이터의 id값을 받아온 후 해당 id값을 이용해 데이터를 조회한 뒤 기존 데이터를 반환하도록 한다. 내부 로직은 상세페이지를 가져오는 것과 똑같고 반환하는 템플릿만 다르게 반환한다.

PostController.java

@GetMapping("/post/{postId}/revise")
public String getPostDetailsToRevise(@PathVariable("postId") Long id, Model model) {
Post post = postService.getPostById(id);

PostDto postDto = PostDto.builder()
.id(post.getId())
.name(post.getName())
.title(post.getTitle())
.content(post.getContent())
.writeTime(post.getWriteTime())
.build();

model.addAttribute("postDto", postDto);
return "post";
}

PostControllerTest.java

@Test
@DisplayName("포스트 수정 페이지로 이동한다.")
public void getPostDetailsToRevise() throws Exception {
Post mockPost = Post.builder()
.id(1L)
.name("tester")
.title("test")
.content("test")
.writeTime(LocalDateTime.now())
.build();

given(postService.getPostById(1L)).willReturn(mockPost);
ResultActions resultActions = mockMvc.perform(get("/post/1/revise"));
verify(postService).getPostById(1L);

resultActions
.andExpect(status().isOk());
}

데이터 수정 요청 처리를 위한 Control

입력받은 데이터를 확인해 id값이 있을 경우에는 새로운 Post를 생성하게 id값이 없는 경우에는 기존 데이터를 Update하도록 한다.

form 태그는 Get과 Post 메소드만 사용할 수 있다. Patch 사용하려고 method까지 다 만들어 놨는데 나중가서 생각남…..

PostController.java

@PostMapping("/post")
public String creatNewPost(@Valid @ModelAttribute("postDto") PostDto postDto) {
if(postDto.getId() == null) {
postService.addPost(postDto);
}else{
postService.revisePostDetails(postDto);
}

return "redirect:/";
}

수정요청에 대한 테스트 코드 작성

데이터 수정이 제대로 이루어진 경우 /로 redirection이 이루어진다. 결과값으로 상태코드가 302로 뜨는지 확인하도록 한다.

PostControllerTest.java

@Test
@DisplayName("포스트를 수정한다.")
public void creatOrUpdatePost() throws Exception {
PostDto postDto = PostDto.builder()
.id(1L)
.name("tester")
.title("test")
.content("test")
.build();

ResultActions resultActions = mockMvc.perform(post("/post")
.flashAttr("postDto", new PostDto())
.param("id", "1")
.param("name", "tester")
.param("title", "test")
.param("content", "test")
);

verify(postService).updatePost(postDto);

resultActions
.andExpect(status().is3xxRedirection())
.andDo(print())
;
}

데이터 수정을 위한 Service 로직

여기서는 DB조회시 PostNotExistedException 예외가 일어날 일이 없다. Control에서 id값의 유무를 통해 create와 update로 나누어 실행하기 때문이다.

PostService.java

@Transactional
public Post updatePost(PostDto postDto) {
Post oldPost = postRepository.findById(postDto.getId()).orElseThrow(() -> new PostNotExistedException(postDto.getId()));
oldPost.revise(postDto);
return oldPost;
}

데이터 수정에 대한 테스트 코드 작성

PostServiceTest.java

@Test
@DisplayName("포스트 데이터를 업데이트 한다.")
public void updatePost(){
PostDto postDto = PostDto.builder()
.id(1L)
.name("junit")
.title("junitTest")
.content("content")
.build();

Post mockPost = Post.builder()
.id(1L)
.name("tester")
.title("test")
.content("test")
.writeTime(LocalDateTime.now())
.build();

given(postRepository.findById(1L)).willReturn(Optional.of(mockPost));
Post post = postService.updatePost(postDto);
verify(postRepository).findById(1L);

assertThat(post.getName()).isEqualTo(postDto.getName());
assertThat(post.getTitle()).isEqualTo(postDto.getTitle());
assertThat(post.getContent()).isEqualTo(postDto.getContent());
}
Share