본문 바로가기
Java/Spring

Spring) 회원 가입 처리하기 (index페이지에서 alert 작동 안되는 원인 파악)

by 박채니 2022. 8. 19.

안녕하세요, 코린이의 코딩 학습기 채니 입니다.

 

개인 포스팅용으로 내용에 오류 및 잘못된 정보가 있을 수 있습니다.


회원 테이블 생성

-- 회원테이블 생성
create table member(
    member_id varchar2(50),
    password varchar2(300) not null,
    name varchar2(256) not null,
    gender char(1),
    birthday date,
    email varchar2(256),
    phone char(11) not null,
    address varchar2(512),
    hobby varchar2(256),
    created_at date default sysdate,
    updated_at date,
    enabled number default 1, -- 1, 0
    constraint pk_member_id primary key(member_id),
    constraint ck_member_gender check(gender in ('M', 'F')),
    constraint ck_member_enabled check(enabled in (1, 0))
);

insert into spring2.member values ('abcde','1234','아무개','M',to_date('88-01-25','rr-mm-dd'),'abcde@naver.com','01012345678','서울시 강남구','운동,등산,독서',default, null, default);
insert into spring2.member values ('qwerty','1234','김말년','F',to_date('78-02-25','rr-mm-dd'),'qwerty@naver.com','01098765432','서울시 관악구','운동,등산',default, null, default);
insert into spring2.member values ('admin','1234','관리자','F',to_date('90-12-25','rr-mm-dd'),'admin@naver.com','01012345678','서울시 강남구','독서',default, null, default);
commit;

 

클래스 구조

 

Dto

Member

@NonNull - 필수 값 처리

@Data - Getter, Setter, RequiredArgsContructor, ToString, EqualsAndHashCode 처리 

// @Getter @Setter @RequiredArgsConstructor @ToString @EqualsAndHashCode. 
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Member {
	@NonNull
	private String memberId;
	@NonNull
	private String password;
	@NonNull
	private String name;
	private Gender gender;
	@DateTimeFormat(pattern = "yyyy-MM-dd") //클라이언트에서 온 값을 커맨드객체에 대입하기 위함!
	private LocalDate birthday;
	private String email;
	@NonNull
	private String phone;
	private String address;
	private String hobby;
	private LocalDateTime createdAt;
	private LocalDateTime updatedAt;
	private boolean enabled;
}

@NonNull 어노테이션을 통해 필수 값 필드를 처리해줄 수 있습니다.

또한, @Getter + @Setter + @RequiredArgsConstructor + @ToString + @EqulasAndHashCode를 한 번에 처리해주는 @Data 어노테이션을 이용할 수 있지만, 생성자를 @RequiredArgsConstructor로 생성하기 때문에 @NonNull이 붙은 필드값에 대해서만 생성자를 만들어줍니다.

@Data만 사용할 경우 (생성자)

따라서 필요에 따라 기본생성자, 모든 파라미터 생성자에 대한 어노테이션을 추가해줘야 합니다.

@NoArg..., @AllArgs... 추가 시 (생성자)

 


회원 가입 처리하기

 

memberEnroll.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%>
<jsp:include page="/WEB-INF/views/common/header.jsp">
	<jsp:param value="회원등록" name="title"/>
</jsp:include>
<link rel="stylesheet" href="${ pageContext.request.contextPath }/resources/css/member.css" />

<div id="enroll-container" class="mx-auto text-center">
	<form name="memberEnrollFrm" action="" method="POST">
		<table class="mx-auto">
			<tr>
				<th>아이디</th>
				<td>
					<input type="text" 
						   class="form-control" 
						   placeholder="4글자이상"
						   name="memberId" 
						   id="memberId"
						   required>
				</td>
			</tr>
			<tr>
				<th>패스워드</th>
				<td>
					<input type="password" class="form-control" name="password" id="password" required>
				</td>
			</tr>
			<tr>
				<th>패스워드확인</th>
				<td>	
					<input type="password" class="form-control" id="passwordCheck" required>
				</td>
			</tr>  
			<tr>
				<th>이름</th>
				<td>	
					<input type="text" class="form-control" name="name" id="name" required>
				</td>
			</tr>
			<tr>
				<th>생년월일</th>
				<td>	
					<input type="date" class="form-control" name="birthday" id="birthday"/>
				</td>
			</tr> 
			<tr>
				<th>이메일</th>
				<td>	
					<input type="email" class="form-control" placeholder="abc@xyz.com" name="email" id="email">
				</td>
			</tr>
			<tr>
				<th>휴대폰</th>
				<td>	
					<input type="tel" class="form-control" placeholder="(-없이)01012345678" name="phone" id="phone" maxlength="11" required>
				</td>
			</tr>
			<tr>
				<th>주소</th>
				<td>	
					<input type="text" class="form-control" placeholder="" name="address" id="address">
				</td>
			</tr>
			<tr>
				<th>성별 </th>
				<td>
					<div class="form-check form-check-inline">
						<input type="radio" class="form-check-input" name="gender" id="gender0" value="M">
						<label  class="form-check-label" for="gender0">남</label>&nbsp;
						<input type="radio" class="form-check-input" name="gender" id="gender1" value="F">
						<label  class="form-check-label" for="gender1">여</label>
					</div>
				</td>
			</tr>
			<tr>
				<th>취미 </th>
				<td>
					<div class="form-check form-check-inline">
						<input type="checkbox" class="form-check-input" name="hobby" id="hobby0" value="운동"><label class="form-check-label" for="hobby0">운동</label>&nbsp;
						<input type="checkbox" class="form-check-input" name="hobby" id="hobby1" value="등산"><label class="form-check-label" for="hobby1">등산</label>&nbsp;
						<input type="checkbox" class="form-check-input" name="hobby" id="hobby2" value="독서"><label class="form-check-label" for="hobby2">독서</label>&nbsp;
						<input type="checkbox" class="form-check-input" name="hobby" id="hobby3" value="게임"><label class="form-check-label" for="hobby3">게임</label>&nbsp;
						<input type="checkbox" class="form-check-input" name="hobby" id="hobby4" value="여행"><label class="form-check-label" for="hobby4">여행</label>&nbsp;
					 </div>
				</td>
			</tr>
		</table>
		<input type="submit" value="가입" >
		<input type="reset" value="취소">
	</form>
</div>
<jsp:include page="/WEB-INF/views/common/footer.jsp"/>

 

Controller

MemberController

@GetMapping - GET 방식

@PostMapping - POST 방식

@Controller
@RequestMapping("/member")
@Slf4j
public class MemberController {
	@Autowired
	private MemberService memberService;
	
	@GetMapping("/memberEnroll.do")
	public String memberEnroll() {
		
		return "member/memberEnroll";
	}
	
	@PostMapping("/memberEnroll.do")
	public String memberEnroll(Member member, RedirectAttributes redirectAttr) {
		try {
			int result = memberService.insertMember(member);
			redirectAttr.addFlashAttribute("msg", "회원가입이 정상적으로 처리 되었습니다.");
			
			return "redirect:/";
		} catch(Exception e) {
			log.error("회원 가입 오류 : " + e.getMessage(), e);
			throw e;
		}
	}
}

@GetMapping, @PostMapping으로 전송 방식에 따라 자동 매핑해주는 어노테이션을 사용하였습니다.

 

Service

MemberService interface 생략

MemberServiceImpl

@Service
public class MemberServiceImpl implements MemberService {
	@Autowired
	private MemberDao memberDao;
	
	@Override
	public int insertMember(Member member) {
		return memberDao.insertMember(member);
	}
}

 

Dao

MemberDao interface

public interface MemberDao {

	int insertMember(Member member);
	
}

기존까지는 Dao interface의 구현체 클래스를 생성하였지만, member 패키지는 구현체를 직접 생성하지 않고 Mybatis에게 구현체를 동적으로 생성해달라고 요청하려고 합니다.

 

Mybatis → 구현체 동적으로 생성

member-mapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ce.spring2.member.model.dao.MemberDao">
  <insert id="insertMember">
  	insert into member values (#{memberId}, #{password}, #{name}, #{gender}, #{birthday}, #{email}, #{phone}, #{address}, #{hobby}, default, default, default)
  </insert>
</mapper>

namespace를 해당 인터페이스의 패키지 명 포함 풀네임으로 작성해줘야합니다.

(해당 인터페이스에서 넘어오도록 하는 설정!) - 태그의 아이디는 메소드명

 

@Mapper - Mapper 인터페이스로 설정

@Mapper
public interface MemberDao {

	int insertMember(Member member);
	
}

 

root-context.xml

#6.3 @Mapper 인터페이스 등록 : Dao 구현 객체를 동적으로 생성

- Dao 구현체를 Mybatis에서 동적으로 생성해달라고 등록! (이런 인터페이스 있으니까 구현체 만들어줘~~)

<!-- #6.3 @Mapper 인터페이스 등록 : Dao 구현 객체를 동적으로 생성 -->
<mybatis-spring:scan base-package="com.ce.spring2.**.dao"/>

com.ce.spring2 하위에 어떤 패키지든 dao 패키지를 모두 동적으로 생성해달라고 요청하였습니다.

 

회원가입

잘 처리되는 것을 확인할 수 있습니다.

 

 

 

※ index 페이지에서 자꾸 RedirectAttribute 한 내용이 확인 되지 않아 확인해본 결과, welcome페이지 때문!!

서버의 web.xml에서 하단에 welcome-file 주석처리하니 잘 작동됨

    <!-- <welcome-file-list>
        <welcome-file>index.html</welcome-file>
        <welcome-file>index.htm</welcome-file>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list> -->