회원가입할 때 중복유저가 있는 경우에는 에러메세지를 띄워 사용자가 봤으면 좋겠다는 생각을 했다.
우선 chatGPT한테 html과 JS 코드를 작성해달라고 했다.
{{>layouts/header}}
<h2>회원가입</h2>
<form id="signup-form" >
<div class="mb-3">
<label class="form-label">userId</label>
<input type="text" class="form-control w-50" name="userId" placeholder="id">
</div>
<div class="mb-3">
<label class="form-label">userPassword</label>
<input type="text" class="form-control" name="password" placeholder="password">
</div>
<div class="mb-3">
<label class="form-label">nickName</label>
<input type="text" class="form-control" name="nickname" placeholder="nickName">
</div>
<button type="submit" class="btn btn-primary">save</button>
</form>
{{>layouts/footer}}
<script>
document.getElementById('signup-form').addEventListener('submit', function(event) {
event.preventDefault();
var formData = new FormData(event.target);
var userDto = {
userId: formData.get('userId'),
password: formData.get('password'),
nickname: formData.get('nickname')
};
fetch('/signUp', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(userDto)
})
.then(function(response) {
if (response.ok) {
alert('계정 생성 성공!');
window.location.href = '/'; // or wherever you want to redirect
} else {
return response.text().then(function(message) {
throw new Error(message);
});
}
})
.catch(function(error) {
alert(error.message); // "중복된 id입니다." 메시지를 표시합니다.
<!-- alert("중복된 회원입니다"); // "중복된 id입니다." 메시지를 표시합니다.-->
});
});
</script>
스크립트태그 안에서 fetch를 이용하여 post요청을 하도록 되어있다.
그럼 이제 컨트롤러에서 PostMapping해주면 되겠네. 하고 만들었는데?
@PostMapping("/signUp")
public String signUp(UserDto userDto){
userService.addUser(userDto);
return "redirect:/";
}
(대략 이렇게 작성함)
뭐가..데이터가 비어있어서 회원엔티티를 만들수 없다는 에러메세지가 자꾸 뜬 것이다.
잘 입력했는데 왜그러지? 스크립트태그가 잘못써졌나?
라고 생각했는데...
PostMapping하는 메소드에서 중요한걸 빼먹었다.
@PostMapping("/signUp")
public String signUp(@RequestBody UserDto userDto){
userService.addUser(userDto);
return "redirect:/";
}
저기 userDto 파라미터 앞에 @RequestBody 를 빼먹었던 것이다. 이걸 붙이니까 잘 작동했다.
근데 저게 꼭 있어야했던건가? 라는 생각도 들었다. 왜냐면 최근에 내가 작성했던 코드들은 저걸 안적었었어서...
왜 안적었었지? 왜 안적었는데 잘 됐었던거지? 하고 찾아봤다.
1. @RequestBody를 안 적어놔도 잘 됐었던 것은...
{{>layouts/header}}
<form action="/forum/{{article.id}}/edit" method="post">
<div class="mb-3">
<label class="form-label">nickname</label>
<input type="text" class="form-control w-25" name="nickname" placeholder="nickname" value="{{article.nickname}}" readonly>
</div>
<div class="mb-3">
<label class="form-label">title</label>
<input type="text" class="form-control" name="title" placeholder="title" value="{{article.title}}">
</div>
<div class="mb-3">
<label class="form-label">content</label>
<textarea class="form-control" name="content" rows="3" value="{{article.content}}"></textarea>
</div>
<button type="submit" class="btn btn-primary">save</button>
</form>
{{>layouts/footer}}
(DTO에는 nickname,title,content 속성이 있음)
이런 코드에서는 input들이 dto속성값과 일치하고, 폼데이터로 되어있어서 자동으로 DTO객체에 바인딩된다.
이 때는 @RequestBody가 없어도 되고, @ModelAttribute도 없어도 자동으로 됨.
근데,
2. @RequestBody가 필요한 경우
{{>layouts/header}}
<h2>회원가입</h2>
<form id="signup-form" >
<div class="mb-3">
<label class="form-label">userId</label>
<input type="text" class="form-control w-50" name="userId" placeholder="id">
</div>
<div class="mb-3">
<label class="form-label">userPassword</label>
<input type="text" class="form-control" name="password" placeholder="password">
</div>
<div class="mb-3">
<label class="form-label">nickName</label>
<input type="text" class="form-control" name="nickname" placeholder="nickName">
</div>
<button type="submit" class="btn btn-primary">save</button>
</form>
{{>layouts/footer}}
<script>
document.getElementById('signup-form').addEventListener('submit', function(event) {
event.preventDefault();
var formData = new FormData(event.target);
var userDto = {
userId: formData.get('userId'),
password: formData.get('password'),
nickname: formData.get('nickname')
};
fetch('/signUp', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(userDto)
})
.then(function(response) {
if (response.ok) {
alert('계정 생성 성공!');
window.location.href = '/'; // or wherever you want to redirect
} else {
return response.text().then(function(message) {
throw new Error(message);
});
}
})
.catch(function(error) {
alert(error.message); // "중복된 id입니다." 메시지를 표시합니다.
<!-- alert("중복된 회원입니다"); // "중복된 id입니다." 메시지를 표시합니다.-->
});
});
</script>
여기서는 <form>안에 뭐라뭐라 적혀있긴 하지만, 결국에 form데이터로 전송하지 않고 fetch를 이용하여 JSON객체를 보낸다. 이렇게 JSON데이터로 보낼 때는 @RequestBody 어노테이션을 부착해야 Dto로 바인딩 할 수 있다.
'웹개발 > SpringBoot' 카테고리의 다른 글
MySQL 설치 및 Spring 연동 방법 (0) | 2023.06.09 |
---|---|
로그인 여부에 따라 바뀌는 로그인/로그아웃 버튼 만들기 (0) | 2023.05.27 |
[JPA] 엔티티 수정시 Dirty checking(변경 감지), Merge(병합) (0) | 2023.05.07 |
JPA, Spring Data JPA (0) | 2023.03.21 |
의존성 주입(DI), 스프링 빈과 의존관계 (0) | 2023.03.19 |
댓글