have a good time 2021. 12. 6. 22:03

<signup.jsp> 파일

                        <form class="login__input"  action="/auth/signup" method="post">
                            <input type="text" name="username" placeholder="유저네임" required="required"  />
                            <input type="password" name="password" placeholder="패스워드"  required="required" />
                            <input type="email" name="email" placeholder="이메일" required="required" />
                            <input type="text" name="name" placeholder="이름" required="required"/>
                            <button>가입</button>
                        </form>

 

이러면 웹 사이트상에 

 

 

이렇게 회원가입 화면이 나온다.

 

그래서 사용자가 유저네임, 패스워드, 이메일, 이름을 입력하고

가입 버튼을 누르면

 

<SignupDto.java> 파일

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;
import lombok.Data;

@Data
public class SignupDto {

	@Size(min = 2, max = 20)
	@NotBlank
	private String username;
	@NotBlank
	private String password;
	@NotBlank
	private String email;
	@NotBlank
	private String name;

SignupDto.java 파일에서 사용자가 입력한 값들(username, password, email, name) 을 받는다.

 

 

스프링은

form 으로 데이터가 들어오면 (jsp 파일에서 form 태그)

(x-www-form-urlencoded 방식) 즉, key = value 형식으로 들어옴

 

 

 

 

(@Size, @NotBlank 는 값 입력시 글자 크기가 최소 2 ~20 사이, 빈칸이 입력되지 않도록 유효성 검사를 한 것으로,

 

https://happy-fun.tistory.com/152

 

회원가입 유효성 검사

회원가입 시 username password email name 값을 받도록 만들었다. 즉, 회원가입 페이지는 아래처럼 되어 있다. 이 모든 값들을 사용자가 입력해야 만 회원가입이 가능하게 하려고 한다. 그러면 2가지 처

happy-fun.tistory.com

이 글을 읽어보면 된다.)

 

 

 

그러면 AuthController.java에서 이를 받아서 회원가입 처리 한다.

그런데, signupdto.java 는 사용자가 웹 사이트에 입력한 값을 받아오는 오브젝트이고,

이를 데이터베이스에 저장하려면, 

User.java 오브젝트를 만들어서 signupdto.java에서 받은 데이터를 이곳(User.java) 에 담아야 한다.

그리고 이를 repository로 전달해줘서 데이터베이스에 저장하도록 해야 한다.

 

 

 

즉, 웹 사이트에서 사용자가 회원가입 페이지에 입력한 정보를 받아오는 것은

SignupDto.java 파일이고,

 

이렇게 받아온 정보를 데이터 베이스에 저장할 때 사용되는 것은

User.java 파일이다.

 

 

 

<User.java> 파일

import java.time.LocalDateTime;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.PrePersist;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

@Builder
@AllArgsConstructor
@NoArgsConstructor
@Data
@Entity
public class User {
	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY) 
	private int id;
	
	@Column(length = 100,  unique = true) 
	private String username; 
	@Column(nullable = false)
	private String password;
	@Column(nullable = false)
	private String name;
	private String website; // 웹 사이트
	private String bio; // 자기 소개
	@Column(nullable = false)
	private String email;
	private String phone;
	private String gender;
	private String role; // 권한
	
	
	private String profileImageUrl;
	private LocalDateTime createDate;
	
	@PrePersist 
	public void createDate() {
		this.createDate = LocalDateTime.now();
	}

}

 

여기에 보면, 우리는 username, password, email, name 만 사용자로부터 받았지만, website 등 다른 변수가 user.java 오브젝트에 있는 것을 알 수 있다.

(최종적으로 데이터베이스에는 username, password, name, email, website, bio, phone 등 모든 변수가 테이블로 만들어진다.)

 

 

아무튼, 그래서 SignupDto.java에 사용자로부터 받은 데이터들을 User.java 오브젝트로 만들기 위해 SignupDto.java 파일에서 toEntity 메서드를 만든다. (빌더 패턴 사용- User.java에서 @Builder 어노테이션 사용)

 

 

 

어노테이션 설명:

@PrePersist 

db 에 값이 insert 되기 직전에 실행

 

즉, createDate 부분은 자동으로 db에 들어감

 

 

@Entity

db에 테이블 생성해줌

 

@GeneratedValue(strategy = GenerationType.IDENTITY) 

번호 증가 전략이 데이터베이스를 따라감

 

 

 

 

<SignupDto.java> 파일

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;

import com.tree.sky.domain.user.User;

import lombok.Data;

@Data
public class SignupDto {

	@Size(min = 2, max = 20)
	@NotBlank
	private String username;
	@NotBlank
	private String password;
	@NotBlank
	private String email;
	@NotBlank
	private String name;
	
	
	public User toEntity() {
		return User.builder()
				.username(username)
				.password(password)
				.email(email)
				.name(name)
				.build();
	}
	
}

 

그런 다음 AuthController.java에서 

SignupDto.java의 toEntity로 만들어진 user 오브젝트를 데이터베이스에 저장하도록 코드를 만든다.

 

<AuthController.java> 파일

@RequiredArgsConstructor
@Controller
public class AuthController {


	private final AuthService authService;
	
    
    	@PostMapping("/auth/signup")
	public String signup(@Valid SignupDto signupDto, BindingResult bindingResult) {

		
	
		if (bindingResult.hasErrors()) {
			Map<String, String> errorMap = new HashMap<>();

			for (FieldError error : bindingResult.getFieldErrors()) {
				errorMap.put(error.getField(), error.getDefaultMessage());
			}
			throw new CustomValidationException("유효성 검사 실패함", errorMap);
		}else {
		
		User user = signupDto.toEntity();
		authService.회원가입(user);
	
		return "auth/signin";

	   }
	}
	
	
	
	
	
}

여기서 보면 signupDto.toEntity로 user 오브젝트를 받고,

authService 객체의 회원가입 메서드로 회원가입을 완성하는 것을 알 수 있다.

 

(더불어 이 코드에서 @Valid, BindingResult,  관련한 코드는 회원가입 유효성 관련 코드로, 

https://happy-fun.tistory.com/152

 

회원가입 유효성 검사

회원가입 시 username password email name 값을 받도록 만들었다. 즉, 회원가입 페이지는 아래처럼 되어 있다. 이 모든 값들을 사용자가 입력해야 만 회원가입이 가능하게 하려고 한다. 그러면 2가지 처

happy-fun.tistory.com

 

이 글을 읽어 보면 된다.)

 

 

(또한 AuthController.java에서 AuthService 객체의 회원가입 메서드를 사용할 떄, 의존성 주입이 필요한데 이에 대한 설명은 아래의 글을 참고하면 된다.

https://happy-fun.tistory.com/156

 

의존성 주입

프로젝트에서 회원가입 코드를 만들 때, AuthController.java 에서 AuthService.java의 회원가입 메서드를 사용하려고 한다면 AuthController.java에 AuthService 오브젝트를 의존성 주입해야 한다. 즉, 아래에서..

happy-fun.tistory.com

 

)

 

 

 

 

<AuthService.java> 파일

import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.tree.sky.domain.user.User;
import com.tree.sky.domain.user.UserRepository;

import lombok.RequiredArgsConstructor;


@RequiredArgsConstructor
@Service
public class AuthService {

	
	private final UserRepository userRepository;
	private final BCryptPasswordEncoder bCryptPasswordEncoder;
	
	
	
	
	@Transactional 
	public User 회원가입(User user) throws RuntimeException{
		String rawPassword = user.getPassword();
		String encPassword = bCryptPasswordEncoder.encode(rawPassword);
		user.setPassword(encPassword);
		user.setRole("ROLE_USER"); // 관리자 ROLE_ADMIN
		User userEntity = null;
		userEntity = userRepository.save(user);
		
		
		return userEntity;
	}
	
	
}

 

여기서 회원가입 메서드를 확인할 수 있다.

특히, 비밀번호 해쉬를 위해 

일단 AuthController.java에서 받아온 user 객체에서 비밀번호를 

rawPassword 변수로 받고,

bCryptPasswordEncoder로 해쉬화 해준다음 다시 user 오브젝트에 넣어주는 것을 알 수 있다.

그리고 권한은, 관리자 권한을 주기 위해 ROLE_USER 로 넣어주었다.

그런다음, userEntity User 객체를 만들어줘서, repository에 저장하고 난 다음의 회원 정보를 받는다.

return userEntity로 받고 있고, 

AuthController.java에서도 보면 return "auth/signin" 하고 있는 거로 보아,

signin.jsp 파일에서 이 사용자 정보를 활용해서 signin.jsp 화면에서 사용할 것임을 알 수 있다.

 

 

@Service

ioc 관리, 트랜잭션 관리

 

 

 

<UserRepository.java> 파일

 

import org.springframework.data.jpa.repository.JpaRepository;

public interface UserRepository extends JpaRepository<User,Integer>{

	
	User findByUsername(String username);
}

특히, respotiroy.java의 경우는, JpaRepository를 상속하면 

어노테이션 없어도 IoC 등록이 자동으로 됨 

 

 

 

이렇게 하면 회원가입이 완료된다.

 

-끝-

 

 

 

<추가 설명>

 

 

회원가입 시

username, password, email, name 값을 사용자로부터 받을 건데,

이렇게 받은 값을 SignupDto.java 파일에 받아서 

AuthController.java 파일에 회원가입 함수에 매개변수로 넣어줄 거임.

 

<SignupDto.java> 파일

@Data
public class SignupDto {

	
	private String username;
	private String password;
	private String email;
	private String name;

 

어노테이션 설명 :

@Data : Getter, Setter를 만들어주는 어노테이션

 

 

그런데, 회원정보가 잘 들어오는지 확인하기 위해,

log를 사용할 수 있음

 

즉, AuthController.java 파일에서 

 

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@RequiredArgsConstructor
@Controller
public class AuthController {

	private static final Logger log = LoggerFactory.getLogger(AuthController.class);
    
    
	@PostMapping("/auth/signup")
	public String signup(SignupDto signupDto) {

		log.info(signupDto.toString());
	
		return "auth/signin";

	   }
	}

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

 

private static final Logger log = LoggerFactory.getLogger(AuthController.class); 선언 후에

log.info(signupDto.toString()); 

 

 

 

 

이렇게 사용하면, 이클립스(sts) 콘솔창에 사용자가 입력한 회원가입 정보가 들어옴

 

 

이런식으로 사용자가 회원가입 때 입력한 username, password, email, name 값을 볼 수 있음

 

 

 

만약에, SignupDto.java의 toString()메서드로 받아온 User 객체를 확인하고 싶다면,

 

AuthController.java 에서

 

1. log.info(signupDto.toString()); 

이 코드 아래에 

 

User user = signupDto.toEntity();

2. log.info(user.toString());

 

이 코드를 추가하면 된다.

 

 

 

@PostMapping("/auth/signup")
	public String signup(SignupDto signupDto) {

		log.info(signupDto.toString()); 	
		User user = signupDto.toEntity();
		
		log.info(user.toString());
	
		return "auth/signin";

	   }
	}

그러면 아래와 같이 웹사이트상에서 사용자가 회원가입을 하면

이클립스(sts) 콘솔창에

1, 2 가 실행된 두 개의 결과를 볼 수 있다.

 

 

참고 자료 : 이지업 강의 사이트 "스프링부트 SNS프로젝트 - 포토그램 만들기"