728x90
회원가입에 필요한 DTO와 Layered Architecture 방식에 맞는 설계를 진행하겠습니다.
DTO
JoinRequest 만들기
@AllArgsConstructor
@NoArgsConstructor
@Getter
public class UserJoinRequest {
private String userName;
private String password;
public User toEntity(String password) {
return User.builder()
.userName(this.userName)
.password(password)
.userRole(USER)
.build();
}
}
Request 정보를 Entity로 만들어서 DB에 저장해야하므로 toEntity() 메서드를 작성하였습니다.
매개변수로 String password가 들어있는데, 암호화된 비밀번호를 다시 입력해야하므로 추가했습니다.
JoinResponse 만들기
@AllArgsConstructor
@NoArgsConstructor
@Getter
public class UserJoinResponse {
private Integer userId;
private String userName;
}
Custom Response 제작
Controller
@RequestMapping("/api/v1/users")
@RestController
@RequiredArgsConstructor
public class UserController {
private final UserService userService;
@PostMapping("/join")
public Response<UserJoinResponse> join(@RequestBody UserJoinRequest dto){
UserDto user = userService.join(dto);
return Response.success(new UserJoinResponse(user.getId(), user.getUserName()));
}
}
UserJoinResponse타입의 Custom한 Response를 반환하도록 설계하였습니다.
요구사항에서 요구 했던 데이터에 id,와 userName이 존재해서 JoinResponse를 생성하여 따로 반환하였습니다.
UserDto를 반환하게 될 경우, 사용자의 비밀번호 등 원치 않은 중요한 정보들이 유출될 가능성이 있기 때문에 따로 ResponseDto를 제작했습니다.
Service
@Service
@RequiredArgsConstructor
public class UserService {
private final UserRepository userRepository;
private final BCryptPasswordEncoder encoder;
public UserDto join(UserJoinRequest dto) {
userRepository.findByUserName(dto.getUserName())
.ifPresent(user->{
throw new SNSAppException(ErrorCode.DUPLICATED_USER_NAME, String.format("userName = %s", dto.getUserName()));
});
User savedUser = userRepository.save(dto.toEntity(encoder.encode(dto.getPassword())));
return UserDto.builder()
.id(savedUser.getId())
.userName(savedUser.getUserName())
.password(savedUser.getPassword())
.userRole(savedUser.getUserRole())
.build();
}
}
비밀번호 암호화를 위한 BCryptPasswordEncoder를 추가하였습니다.
먼저 같은 userName을 가지고 있는 사용자가 있는지 확인하고, 같은 userName이 발견될 시에는 예외를 던져주었습니다.
같은 userName을 가지고 있는 유저가 없다면 User Entity에 dto의 정보를 toEntity화 하여 저장하고 해당 정보를 받습니다.
저장된 유저의 정보를 다시 UserDto로 변경하여 Controller로 반환합니다.
Repository
public interface UserRepository extends JpaRepository<User, Integer> {
Optional<User> findByUserName(String userName);
}
Optional를 반환하는 유저 이름으로 유저를 찾아주는 findByUserName(StringName)을 만들었습니다.
결과
같은 userName이 존재할 때
반응형
'프로젝트 > Archive' 카테고리의 다른 글
[02] 로그인 기능 만들기 - 1 (1) | 2022.12.21 |
---|---|
[02] 로그인 기능 만들기 - 0 (0) | 2022.12.21 |
[01] 회원가입 기능 만들기 - 0 (1) | 2022.12.21 |
[스프링 부트 쇼핑몰 프로젝트 with jpa] Thymeleaf 소개 (0) | 2022.10.06 |
[스프링 부트 쇼핑몰 프로젝트 with jpa] Spring DATA JPA Querydsl (0) | 2022.10.04 |