application/json
에서multipart/formdata
타입으로 변경FormData
객체에 데이터를 담아서 서버에 요청클라이언트 요청 부분
const formData = new FormData();
formData.append('memberId', memberId);
formData.append('thumbnail', 'thumbnail');
formData.append('description', description);
formData.append('title', title);
formData.append('content', content);
formData.append('tags', tags);
fetch("/post/write", {
method: 'POST',
body: formData
})
.then((response) => response.text())
.then((data) => {
window.location.href = '/post/' + data;
})
.catch((error) => {
console.error('실패', error);
});
DTO 부분
@NoArgsConstructor
@Getter
public class PostRequestDto {
private String thumbnail;
private String description;
private String title;
private String content;
private String tags;
@Builder
public PostRequestDto(String thumbnail, String description, String title, String content, String tags) {
this.thumbnail = thumbnail;
this.description = description.trim();
this.title = title.trim();
this.content = content.trim();
this.tags = !tags.isBlank() ? PostUtils.tagParsing(tags) : "";
}
public Post toPost(Member member) {
return Post.builder()
.member(member)
.thumbnail(this.thumbnail)
.description(this.description)
.title(this.title)
.content(this.content)
.build();
}
public List<Tag> getTagList() {
if (!tags.isBlank()) {
return Stream.of(this.tags.split("#"))
.filter(s -> s.length() > 0)
.map(s -> Tag.builder().tagName(s.toLowerCase()).build())
.collect(Collectors.toList());
} else {
return new ArrayList<>();
}
}
}
클라이언트에서 Content-Type
헤더에 직접적으로 타입을 명시하여 요청
@RequestParam
으로 각 파라미터를 직접 받아보기
이후에, @ModelAttribute
의 데이터 바인딩에 대해서 검색했다.
깊은 코드 레벨까지 이해하기는 어려워서 핵심만 정리
전제 조건
- public 생성자만 여러 개 작성하거나 그 외 생성자만 여러 개 작성하는 경우에는 디폴트 생성자를 작성해야 한다.
디폴트 생성자를 찾을 수 없다는 에러가 발생함 (이유는 아직 파악 못함)
가장 먼저 public 이면서 인자 수가 가장 적은 생성자를 찾는다.
1번의 조건에 맞는 생성자를 통해서 새 인스턴스를 생성한다.
setter 메서드를 통해서 클라이언트에게 받은 파라미터를 각각의 필드에 값을 넣어준다.
문제의 원인은 @NoArgsConstructor
때문이었다.
엔티티를 작성할 때 @NoArgsConstructor
를 작성하는 것이 습관이 되어버린 탓에 DTO
에도 남발한 것이 문제였다.
Lombok을 너무 남용하지 말자...
이것 때문에 하루를 날렸는데 감사합니다...