Delete 기능을 추가하는 실습이다.
● article의 상세페이지를 보여주는 뷰페이지에 Delete 버튼을 추가한다. 예를들면↓
상세페이지의 Delete버튼을 누르면 href="~~" 링크로 연결된다.
<a href="/articles/{{article.id}}/delete" class="btn btn-danger">Delete</a>
● 이제 그 (링크)url요청에 대한 매핑을 컨트롤러 안에 만들어주어야겠다.
public class ArticleController {
...
// 원래 DeleteMapping을 쓰지만, html의 form태그는 get과 post만 지원한다
// 그래서 일단 get방식을 통해 delete 기능을 구현할 수밖에 없었다
@GetMapping("/articles/{id}/delete")
public String delete(@PathVariable Long id,
RedirectAttributes rttr) {
// 아래처럼 해도 되고, Repository에 곧바로 deleteById() 해도 좋다
Article target = articleRepository.findById(id).orElse(null);
if (target != null) {
articleRepository.delete(target);
rttr.addFlashAttribute("msg", "삭제가 완료되었습니다.");
}
// 결과 페이지로 리다이렉트
return "redirect:/articles";
}
}
∨ 스프링이 제공하는 RedirectArributes 클래스 (Model을 확장한 클래스)
: RedirectAttributes 클래스의 메서드 중 addFlashAttribute()를 사용해봤다.
삭제 후 리다이렉트해서 article목록 보여줄 때, "삭제 완료 메세지"를 일시적으로 보여주기 위해서 사용한 클래스다.
∨ redirect시 Model을 넘기기 vs RedirectAttributes.addFlashAttribute로 넘기기
: 전자는 url에 다 노출이 되고(: get방식) 후자는 노출이 되지 않는다.
아직 Model을 넘기는 redirect는 실습을 안 해봤지만 이론만 간단히 정리해두겠다.
검색해보니까 많은 사람들이 "Model로 넘기는 경우와 RedirectAttributes를 사용하는 두 경우"를 비교해 학습한다.
∨ Model을 넘기는 redirect
- methodA가 methodB로 addAttribute()된 Model을 보내게 된다.
- Model의 값은 methodB에 @RequestParam 파라미터를 통해 전달된다. 이렇게 전달된 파라미터를 다시 methodB에서 model에 addAttribute()해준다.
- 그리고 methodB가 view에 Model을 전달하게 될텐데, GET방식으로 전달하기 때문에 URL에 나타난다.
(그 url에 물음표 뒤에 쭈루룩 정보가 떠버리는게.. 이거다)
∨ 반면 rttr.addFlashAttribute("msg", "success")으로 전달할 경우
- 세션을 통해 전달하는 거라서 url에 노출되지 않고 전달한다.
- methodA에서 methodB로 RedirectAttributes.addFlashAttribute를 통해 설정된 값을 보낼 때,
- methodB에서는 매핑이나 또다시 addAttribute 할 필요 없이 그냥 바로 사용가능하다.
- 왜? : 세션을 사용해 전달하기 때문이다.
- addFlashAttribute로 전달하는 값은 1회용이라 리다이렉트 후 사라진다.
● 헤더에 삭제완료되었다는 임시 메세지를 출력하도록 html을 수정하자.
그러기 위해 /layouts/header.mustache에 {{#msg}} 변수를 사용해 메세지창을 띄워 줄 것이다.
recall. 컨트롤러의 삭제전용 메서드에서 RedirectAttributes에 addFlashAttribute("msg", "~~~") 했었음
cf. Bootstrap에 Alert 찾아서 쓰기
<!-- alert msg -->
{{#msg}}
<div class="alert alert-primary alert-dismissible">
{{msg}}
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
</div>
{{/msg}}
'web +a' 카테고리의 다른 글
스프링부트 ~18 | REST API와 JSON (0) | 2022.07.21 |
---|---|
스프링부트 ~17 | SQL 쿼리 로깅 & CRUD 쿼리 실습 (0) | 2022.07.20 |
스프링부트 ~15 | Update (0) | 2022.07.20 |
스프링부트 ~13 | 링크와 리다이렉트 (0) | 2022.07.20 |
스프링부트 ~12 | DB속 모든 Entity findAll하기 (0) | 2022.07.19 |