흐름
데이터 수정 1단계 : 수정 페이지를 만들고 기존 데이터 불러오기
1. 수정 페이지 요청 (상세 페이지에 edit 버튼 추가, ArticleController에 edit() 메서드 추가, url : /articles/{id}/edit)
2. DB에서 데이터를 찾아 서버로 전송(articleRepository의 findById(id) 메서드 이용)
3. 가져온 데이터를 모델에 등록
4. 뷰 페이지 출력 (edit.mustache 추가)
데이터 수정 2단계 : 데이터를 수정해 DB에 반영한 후 결과를 볼 수 있게 상세 페이지로 리다이렉트
1. 폼 데이터 전달 (form 태그는 patch 사용 불가, post로 하되 id값을 넘겨야하므로 input에 hidden 설정으로 value="{{id}}" 추가)
2. DTO를 엔티티로 변환 (ArticleController에 update() 메서드 추가, 매개변수로 DTO 추가, 데이터를 넘겨줄때 id값을 넘기므로 DTO에 id 필드 추가 및 생성자 null -> id로 변경 / toEntity() 로 DTO 엔티티로 변환)
3. DB 갱신 (ArticleRepository.findById(articleEntity.getId()) DB에서 데이터 찾은 후 save() 메서드를 호출, 데이터 갱신)
4. 리다이렉트 (update() 에서 수정 결과를 상세 페이지로 리다이렉트 하도록 url 수정)
Trouble Shooting
1. 스프링 자체 에러 문제
문제상황
ARN 27428 --- [nio-8090-exec-8] ocalVariableTableParameterNameDiscoverer : Using deprecated '-debug' fallback for parameter name resolution. Compile the affected code with '-parameters' instead or avoid its introspection: com.example.firstproject.dto.ArticleForm
해결 방법
스프링 자체 에러, 6.0.3 버전에서 수정됨. application.properties에 다음 설정 추가
logging.level.org.springframework.core.LocalVariableTableParameterNameDiscoverer = error
오류 뜨지않음!
2. @Getter 인식 문제
문제상황
getId() 메서드를 사용하려면 엔티티에 직접 게터 메서드를 작성하거나 롬복의 어노테이션 @getter를 이용하면 됨
근데 롬복의 게터 인포트하고 어노테이션 적용해도 메서드를 사용할 수 없다고 뜸 (근데 실행은 잘 됨 왜지?)
해결 방법
1. settings > complier > Annotation Processors 에서 Enable annotation processing 선택
2. settings > Plugins 에서 lombok 검색 후 intall
3. File > Invalidate Caches 에서 invalidate and Restart
빨간 줄 안 뜨고 해결 잘 됨!
참고 : https://fe-churi.tistory.com/57
책에서 form 태그는 patch 메서드를 제공하지 않아서 post 메서드를 이용하고, id값은 hidden 속성을 이용한 input 태그로 서버에 넘겨줬다. 이 방법 말고 다른 방법은 없을까 해서 찾아보니 2가지 방법이 있었다.
1. HiddenHttpMethodFilter 이용
<form action="/.." method="POST">
<input type="hidden" name="_method value="PATCH">
post 방식이지만 '_method'를 이용하여 overloaded post하는 방법이다.
bean으로 등록하거나 application.properties에 HiddenHttpMethodFilter을 추가하여 사용한다.
이를 사용하면 form 태그에 input 히든 태그로 다른 method 요청을 구현할 수 있다.
위와 같이 설정하면 spring boot의 컨트롤러에서 @PatchMapping 어노테이션을 사용할 수 있으며, html form에서 hidden input으로 전달된 '_method' 값을 읽어 실제 http 메서드를 변경하여 준다.
단점
1. 보안 문제 : 클라이언트 측에서 HTTP 메서드를 변경할 여지가 있고, CSRF 공격에 취약할 수 있다.
2. RESTful 원칙 위반 가능성 : RESTful API 설계 규칙에 따르면 각각의 HTTP 메서드는 고유한 의미를 가지게 되는데 HiddenHttpMethodFilter를 이용하면 POST 요청을 보내면서 다른 메서드로 동작하기 때문에 원칙을 위반할 수 있다.
클라이언트-서버 간 일관성 문제나 프록시 서버와의 호환성 문제 등이 있기에 이러한 간단한 코딩에서 사용하고 복잡한 프로젝트에서는 프론트 백엔드를 나누어 개발하기때문에 쓰이지 않을 것 같다.
2. AJAX 사용
<form id="myForm">
<input type="text" name="data" value="example">
<button type="button" onclick="submitForm()">Update</button>
</form>
<script>
function submitForm() {
const form = document.getElementById('myForm');
const data = new FormData(form);
fetch('/update', {
method: 'PATCH',
body: data
}).then(response => response.json())
.then(data => {
console.log(data);
}).catch(error => {
console.error('Error:', error);
});
}
</script>
form에 따로 메서드를 설정하지 않고 java script를 이용하여 AJAX 요청을 보낸다.
왜 form 태그는 GET과 POST만 지원할까?
2010년도에 누군가가 이에 관해서 PUT/DELETE 미지원에 관련하여 이슈와 PR을 등록하였고, HTML5에 이에 관하여 추가 지원이 될 예정이었으나 메인테이너가 이 이슈에 대해 PUT/DELETE는 Payload가 있다는 것이 이치에 맞지 않다고 반박하였고, 그대로 이슈가 닫혀 여전히 지원하지 않고 있다고 한다...
'코딩 자율학습단 > 학습 일지' 카테고리의 다른 글
[DAY 9] CRUD와 SQL 쿼리 (0) | 2024.08.08 |
---|---|
[DAY 8] 게시판 CRUD : Delete (0) | 2024.08.08 |
[DAY 6] 페이지 연결 - 링크와 리다이렉트 (0) | 2024.08.05 |
[DAY 5] 게시판 CRUD : Read (0) | 2024.08.02 |
[DAY 4] DB 조회와 롬복을 통한 리팩터링 (0) | 2024.08.01 |