์ง๋์๊ฐ ๊น์ง entity, DTO, Repository ๋ฅผ ๋ง๋ค์ด ๋ณด์๋ค.
์ค๋์ ํ์ Serivce ํจํค์ง๋ฅผ ์์ฑํ์ฌ UserService ํด๋์ค๋ฅผ ๋ง๋ค์ด ๋ณด๊ฒ ๋ค.
๋จผ์ ์๋น์ค! ์ ๋ํด ๊ฐ๋จํ๊ฒ ๊ฐ๋ ? ์ ๋ฆฌ ํ๊ณ ๊ฐ๊ฒ ๋ค.
Service ๋?
์ Service๋ฅผ ์ดํดํ๊ธฐ ์ํด ํฐ ํ์ ๋ณด๊ฒ ์ต๋๋ค.
- Client๊ฐ Request๋ฅผ ๋ณด๋ธ๋ค.(Ajax, Axios, fetch๋ฑ..)
- Request URL์ ์๋ง์ Controller๊ฐ ์์ ๋ฐ๋๋ค. (@Controller , @RestController)
- Controller ๋ ๋์ด์จ ์์ฒญ์ ์ฒ๋ฆฌํ๊ธฐ ์ํด Service ๋ฅผ ํธ์ถํ๋ค.
- Service๋ ์๋ง์ ์ ๋ณด๋ฅผ ๊ฐ๊ณตํ์ฌ Controller์๊ฒ ๋ฐ์ดํฐ๋ฅผ ๋๊ธด๋ค.
- Controller ๋ Service ์ ๊ฒฐ๊ณผ๋ฌผ์ Client ์๊ฒ ์ ๋ฌํด์ค๋ค.
Service๊ฐ ์๋ง์ ์ ๋ณด๋ฅผ ๊ฐ๊ณตํ๋ ๊ณผ์ ์ '๋น์ฆ๋์ค ๋ก์ง์ ์ํํ๋ค.' ๋ผ๊ณ ํฉ๋๋ค.
Service๊ฐ ๋น์ฆ๋์ค ๋ก์ง์ ์ํํ๊ณ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ ๊ทผํ๋ DAO๋ฅผ ์ด์ฉํด์ ๊ฒฐ๊ณผ๊ฐ์ ๋ฐ์ ์ต๋๋ค.
์ด๊ฒ ๋ฌด์จ๋ง์ด๋๋ฉด
์ฐ๋ฆฌ๊ฐ ์ฃผ์์ฐฝ์ http://www.naver.com ์ ์ ๋ ฅํ๋ฉด ๋ค์ด๋ฒ ํํ์ด์ง๋ก ์ ์ํ๊ฒ ๋๋ค.
๊ทธ๋ฆฌ๊ณ ๋ก๊ทธ์ธ์ ํ๊ธฐ์ํด์๋ ํด๋น ์ฃผ์ ๋ค์ /login ์ ๋ถ์ฌ์ผ ํ๋ค๊ณ ๊ฐ์ ํ์.
๊ทธ๋ ๋ค๋ฉด http://www.naver.com/login ์ ์ ์ํ๋ฉด ๋ก๊ทธ์ธ ํ์ด์ง๋ก ์ด๋ํ ๊ฒ์ด๋ค.
์ ๊ณผ์ ์์ client ์ฆ, ์ฐ๋ฆฌ๊ฐ ์ฃผ์์ฐฝ์ ํด๋น url์ ๋ฃ์ด์ ์ํฐํค๋ฅผ ๋ฑ ๋๋ฅด๋ ์๊ฐ
1 ๋ฒ ๋ถํฐ ์ฐจ๋ก๋๋ก 5๋ฒ๊น์ง ์คํ๋๋ค๊ณ ๋ณด๋ฉด ๋๋ค.
์ฆ, ํด๋น ์๋น์ค์ ๋ํด์๋ service ํจํค์ง์์ ๋ด๋นํ๋ค.
๋ก๊ทธ์ธ ๊ธฐ๋ฅ์ ํต์ฌ ๋ก์ง์ ์๋น์ค์ ์๋ค๊ณ ๋ณด๋ฉด ๋๋ค.
๊ทธ๋ฆฌ๊ณ ์๋น์ค๋ ํด๋น ๊ธฐ๋ฅ! ๊ทธ๋ฌ๋๊น ๋ก๊ทธ์ธ์ผ๋ก ๊ฐ์ ํ๋ฉด ๋ก๊ทธ์ธ ํต์ฌ๊ธฐ๋ฅ์ ๋ง๋ค๊ธฐ ์ํด์๋ DB์ ์๋ ๋ฐ์ดํฐ๋ค์ ์ด์ฉํด์ผ ๋๋ค. ๊ทธ๋ ๊ธฐ ๋๋ฌธ์ ํ์๋ ํฌ์งํ ๋ฆฌ(UserRepository) ๋ฅผ ๊ฐ์ ธ์์ ์๋น์ค ๋ก์ง์ ์ง ๋ค.
๋๋ต์ ์ธ ์๋น์ค ํ๋ฆ? ์ดํด๋ฅผ ํ๋ฐ๋ฉด ์ด์ ์ฝ๋๋ฅผ ๋ณด์!
UserService ์ ์ฒด ์ฝ๋
package com.example.projectpicker.user.service;
import com.example.projectpicker.security.TokenProvider;
import com.example.projectpicker.user.dto.LoginResponseDTO;
import com.example.projectpicker.user.dto.UserSignUpDTO;
import com.example.projectpicker.user.dto.UserSignUpResponseDTO;
import com.example.projectpicker.user.entity.UserEntity;
import com.example.projectpicker.user.exception.DuplicatedEmailException;
import com.example.projectpicker.user.exception.NoRegisteredArgumentsException;
import com.example.projectpicker.user.repository.UserRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
@Service
@Slf4j
@RequiredArgsConstructor
public class UserService {
private final UserRepository userRepository;
private final PasswordEncoder passwordEncoder;
private final TokenProvider tokenProvider;
// ํ์๊ฐ์
์ฒ๋ฆฌ PART
public UserSignUpResponseDTO create(final UserSignUpDTO userSignUpDTO){ //final ํค์๋: ํด๋์ค๋ ๋ณ์์ final์ ๋ถ์ด๋ฉด ์ฒ์ ์ ์๋ ์ํ๊ฐ ๋ณํ์ง ์๋ ๊ฒ์ ๋ณด์ฅํ๋ค๋ ์๋ฏธ
// ๊ฐ์
์ ๋ณด๊ฐ null ์ผ๋
if(userSignUpDTO == null){
throw new NoRegisteredArgumentsException("๊ฐ์
์ ๋ณด๊ฐ ์์ต๋๋ค.");
}
final String email = userSignUpDTO.getEmail(); // ํด๋ผ์ด์ธํธ๊ฐ ๋ณด๋ธ ๋ฐ์ดํฐ(์ด๋ฉ์ผ)
// ์ด๋ฏธ ์กด์ฌํ๋ ์ด๋ฉ์ผ์ธ ๊ฒฝ์ฐ
if(userRepository.existsByUserEmail(email)){
log.warn("์ด๋ฏธ ์กด์ฌํ๋ ์ด๋ฉ์ผ ์
๋๋ค. - {}",email);
throw new DuplicatedEmailException("์ด๋ฏธ ์กด์ฌํ๋ ์ด๋ฉ์ผ์
๋๋ค.");
}
//ํจ์ค์๋ ์ธ์ฝ๋ฉ (์ํธํ์ฒ๋ฆฌ)
String rawPassword = userSignUpDTO.getPassword(); // ํ๋ฌธ ๋น๋ฐ๋ฒํธ
String encodedPassword = passwordEncoder.encode(rawPassword); //passwordEncoder ์ธ๋ถ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ด์ฉํด ๋น๋ฐ๋ฒํธ ์ํธํ ์ฒ๋ฆฌ
userSignUpDTO.setPassword(encodedPassword); // ์ํธํ๋ ๋น๋ฐ๋ฒํธ๋ก ์ค์ !
UserEntity savedUser = userRepository.save(userSignUpDTO.toEntity()); // ์ ๊ณผ์ ์ ์ ์ฅ!
log.info("ํ์ ๊ฐ์
์ฑ๊ณต!! - user_id: {} ", savedUser.getUserId());
return new UserSignUpResponseDTO(savedUser); // ํด๋ผ์ด์ธํธ์๊ฒ ์๋ต๊ฒฐ๊ณผ์๋ savedUSer(์ํธ์ฒ๋ฆฌ๋) ์ ๋ณด ๋ฐํ
}
//์ด๋ฉ์ผ ์ค๋ณตํ์ธ
public boolean isDuplicate(String email){
if (email == null){
throw new RuntimeException("์ด๋ฉ์ผ ๊ฐ์ด ์์ต๋๋ค.");
}
return userRepository.existsByUserEmail(email);
}
// ๋ก๊ทธ์ธ ๊ฒ์ฆ(์ด๋ฉ์ผ,๋น๋ฐ๋ฒํธ) PART
public LoginResponseDTO getByCredentials(final String email, final String rawPassword){
// ์
๋ ฅํ ์ด๋ฉ์ผ์ ํตํด ํ์์ ๋ณด ์กฐํ
UserEntity originalUser = userRepository.findByUserEmail(email); // ์ด๋ฉ์ผ๋ก ์กฐํ๋ ํ์์ originUser ์ ๋ด์.
// email ์กฐํ๋ ํ์์ด null ์ผ๋(์์ ๋)
if(originalUser == null) {
throw new RuntimeException("๊ฐ์
๋ ํ์์ด ์๋๋๋ค.");
}
// ๋น๋ฐ๋ฒํธ ๊ฒ์ฆ
if(!passwordEncoder.matches(rawPassword,originalUser.getUserPassword())){
throw new RuntimeException("๋น๋ฐ๋ฒํธ๊ฐ ํ๋ ธ์ต๋๋ค.");
}
//๋ก๊ทธ์ธ ์ฑ๊ณต์ ๋ก๊ทธ ์ถ๋ ฅ
log.info("{}๋ ๋ก๊ทธ์ธ ์ฑ๊ณต",originalUser.getUserName());
// ํ ํฐ ๋ฐ๊ธ
String token = tokenProvider.createToken(originalUser);
return new LoginResponseDTO(originalUser, token);
}
}
/**
* Service๋ฅผ ์ดํดํ๊ธฐ ์ํด ํฐ ํ
*
* 1. Client๊ฐ Request๋ฅผ ๋ณด๋ธ๋ค.(Ajax, Axios, fetch๋ฑ..)
* 2. Request URL์ ์๋ง์ Controller๊ฐ ์์ ๋ฐ๋๋ค. (@Controller , @RestController)
* 3. Controller ๋ ๋์ด์จ ์์ฒญ์ ์ฒ๋ฆฌํ๊ธฐ ์ํด Service ๋ฅผ ํธ์ถํ๋ค.
* 4. Service๋ ์๋ง์ ์ ๋ณด๋ฅผ ๊ฐ๊ณตํ์ฌ Controller์๊ฒ ๋ฐ์ดํฐ๋ฅผ ๋๊ธด๋ค.
* 5. Controller ๋ Service ์ ๊ฒฐ๊ณผ๋ฌผ์ Client ์๊ฒ ์ ๋ฌํด์ค๋ค.
*
* ์ ๋ฆฌ
* Service๊ฐ ์๋ง์ ์ ๋ณด๋ฅผ ๊ฐ๊ณตํ๋ ๊ณผ์ ์ '๋น์ฆ๋์ค ๋ก์ง์ ์ํํ๋ค.' ๋ผ๊ณ ํฉ๋๋ค.
* Service๊ฐ ๋น์ฆ๋์ค ๋ก์ง์ ์ํํ๊ณ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ ๊ทผํ๋ DAO๋ฅผ ์ด์ฉํด์ ๊ฒฐ๊ณผ๊ฐ์ ๋ฐ์ ์ต๋๋ค.
*/
๋จผ์ ์๋จ์ ์์นํด ์๋ ์๋ ์ฝ๋๋ค์ ์๊น ์งง์ ๋งํ?์์ ๋์์๋๋ฐ
์๋น์ค๋ก์ง์ ๊ตฌํํ๊ธฐ์ํด์ db์ ๋ฐ์ดํฐ๋ค์ด ํ์ํ๋ค. ๋งค์ฐ ๋น์ฐํ ์ด์ผ๊ธด๋ฐ ๋ด๊ฐ ๋ก๊ทธ์ธ์ ํ๊ธฐ์ํด์
db์ ๋ด๊ฒจ์๋ ๋๋ฅผ ์ธ์ฆํ ์ ์๋? ๊ทธ๋ฐ ๋ฐ์ดํฐ๋ค๊ณผ ์ผ์น ํ์ง ํ์ธํด์ผ ๋๋ค.
๊ทธ๋ ๊ธฐ ๋๋ฌธ์ db (entity)๋ฅผ ๋ฐ๋ก ์ฐธ์กฐํ๋๊ฑด ๋ฌด๋ฆฌ๊ณ , ๋ ํฌ์งํ ๋ฆฌ๋ฅผ ์ด์ฉํด์ db ๊ฐ์ ์ฐธ์กฐํ๋ค.
๊ทธ๋์ ์๋ ์ฝ๋๋ฅผ ์ด์ฉํด ์๋น์ค ๊ตฌํ์ ์์ด ํ์ํ ํ์ผ (ํด๋์ค)๋ค์ ๋ถ๋ฅธ๋ค!
private final UserRepository userRepository;
private final PasswordEncoder passwordEncoder;
private final TokenProvider tokenProvider;
// ํ์๊ฐ์
์ฒ๋ฆฌ PART
public UserSignUpResponseDTO create(final UserSignUpDTO userSignUpDTO){ //final ํค์๋: ํด๋์ค๋ ๋ณ์์ final์ ๋ถ์ด๋ฉด ์ฒ์ ์ ์๋ ์ํ๊ฐ ๋ณํ์ง ์๋ ๊ฒ์ ๋ณด์ฅํ๋ค๋ ์๋ฏธ
// ๊ฐ์
์ ๋ณด๊ฐ null ์ผ๋
if(userSignUpDTO == null){
throw new NoRegisteredArgumentsException("๊ฐ์
์ ๋ณด๊ฐ ์์ต๋๋ค.");
}
final String email = userSignUpDTO.getEmail(); // ํด๋ผ์ด์ธํธ๊ฐ ๋ณด๋ธ ๋ฐ์ดํฐ(์ด๋ฉ์ผ)
// ์ด๋ฏธ ์กด์ฌํ๋ ์ด๋ฉ์ผ์ธ ๊ฒฝ์ฐ
if(userRepository.existsByUserEmail(email)){
log.warn("์ด๋ฏธ ์กด์ฌํ๋ ์ด๋ฉ์ผ ์
๋๋ค. - {}",email);
throw new DuplicatedEmailException("์ด๋ฏธ ์กด์ฌํ๋ ์ด๋ฉ์ผ์
๋๋ค.");
}
//ํจ์ค์๋ ์ธ์ฝ๋ฉ (์ํธํ์ฒ๋ฆฌ)
String rawPassword = userSignUpDTO.getPassword(); // ํ๋ฌธ ๋น๋ฐ๋ฒํธ
String encodedPassword = passwordEncoder.encode(rawPassword); //passwordEncoder ์ธ๋ถ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ด์ฉํด ๋น๋ฐ๋ฒํธ ์ํธํ ์ฒ๋ฆฌ
userSignUpDTO.setPassword(encodedPassword); // ์ํธํ๋ ๋น๋ฐ๋ฒํธ๋ก ์ค์ !
UserEntity savedUser = userRepository.save(userSignUpDTO.toEntity()); // ์ ๊ณผ์ ์ ์ ์ฅ!
log.info("ํ์ ๊ฐ์
์ฑ๊ณต!! - user_id: {} ", savedUser.getUserId());
return new UserSignUpResponseDTO(savedUser); // ํด๋ผ์ด์ธํธ์๊ฒ ์๋ต๊ฒฐ๊ณผ์๋ savedUSer(์ํธ์ฒ๋ฆฌ๋) ์ ๋ณด ๋ฐํ
}