코딩 자율학습단/학습 일지

[DAY 7] 게시판 CRUD : Update - form 태그에서 PATCH 메서드 이용하는 방법 / Lombok 인식 에러 고치기

young604 2024. 8. 7. 02:07
728x90

흐름

데이터 수정 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

 

[TIP] SpringBoot Intellij lombok 인식이 안될때

컴퓨터를 포멧하는 일이 있어 다시 인텔리제이를 설치하고 나서 토이프로젝트 하다가 위와 같은 Lombok을 인식 못하는 이슈가 발생했다. 그래서 이런 이슈에 대해 기록해 두고자 한다. Intellij --> p

fe-churi.tistory.com


책에서 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가 있다는 것이 이치에 맞지 않다고 반박하였고, 그대로 이슈가 닫혀 여전히 지원하지 않고 있다고 한다...

자세한 내용 참고 : https://softwareengineering.stackexchange.com/questions/114156/why-are-there-no-put-and-delete-methods-on-html-forms

 

Why are there no PUT and DELETE methods on HTML forms?

HTML4 / XHTML1 allows only GET and POST in forms, now it seems like HTML5 will do the same. There is a proposal to add these two but it doesn't seem to be gaining traction. What were the technical or

softwareengineering.stackexchange.com

 

728x90