Spring & Springboot/올인원 스프링 프레임워크

전자 도서관 프로젝트 - 관리자 회원가입 기능 구현

YJ_ma 2023. 10. 6. 22:56

관리자 회원가입 기능 구현

패키지와 클래스 생성하기

스프링 MVC는 MVC패턴에 기반한 프레임워크라고 한다.

따라서 관리자 회원가입 기능도 Controller, Service, DAO 객체를 이용해서 구현한다.

[src/main/java]에 다음과 같이 패키지와 클래스를 생성한다.

com.office.library.admin 패키지 com.office.library.admin.member 패키지
AdminHomeController.java · Controller 클래스 : AdminMemberController.java
· Dao 클래스 : AdminMemberDao.java
· Service 클래스 : AdminMemberService.java
· Vo 클래스 : AdminMemberVo.java

생성 결과 구조도

관리자 홈 만들기

관리자 홈 접속 URL : http://localhost:8090/library/admin

AdminHomeController에 관리자 홈 화면 접속할 수 있는 메서드를 만들고 /admin에 매핑한다.

■ AdminHomeController 코드

package com.office.library.admin;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller
@RequestMapping("/admin")
public class AdminHomeController {

	@RequestMapping(value={"", "/"}, method=RequestMethod.GET)
	public String home() {
		System.out.println("[AdminHomeController] home()");

		String nextPage = "admin/home";

		return nextPage;
	}
}

 

AdminHomeController는 @Controller에 의해서 프로젝트가 실행될 때 스프링 IoC 컨테이너에 빈 객체로 생성된다.

그리고 @RequestMapping("/admin")을 명시함으로써 기본적으로 /admin에 대한 요청을 AdminHomeController가 처리하게 된다.

 

📣만약 @RequestMapping("/admin")을 명시하지 않으면?

💡 AdminHomeController는 '/admin' 요청뿐만 아니라 클라이언트의 모든 요청을 처리할 수 있는 컨트롤러가 된다.

 

home()에 매핑되어 있는 문자열은 2개("", "/")이다.

이는 "/admin"과 "/admin/"요청을 모두 home()이 처리할 수 있게 해준다.

 

@RequestMapping은 valuemethod 속성을 가지고 있다.

· value 속성 : 사용자 요청 정보 명시

· method 속성 : 요청 정보가 전송되는 방식(get, post) 명시

- method의 기본 값은 get으로 만약 home()에 method 속성을 명시하지 않으면 home()은 get요청에 대해서만 호출된다.

또한 value 속성만 있다면 method를 명시하지 않고 value 속성 값만 명시할 수도 있다. 

다음은 동일한 매핑 방식이다.

① @RequestMapping(value = {"", "/"}, method = RequestMethod.GET)

② @RequestMapping(value = {"", "/"})

③ @RequestMapping({"", "/"})

 

home()은 "admin/home"을 반환한다.

이에 따르면 [views]의 [admin] 폴더에 있는 home, jsp를 이용해서 뷰로 만들고 이를 이용해서 클라이언트에 응답하게 된다.

home.jsp 실행 화면

 

관리자 회원가입 화면 만들기

· 다음 코드는 admin/home.jsp가 nav.jsp를 include하고 있다.

· nav.jsp의 경로 : WEB-INF > views > admin > include > nav.jsp

<jsp:include page="./include/nav.jsp" />

· nav.jsp는 관리자 화면의 전체적인 메뉴로 '회원가입'을 클릭하면 서버에 /admin/member/createAccountForm 요청이 발생한다.

<a href="<c:url value='/admin/member/createAccountForm' />" >회원가입</a>

 

이제 /createAccountForm 요청을 처리하기위해 AdminMemberController.java에 다음 작업을 수행한다.

· @Controller, @RequestMappping을 명시해서 AdminMemberController가 컨트롤러의 역할을 수행하도록 해준다.

· /createAccountForm 요청을 처리하는 메서드(createAccountForm())을 생성해준다.

· 이 메서드에는 회원가입 양식이 있는 페이지를 반환하는 코드를 넣어준다.

 

■ AdminMemberController.java 코드

package com.office.library.admin.member;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller
@RequestMapping("/admin/member")
public class AdminMemberController {

	// 회원가입
	@RequestMapping(value="/createAccountForm", method=RequestMethod.GET)
	public String createAccountForm() {
		System.out.println("[AdminMemberController] createAccountForm()");
		String nextPage = "admin/member/create_account_form";

		return nextPage;
	}

}

 

create_account_form.jsp는 home.jsp와 마찬가지로 InternalResourceViewResolver에 의해 클라이언트에게 반환된다.

servlet-context.xml

create_account_form.jsp는 관리자 회원가입 페이지로 <form>을 이용해서 관리자 정보를 입력할 수 있다.

<form>의 주요 속성

· value : 관리자 정보를 서버로 전송하기 위한 서버 주소(url)

value='/admin/member/createAccountConfirm'

· name : <form>의 이름으로 관리자 정보를 서버로 전송하기 전에 실시하는 유효성 검사에 이용
실제 관리자 정보가 저장되는 데이터베이스의 컬럼명과 동일하게 설정

name="create_account_form"

· method : 관리자 정보를 서버로 전송하는 방법을 설정

- 여기서는 관리자 개인정보(비밀번호 등)가 있으므로 post 방식으로 설정한다.

- 기본값 : get 방식

method="post"

■ create_account_form.jsp 코드

<div class="create_account_form">

    <form action="<c:url value='/admin/member/createAccountConfirm' />" name="create_account_form" method="post">

        <input type="text" name="a_m_id" placeholder="INPUT ADMIN ID."> <br>
        <input type="password" name="a_m_pw" placeholder="INPUT ADMIN PW."> <br>
        <input type="password" name="a_m_pw_again" placeholder="INPUT ADMIN PW AGAIN."> <br>
        <input type="text" name="a_m_name" placeholder="INPUT ADMIN NAME."> <br>
        <select name="a_m_gender">
            <option value="">SELECET ADMIN GENDER.</option>
            <option value="M">Man</option>
            <option value="W">Woman</option>
        </select> <br>
        <input type="text" name="a_m_part" placeholder="INPUT ADMIN PART."> <br>
        <input type="text" name="a_m_position" placeholder="INPUT ADMIN POSITION."> <br>
        <input type="email" name="a_m_mail" placeholder="INPUT ADMIN MAIL." ><br>
        <input type="text" name="a_m_phone" placeholder="INPUT ADMIN PHONE."> <br>
        <input type="button" value="create account" onclick="createAccountForm();"> 
        <input type="reset" value="reset">

    </form>

</div>

<form>안에 <input>과 <select>는 회원가입을 하는 관리자의 개인정보를 입력받기 위한 코드이다.

· a_m_id : 관리자 아이디

· a_m_pw : 관리자 비밀번호

· a_m_pw_again : 관리자의 의도치 않은 비밀번호 입력 방지 용도

· a_m_name : 관리자 이름

· a_m_gender : 관리자 성별

· a_m_part : 관리자 근무 부서

· a_m_position : 관리자 직무

· a_m_mail : 관리자 메일

· a_m_phone : 관리자 연락처

첫 실행 화면 회원가입 페이지
home.jsp 실행 화면

 

관리자 회원가입 처리하기

컨트롤러 기능 구현

· create_account_form.jsp에서 회원가입에서 필요한 관리자 정보 입력 후 <create account>버튼을 클릭하면 <form>의 action에 명시한 서버 주소로 관리자 정보가 전송된다.

· 이를 서버에서 처리하기 위해 AdminMemberController에 createAccountConfirm()메서드를 추가해준다.

■ AdminMemberController 코드

// 회원가입 확인
@RequestMapping(value="/createAccountConfirm", method=RequestMethod.POST)
public String createAccountConfirm() {
    System.out.println("[AdminMemberController] createAccountConfirm()");

    return null;
}

 

💡더 간략하게 표현

@RequestMapping → @GetMapping / @PostMapping

 

createAccountConfirm()은 관리자가 회원가입 양식에 입력한 정보를 파라미터로 받아야하는데, Vo 객체인 AdminMemberVo를 이용한다.

· AdminMemberVo는 개인정보에 해당하는 멤버 필드와 이를 외부에서 사용할 수 있도록 setter/getter 메서드로 구성되어 있다.

■ AdminMemberVo 코드

package com.office.library.admin.member;

public class AdminMemberVo {
	int a_m_no;				// 관리자 번호
	int a_m_approval;		// 최고 관리자 승인 여부
	String a_m_id;			// 관리자 아이디
	String a_m_pw;			// 관리자 비밀번호
	String a_m_name;		// 관리자 이름
	String a_m_gender;		// 관리자 성별 구분
	String a_m_part;		// 관리자 근무 부서
	String a_m_position;	// 관리자 업무
	String a_m_mail;		// 관리자 메일
	String a_m_phone;		// 관리자 연락처
	String a_m_reg_date;	// 관리자 등록일
	String a_m_mod_date;	// 관리자 수정일

	public int getA_m_no() {
		return a_m_no;
	}
	public void setA_m_no(int a_m_no) {
		this.a_m_no = a_m_no;
	}
	public int getA_m_approval() {
		return a_m_approval;
	}
	public void setA_m_approval(int a_m_approval) {
		this.a_m_approval = a_m_approval;
	}
	public String getA_m_id() {
		return a_m_id;
	}
	public void setA_m_id(String a_m_id) {
		this.a_m_id = a_m_id;
	}
	public String getA_m_pw() {
		return a_m_pw;
	}
	public void setA_m_pw(String a_m_pw) {
		this.a_m_pw = a_m_pw;
	}
	public String getA_m_name() {
		return a_m_name;
	}
	public void setA_m_name(String a_m_name) {
		this.a_m_name = a_m_name;
	}
	public String getA_m_gender() {
		return a_m_gender;
	}
	public void setA_m_gender(String a_m_gender) {
		this.a_m_gender = a_m_gender;
	}
	public String getA_m_part() {
		return a_m_part;
	}
	public void setA_m_part(String a_m_part) {
		this.a_m_part = a_m_part;
	}
	public String getA_m_position() {
		return a_m_position;
	}
	public void setA_m_position(String a_m_position) {
		this.a_m_position = a_m_position;
	}
	public String getA_m_mail() {
		return a_m_mail;
	}
	public void setA_m_mail(String a_m_mail) {
		this.a_m_mail = a_m_mail;
	}
	public String getA_m_phone() {
		return a_m_phone;
	}
	public void setA_m_phone(String a_m_phone) {
		this.a_m_phone = a_m_phone;
	}
	public String getA_m_reg_date() {
		return a_m_reg_date;
	}
	public void setA_m_reg_date(String a_m_reg_date) {
		this.a_m_reg_date = a_m_reg_date;
	}
	public String getA_m_mod_date() {
		return a_m_mod_date;
	}
	public void setA_m_mod_date(String a_m_mod_date) {
		this.a_m_mod_date = a_m_mod_date;
	}
}

이제 AdminMemberController.java에서 createAccountConfirm()을 다음과 같이 수정한다.

· 관리자가 입력한 정보를 AdminMemberVo에 담아서(setter 메서드 이용) createAccountConfirm()에 전달한다.

// 회원가입 확인
//@RequestMapping(value="/createAccountConfirm", method=RequestMethod.POST)
@PostMapping("/createAccountConfirm")
public String createAccountConfirm(AdminMemberVo adminMemberVo) {
    System.out.println("[AdminMemberController] createAccountConfirm()");

    return null;
}

 

전달된 관리자 정보는 서비스 객체에게 전달해야 하므로 AdminMemberService에 다음과 같이 코딩한다.

■ AdminMemberService 코드

package com.office.library.admin.member;

import org.springframework.stereotype.Service;

@Service
public class AdminMemberService {
	public int createAccountConfirm(AdminMemberVo adminMemberVo) {
		System.out.println("[AdminMemberService] createAccountConfirm()");

		return 0;
	}
}

· AdminMemberService가 스프링 컨테이너에 빈 객체로 생성되기 위해 @Service를 명시

· createAccountConfirm() : 회원가입을 처리하고 컨트롤러에서 VO객체를 받을 수 있도록 매개변수로 AdminMemberVo 타입의 adminMemberVo를 가지고 있다.

 

이제, AdminMemberService를 사용하기 위해 AdminMemberController에 객체를 생성해야한다.

· AdminMemberService는 @Service에 의해 이미 스프링 컨테이너에 빈 객체가 생성되어 있다.

· AdminMemberController는 의존 객체 자동 주입 방법으로 @Autowired를 이용해서 AdminMemberService를 멤버 필드로 선언하여 별도의 생성과정 없이 객체를 사용할 수 있다.

■ AdminMemberController 코드

@Controller
@RequestMapping("/admin/member")
public class AdminMemberController {
	
	@Autowired
	AdminMemberService adminMemberService;

 

이제 createAccountConfirm()에 adminMemberService를 사용하도록 수정해준다.

■ AdminMemberController - createAccountConfirm함수 코드

· adminMemberService의 createAccountConfirm()을 이용하고 adminMemberVo를 전달한다.

· 반환값 result는 서비스 객체로 전달된 업무가 정상적으로 처리됐는지 확인 용도 변수로, 0이하라면 '관리자 회원가입' 업무가 정상적으로 처리되지 않은 것으로 판단하고 응답 페이지를 오류 페이지(create_account_ng.jsp)로 반환된다.

// 회원가입 확인
//@RequestMapping(value="/createAccountConfirm", method=RequestMethod.POST)
@PostMapping("/createAccountConfirm")
public String createAccountConfirm(AdminMemberVo adminMemberVo) {
    System.out.println("[AdminMemberController] createAccountConfirm()");

    String nextPage = "admin/member/create_account_ok";

    int result = adminMemberService.createAccountConfirm(adminMemberVo);

    if (result <= 0)
        nextPage = "admin/member/create_account_ng";

    return nextPage;
}

 

서비스 기능 구현

· AdminMemberService는 서비스 객체로 데이터베이스와 통신하기 위해 DAO를 사용한다.

· AdminMemberDao를 스프링 컨테이너에 빈 객체로 생성하고 AdminMemberService에서 @Autowired를 이용한 의존 객체 자동 주입을 해본다.

■ AdminMemberDao 코드

· @Component를 추가해준다.

package com.office.library.admin.member;

import org.springframework.stereotype.Component;

@Component
public class AdminMemberDao {

}

■ AdminMemberService 코드

@Service
public class AdminMemberService {
	
	@Autowired
	AdminMemberDao adminMemberDao;

 

createAccountConfirm()의 업무

· '관리자 회원가입' 업무를 담당하며 두 가지 작업을 수행한다.

① 사용자가 입력한 아이디가 기존에 다른 사람이 사용하고 있는 아이디와 중복되는지 확인

- 만약 중복되는 아이디라면 회원가입은 더 이상 진행❌

- 서비스는 컨트롤러에 '회원가입 실패'를 알려줘야 한다.

② 중복된 아이디가 아니라면, DAO를 통해서 데이터베이스에 관리자 정보를 추가

- 데이터베이스에 모든 정보가 정상적으로 추가됐다면 서비스는 컨트롤러에게 '회원가입 성공'을 알려줘야 한다.

 

위와 같은 내용을 적용한 AdminMemberService의 코드는 다음과 같다.

■ AdminMemberService 코드

· AdminMemberDao관련 함수는 뒤에 추후 나온다.

package com.office.library.admin.member;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class AdminMemberService {

	final static public int ADMIN_ACCOUNT_ALREADY_EXIST = 0;	// 회원가입 실패(중복 아이디)
	final static public int ADMIN_ACCOUNT_CREATE_SUCCESS = 1;	// 회원가입 성공
	final static public int ADMIN_ACCOUNT_CREATE_FAIL = -1;		// 회원가입 실패(데이터베이스 insert 실패)

	@Autowired
	AdminMemberDao adminMemberDao;

	public int createAccountConfirm(AdminMemberVo adminMemberVo) {
		System.out.println("[AdminMemberService] createAccountConfirm()");

		boolean isMember = adminMemberDao.isAdminMember(adminMemberVo.getA_m_id());

		if (!isMember) {
			int result = adminMemberDao.insertAdminAccount(adminMemberVo);

			if (result > 0)
				return ADMIN_ACCOUNT_CREATE_SUCCESS;
			else
				return ADMIN_ACCOUNT_CREATE_FAIL;
		} else {
			return ADMIN_ACCOUNT_ALREADY_EXIST;
		}
	}
}