바트심슨으로 하루만 살고 싶다
[스프링 프레임워크]게시판 만들기 #4 : 회원가입 본문
* 이전 내용
[스프링 프레임워크]게시판 만들기 #3 : 데이터베이스 테이블 생성 및 게시판 카테고리 출력, 페이지 상하단 고정
[스프링 프레임워크]게시판 만들기 #3 : 데이터베이스 테이블 생성 및 게시판 카테고리 출력, 페
* 이전 내용 [스프링 프레임워크]게시판 만들기 #2 : Spring과 오라클 DB 연동 및 데이터 베이스 세팅, dependency 세팅 [스프링 프레임워크]게시판 만들기 #2 : Spring과 오라클 DB 연동 및 데이터 베이스
11027bart.tistory.com
회원가입
1. 회원가입 제약조건 설정하기
회원정보(이름, 아이디, 비밀번호 )를 입력받고 회원가입 진행하기
기본적인 회원가입 폼은 아래 사진과 같다.
고려해야 할 사항 및 지정할 제약조건
1. 이름은 3자 ~ 5자의 한글로 입력
아이디, 비밀번호, 비밀번호 확인은 5자 ~ 10자의 영문 대, 소문자와 숫자로 입력
2. 모든 텍스트 입력
3. 데이터 베이스의 id가 존재하는지의 여부 확인
3 - 1. 중복확인을 하지 않고는 회원가입을 할 수 없도록 하기
4. 비밀번호와 비밀번호 확인의 입력이 같은지 확인하기
5. 모든 조건을 통과하면 회원가입 완료 알림창 띄우기
Join.jsp ( 회원가입 폼 )
hidden으로 idExist를 넣어주었다 - 이것은 중복확인 버튼을 클릭했는지의 여부를 확인할 수 있다.
<form:form action="${root }user/join_pro" method="post" modelAttribute="joinBean">
<form:hidden path="idExist"/>
<div class="form-group">
<form:label path="user_name">이름</form:label>
<form:input path="user_name" class="form-control"/>
<form:errors path="user_name" style='color:red'/>
</div>
<div class="form-group">
<form:label path="user_id">아이디</form:label>
<div class="input-group">
<form:input path="user_id" class="form-control" onkeypress="resetIdExist()"/>
<div class="input-group-append">
<button type="button" class="btn btn-primary" onclick="checkIdExist()">중복확인</button>
</div>
</div>
<form:errors path="user_id" style='color:red'/>
</div>
<div class="form-group">
<form:label path="user_pw">비밀번호</form:label>
<form:password path="user_pw" class="form-control"/>
<form:errors path="user_pw" style='color:red'/>
</div>
<div class="form-group">
<form:label path="user_pw2">비밀번호 확인</form:label>
<form:password path="user_pw2" class="form-control"/>
<form:errors path="user_pw2" style='color:red'/>
</div>
<div class="form-group">
<div class="text-right">
<button type="submit" class="btn btn-primary">회원가입</button>
</div>
</div>
</form:form>
form 태그를 이용해 회원가입 시 modelAttribute로 지정한 "joinBean"에 해당 데이터들을 가지고 가게 해준다.
회원가입 시 중복확인 버튼 클릭 여부 확인과 비밀번호 일치 확인의 작업을 각각 스크립트에서 onclick과 onkeypress함수를 작성해 설정해줄 수 있다. - 아래에서 설명
User DTO (회원 관련)
2. @Size, @Pattern 어노테이션으로 제약조건 설정하기, 중복확인 버튼 초기화
package co.ky.sol.beans;
public class User {
private int user_idx;
@Size(min=3, max=5)
@Pattern(regexp="[가-힣]*")
private String user_name;
@Size(min=5, max=10)
@Pattern(regexp="[a-zA-Z0-9]*")
private String user_id;
@Size(min=5, max=10)
@Pattern(regexp="[a-zA-Z0-9]*")
private String user_pw;
@Size(min=5, max=10)
@Pattern(regexp="[a-zA-Z0-9]*")
private String user_pw2;
private boolean idExist;
//중복확인 = false , 로그인 = false
//초기값으로 확인을 하지 않은 상태로 만든다.
public User() {
this.idExist = false;
}
// getter, setter 생략
}
이름(user_name)은 3자 ~ 5자의 한글
아이디, 비밀번호, 비밀번호 확인(user_id, user_pw, user_pw2)은 영문 대, 소문자와 숫자가 포함된 5자 ~ 10자의 조건을
설정했다.
이 상태에서도 에러메세지는 나오지만 엉성한 부분이 있으니 에러메시지를 따로 설정하기 위해 properties를 작성하자.
error.properties 프로퍼티 파일 에러 메시지로 사용하기
Size.joinBean.user_name = 사용자 이름은 3~5글자 사이여야한다.
Pattern.joinBean.user_name = 사용자 이름은 한글로 작성
Size.joinBean.user_id = 사용자 아이디는 5~10 글자 사이여야한다.
Pattern.joinBean.user_id = 사용자 아이디는 영문자 및 숫자로 입력
Size.joinBean.user_pw = 사용자 비밀번호는 5~10 글자 사이여야한다.
Pattern.joinBean.user_pw = 사용자 비밀번호는 영문자 및 숫자로 입력
Size.joinBean.user_pw2 = 사용자 비밀번호는 5~10 글자 사이여야한다.
Pattern.joinBean.user_pw2 = 사용자 비밀번호는 영문자 및 숫자로 입력
NotEquals.joinBean.user_pw = 비밀번호가 일치하지 않습니다.
NotEquals.joinBean.user_pw2 = 비밀번호가 일치하지 않습니다.
CheckyourIdExist.joinBean.user_id = 중복확인을 누른 뒤 회원가입 해주세요
properties를 에러메시지로 대체하기 위해 validate 관련 설정을 해주어야 한다.
3. ServletAppContext에 프로퍼티 파일을 메시지로 사용하기 위한 bean 등록
@Bean
public static PropertySourcesPlaceholderConfigurer PropertySourcesPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
@Bean
public ReloadableResourceBundleMessageSource messageSource() {
ReloadableResourceBundleMessageSource res=new ReloadableResourceBundleMessageSource();
res.setBasenames("/WEB-INF/properties/error");
return res;
}
PropertySourcesPlaceholderConfigurer
- 추상 클래스PlaceholderConfigurerSupport를 구현한 클래스
- Bean으로 등록해서 사용하며, PropertySource를 여러 개 등록할 수 있다.
- PropertySource를 추가하여 @Value 어노테이션의 ${...}${...} 부분에 프로퍼티 값을 주입해 준다.
ReloadableResourceBundleMessageSource
- 원래 properties로 지정하면 서버가 가동되는 동안에는 값 변경이 불가하지만, 서버를 중지하지 않더라도 properties를 갱신해서 사용 가능
- properties 파일을 등록해 주면 message로 등록 가능
4. Validator 생성하기 - 비밀번호 불일치 확인, 중복확인 버튼 클릭하도록 설정
package co.ky.sol.validator;
public class UserValidator implements Validator {
@Override
public boolean supports(Class<?> clazz) {
return User.class.isAssignableFrom(clazz);
}
@Override
public void validate(Object target, Errors errors) {
User user = (User) target;
//에러가 발생한 객체의 이름을 검사한다.
//에러 메시지 충돌 방지
String str = errors.getObjectName();
//회원가입에 관한 유효성 검사 - 비밀번호 확인
if (str.equals("joinBean")) {
if (user.getUser_pw().equals(user.getUser_pw2()) == false) {
errors.rejectValue("user_pw", "NotEquals");
errors.rejectValue("user_pw2", "NotEquals");
}
// 중복확인을 안했다면 에러 메시지 출력
if (user.isIdExist() == false) {
errors.rejectValue("user_id", "CheckyourIdExist");
}
}
}
}
5. Controller에 @InitBinder 선언하기
@InitBinder : UserValidator 사용 시 @Valid 어노테이션으로 검증이 필요한 객체를 가져오기 전에 수행할 메서드를 지정해 주는 어노테이션
WebDataBinder
- 커맨드 객체를 바인딩하는 객체
- addValidator() 메서드를 통해 UserValidator 객체를 add 해준다는 의미로 데이터 검증을 하겠다는 의미
- @InitBinder 어노테이션이 붙은 메서드를 통해 최초에 호출하여 데이터를 검증
회원 가입 폼에서 해당 오류가 출력되는 것을 확인할 수 있다.
중복 확인 클릭 확인
function checkIdExist() {
var user_id = $("#user_id").val();
if (user_id.length == 0) {
alert("아이디를 입력해주세요");
return;
}
$.ajax({
url: "${root}user/checkIdExist/" + user_id,
type: "get",
dataType: "text",
success: function (result) {
if (result.trim() == "true") {
alert("사용할 수 있는 아이디입니다");
$("#idExist").val("true");
} else {
alert("사용할 수 없는 아이디입니다");
$("#idExist").val("false");
}
},
});
}
function resetIdExist() {
$("#idExist").val("false");
}
checkIdExist
- 중복확인 버튼 클릭 시 입력되어 있는 텍스트가 없다면 다시 입력
- ajax를 이용해 user_id에 입력된 정보를 매핑 과정을 거쳐 반환된 데이터가
true라면 중복확인 버튼은 $("#idExist"). val("true")로 클릭이 진행된 상태로 만들고
false라면 중복 확인 버튼은 $("#idExist"). val("false")로 클릭이 진행되지 않은 상태로 만든다.
ajax 진행 과정에서 RestController를 이용한다.
url에 user_id를 담아 RestController에서 해당 url을 매핑해 같이 넘어온 파라미터를 checkIdExist 메서드를 이용해
true / false를 반환받아온다.
package co.ky.sol.controller;
@RestController
public class ResController {
//Json 형태로 객체 데이터를 반환하는 것
//특정 URL에 접속 시 데이터를 String 형태로 반환해줌
//데이터를 제공하는 REST API 개발할 때 사용
//응답 결과가 데이터 (문자열인 경우) 주로 사용
@Autowired
private UserService userService;
@GetMapping("/user/checkIdExist/{user_id}")
public String checkIdExist(@PathVariable String user_id) {
//id가 있다면
boolean b = userService.checkIdExist(user_id);
return b + "";
}
}
resetIdExist
- onkeypress로 지정해 해당 인풋에 키 입력이 발생한 경우 $("#idExist").val("false")로 클릭이 진행되지 않은 상태로 만든다.
이제 로그인 폼에서 가지고 오는 데이터를 ModelAttribute를 통해 이름을 지정해 주어야 한다.
( 여러 번 사용되기 때문에 타입이 아닌 이름으로 분류해 주어야 오류가 나지 않는다. )
( UserController 회원가입 매핑)
@GetMapping("/join")
public String join(@ModelAttribute("joinBean") User joinBean) {
return "user/join";
}
@PostMapping("/join_pro")
public String join_pro(@Valid @ModelAttribute("joinBean") User joinBean ,
BindingResult result) {
if(result.hasErrors()) {
return "user/join";
}
//내가 회원가입 폼에 입력한 사용자 정보를
//Mapper > DAO > Service를 거쳐 Mapping에서 joinBean에 저장하겠다.
userService.addUser(joinBean);
return "user/join_success";
}
UserMapper인터페이스 - 회원가입 완료 시 insert문으로 회원정보를 테이블에 삽입하도록 정의
package co.ky.sol.mapper;
public interface UserMapper {
//중복확인을 위해 user_id를 기준으로 user_name이 존재하는지 확인하는 쿼리문
@Select("select user_name from user_info_table where user_id=#{user_id}")
String checkIdExist(String user_id);
//데이터베이스에 집어넣는 작업이기 때문에 반환형이 없다.
@Insert("insert into user_info_table(user_idx, user_name, user_id, user_pw) values(user_seq.nextval, #{user_name}, #{user_id}, #{user_pw})")
void addUser(User joinBean);
}
#{}
파라미터가 String 형태로 들어와 자동적으로 '파라미터' 형태가 된다.
위의 코드에서 #{user_id}는 user_id의 값이 abc라면 쿼리문에는 USER_ID='abc'의 형태가 된다.
@Insert에서 user_seq.nextval은 user_seq 시퀀스를 실행하여 user_idx의 수를 증가시킨다는 의미이다.
create sequence user_seq
start with 0
INCREMENT by 1
MINVALUE 0;
UserDao - 회원 정보와 관련된 정보 주입, 전송 및 DB와 연동되는 클래스
package co.ky.sol.dao;
@Repository
public class UserDao {
@Autowired
private UserMapper userMapper;
//중복 확인
public String checkIdExist(String user_id) {
return userMapper.checkIdExist(user_id);
}
//회원가입시 정보 삽입
public void addUser(User joinBean) {
userMapper.addUser(joinBean);
}
}
UserService - 비즈니스 로직을 처리하는 클래스(DAO에서 정의한 메서드 호출 후 사용)
package co.ky.sol.service;
@Service
public class UserService {
@Autowired
private UserDao userDao;
public boolean checkIdExist(String user_id) {
String user_name = userDao.checkIdExist(user_id);
// name이 없다는 것 = 회원 정보에 이름이 없다.
if(user_name == null) {
return true;
}
// name이 이미 회원 정보에 존재한다.
else {
return false;
}
}
public void addUser(User joinUser) {
//dao에 있는 addUser메서드를 호출
userDao.addUser(joinUser);
}
}
checkIdExist(String user_id)
DB에서 user_id와 일치하는 user_name이 없다면 회원가입 폼에서
중복 확인 시 사용 가능한 아이디이기 때문에 반환은 true로 주었다.
addUser(User joinUser)
회원가입 폼에서 넘어온 데이터를 DB에 삽입할 수 있다.
(Controller에서 매핑 과정에서 사용됨)
UserController
- 로그인과 회원가입에 대한 매핑
- @valid 유효성 검사
- modelAttribute로 지정한 이름으로 파라미터 데이터를 DTO객체에 지정해 넣는다.
- BindingResult로 에러가 발생하는지 여부 확인
- @initBinder로 추가적인 validator 실행
- UserService를 사용할 수 있도록 @Autowired로 자동주입
- join_pro에서 service를 이용해 호출
package co.ky.sol.controller;
@Controller
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
//회원가입 페이지 요청시 User객체 joinBean을 @ModelAttribute에
//"joinBean"으로 회원가입 폼에서 지정한 이름과 같도록 지정한다.
//이 과정을 통해서 회원가입 완료를 하는 과정에서 해당 입력 데이터들이
// "joinBean"에 담겨진다.
@GetMapping("/join")
public String join(@ModelAttribute("joinBean") User joinBean) {
return "user/join";
}
//회원가입 시 에러사항이 발생하지는 않았는지
//만약 발생하지 않았다면 DB에 회원추가를 진행한다.
@PostMapping("/join_pro")
public String join_pro(@Valid @ModelAttribute("joinBean") User joinBean ,
BindingResult result) {
if(result.hasErrors()) {
return "user/join";
}
userService.addUser(joinBean);
return "user/join_success";
}
}
이제 회원 가입이 제대로 작동하는지 확인해 보자.
'Java > Spring' 카테고리의 다른 글
[스프링 프레임워크]게시판 만들기 #6 : 글 작성, 게시글 목록, 게시글 상세보기, 게시글 수정-삭제 접근 방지 (2) | 2023.02.16 |
---|---|
[스프링 프레임워크]게시판 만들기 #5 : 로그인, 로그아웃, 정보수정 (1) | 2023.02.16 |
[스프링 프레임워크]게시판 만들기 #3 : 데이터베이스 테이블 생성 및 게시판 카테고리 출력, 페이지 상하단 고정 (0) | 2023.02.14 |
[스프링 프레임워크]게시판 만들기 #2 : Spring과 오라클 DB 연동 및 데이터 베이스 세팅, dependency 세팅 (0) | 2023.02.13 |
[스프링 프레임워크]게시판 만들기 # 1 : 프로젝트 생성 및 셋팅 (0) | 2023.02.13 |