< 20. 회원정보 수정 - Optinal 사용하기 >
서버단에서의 '유효성 검사'는 끝이났다
이제 남은것은 DB단에서의 문제를 해결하는 것이다.
앞 시간에 설명했던 Optional<T>의 3가지 옵션중에 orElseThrow()를 사용해서 Exception을 강제로 발동시킬것이다.
UserService로 가서 get()을 지우고 orElseThrow()를 넣어주도록 하자
package com.cos.photogramstart.handler;
import java.util.Map;
public class CustomValidationApiException extends RuntimeException{
//객체를 구분하기 위해 '시리얼넘버'를 넣어주는것
//JVM을 위해 걸어주는것이다
private static final long serialVersionUID = 1L;
private Map<String, String> errorMap;
public CustomValidationApiException(String message) { //String message만 입력해도 되는 메서드 새로 만들어줌
super(message);
}
public CustomValidationApiException(String message, Map<String, String> errorMap) {
super(message);
this.errorMap = errorMap;
}
public Map<String, String> getErrorMap() {
return errorMap;
}
}
-> 따라서 fail에 if문을 사용하여 message만 뿌릴 경우와, errorMap까지 뿌릴 경우를 분리해주어야 한다.
@RequiredArgsConstructor
@Service
public class UserService {
private final UserRepository userRepository;
private final BCryptPasswordEncoder bCryptPasswordEncoder;
@Transactional
public User 회원수정(int id, User user) {
//1.영속화
//User userEntity = userRepository.findById(id).get(); //1.무조건 찾았다 걱정마 get() 2. 못찾았어 Excetption 발동시킬게
// orElseThrow()
User userEntity = userRepository.findById(id).orElseThrow(() -> {
return new CustomValidationApiException("찾을 수 없는 아이디 입니다."); //생성자 새로 추가
});
//2.영속화된 오브젝트를 수정 - DirtyChecking (업데이트 완료)
String rawPassword = user.getPassword();
String encPassword = bCryptPasswordEncoder.encode(rawPassword); //password 암호화를 해주어야 한다
userEntity.setName(user.getName());
userEntity.setPassword(user.getPassword());
userEntity.setBio(user.getBio());
userEntity.setWebsite(user.getWebsite());
userEntity.setPhone(user.getPhone());
userEntity.setGender(user.getGender());
return userEntity; //DirtyChecking이 일어나서 업데이트가 완료경
}
}
//영속화된 Object를 수정하면 자동으로 DB에 반영이 된다
-> orElseThrow()의 안에 Supplier 타입을 담고 <>의 자리에 IllgalArgumentException을 담아주고 GET을 걸어주면 된다.
IllegalArgumentException은 findById()의 내부에 id값이 잘못되었을때 발동되는 Exception이다.
그리고 이 코드를 '람다식'으로 바꾸어서 조금 더 간결하게 수정해주자.
DB에 존재하지 않는 userId에 대한 '수정요청'이 들어왔을때, 서버가 터지면서
"java.lang.IllegalArgumentException : 찾을 수 없는 ID입니다" 의 오류가 출력된다.
이런 오류들도 '글로벌 예외처리'를 하는것이 좋다.
'글로벌 예외 처리'를 위해 내가 Custom한 Exception을 사용할 것인데, IllegalExeption대신 CustomValidationApiException을 걸어주면 에러가 뜬다.
그 이유는 바로 CustomValidationApiException에서 만든 '생성자'가 받는 매개변수가
String message, Map<String,Stirng> errorMap 두개 이기 때문이다.
우리가 응답할 에러는 "찾을 수 없는 ID입니다" 라는 String 하나이고, errorMap은 필요없다.
따라서 CustomValidationException에 StringMessage만 받는 '생성자'자를 하나 더 만들어준다.
package com.cos.photogramstart.handler;
import java.util.Map;
public class CustomValidationApiException extends RuntimeException{
//객체를 구분하기 위해 '시리얼넘버'를 넣어주는것
//JVM을 위해 걸어주는것이다
private static final long serialVersionUID = 1L;
private Map<String, String> errorMap;
public CustomValidationApiException(String message) { //String message만 입력해도 되는 메서드 새로 만들어줌
super(message);
}
public CustomValidationApiException(String message, Map<String, String> errorMap) {
super(message);
this.errorMap = errorMap;
}
public Map<String, String> getErrorMap() {
return errorMap;
}
}
-> UserService에 있던 에러가 사라진다.
이제 이 에러가 발생하여 CustomValidationApiException이 발생하게 되면, ControllerExceptionHandler가 에러를 낚아채서 ResponseEntity를 응답하게 되어있다.
당연하게도 HttpStatus 상태코드가 있기 때문에 AJAX는 fail코드가 실행되면서, StringMessage인 "찾을 수 없는 ID입니다"가 응답될 것이다.
// (1) 회원정보 수정
function update(userId, event) {
event.preventDefault(); //폼태그 액션을 더이상 진행되지 않게 막기
let data = $("#profileUpdate").serialize();
console.log(data);
$.ajax({
type:"put",
url :`/api/user/${userId}`,
data : data,
contentType:"application/x-www-form-urlencoded; charset=utf-8",
dataType:"json"
}).done(res => { //HttpStatus 상태코드 200번대 일때
console.log("update 성공", res);
location.href = `/user/${userId}`;
}).fail(error => { //HttpStatus 상태코드 200번대가 아닐때, fail이 실행된다
if (error.data == null) {
alert(error.responseJSON.message); //message만 응답
} else {
alert("회원정보 수정에 실패하였습니다. 원인 : " + JSON.stringify(error.responseJSON.data)); //errorMap이 포함된 응답
}
});
}
-> 다시 테스트해보면 정상적으로 '에러메세지'가 응답된다.
이로써 DB단에서의 문제점도 해결됨으로써 '회원가입, 로그인, 회원정보수정'의 기능이 모두 끝이났다.
'메타코딩 SNS프로젝트' 카테고리의 다른 글
22. 구독하기 - 모델만들기 (0) | 2022.06.20 |
---|---|
21. 구독하기 - 연관관계 개념잡기 (0) | 2022.06.20 |
6월 16일 17일 오류 일지 (0) | 2022.06.18 |
인스타그램 클론코딩 Chapter 3. 포토그램 인증 - 회원정보 수정 (0) | 2022.06.16 |
인스타그램 클론코딩 Chapter 3. 포토그램 인증 - 3 로그인 (0) | 2022.06.15 |