1️⃣ 현재 상태
⏺️ 서버를 돌리고
http://localhost:8080/joinForm 페이지 접속
⏺️ 회원가입 메뉴 클릭 후
⏺️ 회원 정보 입력, 그리고 회원가입 클릭⏺️ 아래와 같이
localhost:8080/join으로 리다이렉팅 되지만 페이지는 없다.
⏺️ 요 서비스를 구현해야됨2️⃣ 프론트 영역확인 먼저 (html 확인)
⏺️
joinForm.html >> <form> 태그 내부 구조 확인
⏺️ action=”/join” 확인 : URL로 /join 페이지 요청이 들어왔을 때 해당 폼태그 실행
⏺️ method=”post확인 : DB에 가입정보를 넣어 변경하는 행동이기 때문에 post
⏺️ x-www-form-urlencoded확인 : 해당 설정이 있어야지, 사용자가 정보를 제출하면 브라우저가 xform 데이터 형식에 맞춰서 인코딩해준다. 이는 서버가 파싱하기 좋게 바꿔준다는 말이다.
⏺️ name= “(키값)“ 확인 : 해당 input 태그에 이 값이 User의 필드값이랑 이름이 일치해야지 브라우저가 인코딩할 수 있다.
⏺️ <button type=”submit”>확인 : 폼태그 내부에 버튼이 위치하고 타입이 submit 이 되어야지 사용자가 ‘회원가입’을 클릭했을 때, 입력정보가 xform데이터로 서버에 전송이 된다.
⏺️ input타입이 text,password,email 으로 설정되어있으면 password입력란은 자동 글자숨김기능이 구현되고, email입력란은 자동으로 @가 있는지 유효성 검사를 한다.
3️⃣ 컨트롤러 책임 이해
컨트롤러 책임은 무엇인가????
컨트롤러
🔹 요청받기 (URL)
🔹 http body는 어떻게? (DTO)
🔹 기본 mime 전략 : x-www-form-urlencoded (username=ssar&password=1234)
🔹 유효성 검사하기 (body 데이터가 있다면)
🔹 클라이언트가 View만 원하는지? 혹은 DB 처리 후 View도 원하는지?
🔹 View만 원하면 view를 응답하면 끝
🔹 DB처리를 원하면 Model(DAO)에게 위임 후 view를 응답하면 끝
4️⃣ 리다이렉션 확인
🔹 일단 회원 가입버튼을 누르고 리다이렉션이 이루어지는지 확인한다.
🔹 다음 코드를 컨트롤러에 구현하자.
Java
@Controller //스프링 컨테이너에 빈 객체로 등록하게 해주는 어노테이션 (IoC의 객체역할)
public class UserController {
// URL경로 매핑 어노테이션 : 식별자 '/join'이 요청되면 해당 메소드를 연결해준다.
@PostMapping("/join")
public String join (){
// 리다이렉션 기능이기 때문에, 요청에 "/join" "/loginForm" 다 존재헤야된다.
return "redirect:/loginForm";
}🔹 아래 URL로 접속하여서 joinForm에서 회원가입을 시도해본다.
Java
http://localhost:8080/joinForm //페이지 접속⏺️ F12를 눌러서 개발자 도구를 들어가본다.
⏺️ 메뉴에서 Network에 들어간다.
⏺️ 회원가입을 누르면 joinForm과 join 페이지 모두 호출되어야 된다.
⏺️ 작동확인 완료!
5️⃣ DTO 만들기
DTO 만들기! DTO란??
데이터 전송 객체(DTO)란 프로세스 사이에서 데이터를 전송하는 객체를 말한다. DTO 기법을 사용하면 중요한 정보를 노출시키지 않고 두 시스템(API와 서버 등) 간 통신을 원활하게 촉진할 수 있다. DTO는 프로그래밍 직업을 가진 사람들이 흔히 사용하는 솔루션이라고 볼 수 있다.
회원 가입 창을 보면서 어떤 정보를 받아야 되는지 확인한다
사용자 username
사용자 password
사용자 email
필요하다!Java
package shop.mtcoding.blog.user;
import lombok.Data;
//요청에 관한 정보를 담을 객체 생성
public class UserRequest {
@Data //Lombok어노테이션으로 Getter,Setter,toString을 사용할 수 있게 해준다.
public static class JoinDTO { //요청중 회원가입에 전달되는 정보를 담을 객체
private String username;
private String password;
private String email;
}
}요청이 잘 전달 되는지 확인
🔹 먼저 join메서드에 파라메터로
UserRequest.JoinDTO requestDTO를 넣는다.
🔹 내부에 sout으로 requestDTO를 담는다. Java
@PostMapping("/join")
public String join (UserRequest.JoinDTO requestDTO){
System.out.println(requestDTO); // 테스트 코드
return "user/loginForm";
}그리고
/joinForm 페이지에서 아래와 같이 입력하고 회원가입 클릭하고 콘솔을 확인해보자.콘솔확인! 잘 작동한것 같다!
6️⃣ UserRepository구현
사용자의 정보를 DB에 입력시켜줄 로직이 필요하다!
Java
package shop.mtcoding.blog.user;
import jakarta.persistence.EntityManager;
import jakarta.persistence.Query;
import jakarta.transaction.Transactional;
import org.springframework.stereotype.Controller;
@Repository //스프링컨테이너에 현재 객체를 Bean으로 등록
public class UserRepository {
// DB와 상호작용 할 수 있게 도와주는 객체 - 쿼리문을 사용가능하게 한다.
// 스프링이 만들어논 객체이고 이미 IoC에 담겨있다. - 가져다 쓰면됨
private EntityManager em;
// 생성자에 의존성 주입 - 이 코드가 있어야 가져다 쓸수 있다.
public UserRepository(EntityManager em) {
this.em = em;
}
@Transactional // DB를 변경하는 작업을 할 때 동기화 시켜주는 어노테이션, 꼭 필요!!!
public void save(UserRequest.JoinDTO requestDTO) {
Query query = em.createNativeQuery("insert into user_tb(username, password, email, created_at) values (?,?,?, now()");
query.setParameter(1, requestDTO.getUsername());
query.setParameter(2, requestDTO.getPassword());
query.setParameter(3, requestDTO.getEmail());
query.executeUpdate(); // 쿼리 발송 flush()기능
}
}Query객체를
import할땐 jakarta.persistence로 해야된다.테스트 중 에러 목록
"this.userRepository" is null 펼쳐보기
Syntax error in SQL statement 펼쳐보기
마지막 확인 payload로 들어가서 값도 정상적으로 전달이 되었는지 확인
이렇게 브라우저로 값이 조회가 가능한거 자체가 보안에 취약할 것 같지만,
아직 그런 진도는 나가지 않았으므로 넘어감.
7️⃣ 컨트롤러 구현
Java
@RequiredArgsConstructor //final이 붙은 객체를 자동 초기화
@Controller//현재 객체를 Spring컨테이너에 등록
public class UserController {
private final UserRepository userRepository; // DB와 소통할 객체 의존성 주입
@PostMapping("/join") // DB를 변경하는 메서드이므로 Post요청
public String join(UserRequest.JoinDTO requestDTO){ // join메서드의 매개변수로 가입DTO전달
// 1. 유효성 검사 -- 이건 이따가
// 2. Model에게 위임하기 - DB와 상호작용할 객체와 메소드 구현 필요!!
userRepository.save(requestDTO);
return "redirect:/loginForm"; // 요청이 완료되면 loginForm으로 전달
}8️⃣ h2 DB 확인
h2 database에도 잘 들어가는지 확인
이 설정은
application-dev.yml에 설정이 되어있으므로
주소창에 입력만 해보면 된다.
설정에는 아이디 sa 비번은 없다.Java
//주소
http://localhost:8080/h2-console/h2 접속중 에러
DB연결 확인
8️⃣ 컨트롤러 유효성검사
이제 DB에 들어갈 정보를 검사하여 걸러내는 기능을 컨트롤러에 추가.
⏺️ 사용자 이름이 3자 이하 제한
⏺️ 에러조건 충족시 400번 페이지 연결
Java
@RequiredArgsConstructor //final이 붙은 객체를 자동 초기화
@Controller//현재 객체를 Spring컨테이너에 등록
public class UserController {
private final UserRepository userRepository; // DB와 소통할 객체 의존성 주입
@PostMapping("/join") // DB를 변경하는 메서드이므로 Post요청
public String join(UserRequest.JoinDTO requestDTO){ // join메서드의 매개변수로 가입DTO전달
// 1. 유효성 검사 - 사용자id가 3자 이하인경우 400번 에러메시지 전달
if(requestDTO.getUsername().length() < 3){
return "error/400";
}
// 2. Model에게 위임하기 - DB와 상호작용할 객체와 메소드 구현 필요!!
userRepository.save(requestDTO);
return "redirect:/loginForm"; // 요청이 완료되면 loginForm으로 전달
}⏺️ 에러 디렉토리 만들기
template >> error ⏺️ 디렉토리 내부
400.mustache 파일 생성
⏺️ mustache 템플릿엔진을 사용해서 html 페이지 작성html5 입력후 자동 추천 메뉴 클릭
🔹 안뜨면 글자 넣고
ctrl + space 누르면 뜬다.400.mustache 페이지 내부 구현
HTML
// 400.mustache 페이지 내부
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
</head>
<body>
<h1>잘못된 요청을 하셨습니다. 400</h1>
</body>
</html>의도적으로 username 두글자 넣어서 테스트
