학원에서 일주일간 JSP로 개인프로젝트를 했다. 주제는 영어 학습 사이트. 벤치마킹?할 사이트는 캠블리로 선정했다.

강의 구매와 튜터 매칭 시스템, 캘린더에서 날짜를 골라서 수업을 듣는 기능은 구현하지 못했다. 

 

https://www.cambly.com/english?lang=ko

 

캠블리 Cambly, 전화영어 그 이상의 영어회화어플

Cambly에서 원어민 튜터와 언제 어디서나 간편하게 영어 수업을 받으시고, 영어 회화의 자신감을 키우세요!

www.cambly.com

 

내가 구현한 기능은

1. 회원가입, 로그인

2. 관리자 강의입력, 관리자 강의목록 보기 및 수정, 회원정보 수정

3. 사용자 강의목록 전체보기, 상세보기

4. 수강후기 게시판 전체보기, 회원 게시글 입력

5. 수강후기 게시글 상세보기 및 수정 삭제, 댓글 입력 삭제

6. 강의 장바구니 담기 및 삭제

 


사이트 디자인은 부트스트랩 템플릿을 이용했다.

https://startbootstrap.com/themes/landing-page/

 

Landing Page - Free Bootstrap 4 Landing Page Theme

A responsive Bootstrap 4 landing page theme by Start Bootstrap. All Start Bootstrap templates are free to download and open source.

startbootstrap.com

이외에도 다른 무료 부트스트랩 템플릿에 있는 사진들을 활용했다. 이 템플릿의 이름인 Wiser을 따와서 사이트 이름을 Wiser로 했다.

https://colorlib.com/wp/template/wiser/

 

Wiser - Free LMS Website Template Design 2020 - Colorlib

Wiser is a top-notch, responsive and free LMS website template design for establishing a striking online learning platform.

colorlib.com


DB구성 (Oracle SQL Developer)과 Table명

1. 회원과 관련된 DB -> WMember

2. 강의와 관련된 DB -> WClass

3. 수강후기 게시판 DB -> WBoard

4. 수강후기 댓글 DB -> WComment_Board

5. 장바구니 DB -> WCart

 

  • WClass의 기본키인 classnum(강의번호. 시퀀스로 부여)은 WBoard의 외래키로 참조된다. 
  • 수강후기 게시글에 해당하는 댓글 리스트를 보여줘야 하므로, WBoard의 기본키인 NUM은 WComment_Board의 BNUM 외래키로 참조된다.
  • (WMember의 classnum, WCart의 classnum또한 WClass의 classnum을 참조해야하는데 제약조건 설정을 빼먹었다..)

 

 


회원 DB관련 DTO (WmemberDTO.java)

 

package com.wmember.model;

public class WMemberDTO {
	private int num;
	private String name;
	private String userid;
	private String pwd;
	private String email;
	
	private int postcode;
	private String address;
	private String detailAddress;
	private String extraAddress;
	
	private String classnum;
	private String reg_date;
	private int admin;
	
	public int getPostcode() {
		return postcode;
	}
	public void setPostcode(int postcode) {
		this.postcode = postcode;
	}
	public String getAddress() {
		return address == null ? "" : address.trim();
	}
	public void setAddress(String address) {
		this.address = address;
	}
	public String getDetailAddress() {
		return detailAddress == null ? "" : detailAddress.trim();
	}
	public void setDetailAddress(String detailAddress) {
		this.detailAddress = detailAddress;
	}
	public String getExtraAddress() {
		return extraAddress == null ? "" : extraAddress.trim();
	}
	public void setExtraAddress(String extraAddress) {
		this.extraAddress = extraAddress;
	}
	public int getNum() {
		return num;
	}
	public void setNum(int num) {
		this.num = num;
	}
	public String getName() {
		return name == null ? "" : name.trim();
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getUserid() {
		return userid == null ? "" : userid.trim();
	}
	public void setUserid(String userid) {
		this.userid = userid;
	}
	public String getPwd() {
		return pwd == null ? "" : pwd.trim();
	}
	public void setPwd(String pwd) {
		this.pwd = pwd;
	}
	public String getEmail() {
		return email == null ? "" : email.trim();
	}
	public void setEmail(String email) {
		this.email = email;
	}
	public String getClassnum() {
		return classnum == null ? "" : classnum.trim();
	}
	public void setClassnum(String classnum) {
		this.classnum = classnum;
	}
	public String getReg_date() {
		return reg_date == null ? "" : reg_date.trim();
	}
	public void setReg_date(String reg_date) {
		this.reg_date = reg_date;
	}
	public int getAdmin() {
		return admin;
	}
	public void setAdmin(int admin) {
		this.admin = admin;
	}
}

 


첫 시작화면에 해당하는 index.jsp

 

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ include file="/include/header.jsp" %>
<style>
h1{
	text-align: left;
}
</style>
  <!-- Masthead -->
  <header class="masthead text-white text-center">
    <div class="overlay"></div>
       
        <div class="mainLine">
          <span style="width: 100%; height: 200px;"></span>
          <h1 style="color:#484848; font-size: 48px; line-height: 1.5em;">생생한 원어민 화상영어,<br/> 지금바로 시작하세요!</h1>
        </div>
       
          <form>
            <div class="form-row" style="width: 30%;">
              <div class="col-12 col-md-9 mb-2 mb-md-0">
                <input type="email" class="form-control form-control-lg" placeholder="  이메일 주소">
              </div>
              <div class="col-12 col-md-3">
                <input type="button" value="회원가입" class="btn btn-block btn-lg btn-primary" onclick="location.href='/Tutoring/member/insert'">
              </div>
            </div>
          </form>
  </header>

  <!-- Icons Grid -->
  <section class="features-icons bg-light text-center">
    <div class="container">
      <div class="row">
        <div class="col-lg-4">
          <div class="features-icons-item mx-auto mb-5 mb-lg-0 mb-lg-3">
            <div class="features-icons-icon d-flex">
              <i class="icon-screen-desktop m-auto text-primary"></i>
            </div>
            <h3>수업</h3>
            <p class="lead mb-0">튜터와 만들어 나가는 유연한 학습 스케쥴</p>
          </div>
        </div>
        <div class="col-lg-4">
          <div class="features-icons-item mx-auto mb-5 mb-lg-0 mb-lg-3">
            <div class="features-icons-icon d-flex">
              <i class="icon-layers m-auto text-primary"></i>
            </div>
            <h3>커리큘럼</h3>
            <p class="lead mb-0">내 레벨에 맞춰 선택해 더욱 체계적인 수업 진행</p>
          </div>
        </div>
        <div class="col-lg-4">
          <div class="features-icons-item mx-auto mb-0 mb-lg-3">
            <div class="features-icons-icon d-flex">
              <i class="icon-check m-auto text-primary"></i>
            </div>
            <h3>수료증</h3>
            <p class="lead mb-0">10시간 이상 수업 시, 캠블리 수료증 발급</p>
          </div>
        </div>
      </div>
    </div>
  </section>

  <!-- Testimonials -->
  <section class="testimonials text-center bg-light">
    <div class="container">
      <h2 class="mb-5">유학 없이도 유창하게 영어로 말할 수 있어요!</h2>
      <div class="row">
        <div class="col-lg-4">
          <div class="testimonial-item mx-auto mb-5 mb-lg-0">
            <img class="img-fluid rounded-circle mb-3" src="img/testimonials-1.jpg" alt="">
            <h5>Margaret E.</h5>
            <p class="font-weight-light mb-0">"I have been teaching English for 3 years. I am very patient, kind and I love to learn about new cultures and your thoughts about life."</p>
          </div>
        </div>
        <div class="col-lg-4">
          <div class="testimonial-item mx-auto mb-5 mb-lg-0">
            <img class="img-fluid rounded-circle mb-3" src="img/testimonials-2.jpg" alt="">
            <h5>Fred S.</h5>
            <p class="font-weight-light mb-0">"A conversationalist, I have worked internationally in business (operations, sales, training and HR) and am also licensed to teach scuba!"</p>
          </div>
        </div>
        <div class="col-lg-4">
          <div class="testimonial-item mx-auto mb-5 mb-lg-0">
            <img class="img-fluid rounded-circle mb-3" src="img/testimonials-3.jpg" alt="">
            <h5>Sarah W.</h5>
            <p class="font-weight-light mb-0">"I own and run a small business, am easy to speak to and hold a TEFL qualification. I look forward to meeting you!"</p>
          </div>
        </div>
      </div>
    </div>
  </section>

  <!-- Call to Action -->
  <section class="call-to-action text-white text-center">
    <div class="overlay"></div>
    <div class="container">
      <div class="row">
        <div class="col-xl-9 mx-auto">
          <h2 class="mb-4">내게 꼭 맞는 튜터를 찾아보세요</h2>
        </div>
        <div class="col-md-10 col-lg-8 col-xl-7 mx-auto">
          <form>
            <div class="form-row">
              <div class="col-12 col-md-9 mb-2 mb-md-0">
                <input type="email" class="form-control form-control-lg" placeholder="  이메일 주소">
              </div>
              <div class="col-12 col-md-3">
                 <input type="button" value="회원가입" class="btn btn-block btn-lg btn-primary" onclick="location.href='/Tutoring/member/insert'">
              </div>
            </div>
          </form>
        </div>
      </div>
    </div>
  </section>
<%@ include file="/include/footer.jsp" %>

 


header.jsp와 footer.jsp를 나누어서 페이지마다 포함시켰다.

 

header.jsp

 

sessionScope.userid 값이 비어있으면 로그인/회원가입 링크가, 

sessionScope.admin 값이 1이면 관리자이므로 관리자/로그아웃 링크가,

sessionScope.admin 값이 0이면 일반회원이므로 내계정/로그아웃 링크가 나타난다.

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>    
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
  <meta name="description" content="">
  <meta name="author" content="">
  <title>영어 수업</title>
  <!-- Bootstrap core CSS -->
  <link href="/Tutoring/vendor/bootstrap/css/bootstrap.css"  rel="stylesheet">
  <!-- Custom fonts for this template -->
  <link href="/Tutoring/vendor/fontawesome-free/css/all.css" rel="stylesheet">
  <link href="/Tutoring/vendor/simple-line-icons/css/simple-line-icons.css"  rel="stylesheet" type="text/css">
  <link href="https://fonts.googleapis.com/css?family=Lato:300,400,700,300italic,400italic,700italic"  rel="stylesheet" type="text/css">
  <!-- Custom styles for this template -->
  <link href="/Tutoring/css/landing-page.css" rel="stylesheet">
  
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
  


</head>
<body>

  <!-- Navigation -->
  <nav class="navbar navbar-light bg-light static-top">
    <div class="container">
         <a class="navbar-brand" href="/Tutoring/index.jsp">Wiser English</a>
         <a class="navbar-nav" href="/Tutoring/include/about.jsp">와이저</a>
         <a class="navbar-nav" href="/Tutoring/class/courseList">과정</a>
    </div>
      <c:choose>
     	<c:when test="${empty sessionScope.userid}">
		    <ul class="navbar-nav">
		      <li class="nav-item">
		      	<a class="btn btn-gray" href="/Tutoring/member/login">로그인</a>
			    <a class="btn btn-primary" href="/Tutoring/member/insert">회원가입</a>
		      </li>
		  	</ul>
    	</c:when>
    	<c:when test="${sessionScope.admin==1}">
		    <ul class="navbar-nav">
		      <li class="nav-item">
		      	<a class="btn btn-gray" href="/Tutoring/member/Adminview">관리자</a>
			    <a class="btn btn-primary" href="/Tutoring/member/logout">로그아웃</a>
		      </li>
		  	</ul>
    	</c:when>
    	<c:when test="${sessionScope.admin==0}">
    		<ul class="navbar-nav">
		      <li class="nav-item">
		      	<a class="btn btn-gray" href="/Tutoring/member/view">내계정</a>
			    <a class="btn btn-info" href="/Tutoring/member/logout">로그아웃</a>
		      </li>
		  	</ul>
    	</c:when>
     </c:choose>  
  	
  </nav>
  
<!-- Bootstrap core JavaScript -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="/Tutoring/vendor/jquery/jquery.js"></script>
<script src="/Tutoring/vendor/bootstrap/js/bootstrap.bundle.js"></script>

header.jsp 실행화면

 

sessionScope.userid, sessionScope.admin 값은 로그인을 할때 받아온다.

 


WMemberLoginAction.java

(로그인 링크에 해당하는 "/Tutoring/member/login" 경로의 서블릿이다.)

 

package com.wmember.action;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import com.wmember.model.WMemberDAO;

/**
 * Servlet implementation class WMemberLoginAction
 */
@WebServlet("/member/login")
public class WMemberLoginAction extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public WMemberLoginAction() {
        super();
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		RequestDispatcher rd=request.getRequestDispatcher("login.jsp");
		rd.forward(request, response);
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.setCharacterEncoding("utf-8");
		String userid=request.getParameter("userid");
		String pwd=request.getParameter("pwd");
		WMemberDAO dao=WMemberDAO.getInstance();
		int flag=dao.loginCheck(userid, pwd);
		int admin=-1;
		if(flag==0 || flag==1) {
			HttpSession session=request.getSession();
			session.setAttribute("userid", userid);
			admin=flag;
			session.setAttribute("admin", admin);
		}
		response.setContentType("text/html;charset=utf-8");
		PrintWriter out = response.getWriter(); 
		out.println(flag);
	}

}

 

  • a링크를 통해 이동하였으므로 doGet에서 처리된다. RequestDispatcher의 forward 메소드로 login.jsp로 이동한다.

  • login.jsp에서 ajax의 post방식으로 다시 WMemberLoginAction.java로 돌아온다. post방식이므로 doPost내에서 처리된다.
  • 파라미터 값으로 받아온 userid와 pwd를 들고 WMemberDAO.java내의 loginCheck 메소드를 실행한다. 
  • 리턴값을 flag에 담는다. 
  • 변수 admin을 -1값을 입력하여 선언한다. admin은 관리자, 일반회원을 구분하는 변수이다. 우선 모든 이용자는 일반회원으로 가입되고, DB에서 admin값에 1을 부여하여 관리자를 선별한다. 
  • loginCheck메소드에 의해 flag값이 0 또는 1로 저장되면 session값으로 userid를 받아온다. admin은 flag값과 통일되고 마찬가지로 session값으로 admin을 받는다.
  • out객체를 통해 flag값을 내보낸다.

 

<WMemberDAO.java 중 loginCheck메소드>

 

//디비셋팅
	private static WMemberDAO instance=new WMemberDAO();
	public static WMemberDAO getInstance() {
		return instance;
	}
	private Connection getConnection() throws Exception{
		Context initCtx=new InitialContext();
		Context envCtx=(Context) initCtx.lookup("java:comp/env");
		DataSource ds=(DataSource) envCtx.lookup("jdbc/wiser"); //context.xml의 name을 jdbc/member로 바꾸기
		return ds.getConnection();
	}
    
    
//로그인체크 (비밀번호 오류: 2, 회원아님: -1, 회원: 0, 관리자: 1)
	public int loginCheck(String userid, String pwd) {
		Connection con=null;
		Statement st=null;
		ResultSet rs=null;
		int flag=-1;
		try {
			con=getConnection();
			String sql="select pwd, admin from wmember where userid='"+userid+"'";
			st=con.createStatement();
			rs=st.executeQuery(sql);
			if(rs.next()) { //id 맞음
				if(rs.getString("pwd").equals(pwd)) { //비번 일치
					flag=rs.getInt("admin");
				}else { //비번 오류
					flag=2;
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			closeConnection(con, st, rs);
		}
		return flag;
	}
    
//닫기 closeConnection
	private void closeConnection(Connection con, PreparedStatement ps) {
		try {
			if(ps!=null) ps.close();
			if(con!=null) con.close();
		} catch (SQLException e) {
			e.printStackTrace();
		} 
	}
	private void closeConnection(Connection con, Statement st, ResultSet rs) {
		try {
			if(st!=null) st.close();
			if(con!=null) con.close();
			if(rs!=null) rs.close();
		} catch (SQLException e) {
			e.printStackTrace();
		} 
	}

 


login.jsp

  • 아이디와 패스워드를 입력하는 폼이 있다.
  • 자바스크립트 태그 안에서 공백을 확인하고 ajax를 이용하여 /Tutoring/member/login으로 다시 이동한다.
  • loginCheck을 끝내고 돌아온 flag값을 switch문을 통해 구분하고 alert창을 띄운 후 각각에 맞게 링크가 이동된다.

 

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ include file="../include/header.jsp" %>
<style>
img{
	display: inline-block;
	float: right;
}
#loginFrm{
	width: 60%;
	height: auto;
	position: absolute;
	top: 50%;
	left: 35%;
	transform: translate(-50%, -50%);
}
</style>
<div class="container-fluid">
	<div class="row">
		<div class="col-md-8">
			<img src="/Tutoring/img/banner.png" alt="loginImage">
		</div>
		<div class="col-md-4">
				<form action="login" method="post" id="loginFrm">
				  <div class="form-group">
				    <label for="userid">아이디</label>
				    <input type="text" class="form-control" id="userid" placeholder="Enter id" name="userid">
				  </div>
				  <div class="form-group">
				    <label for="pwd">패스워드</label>
				    <input type="password" class="form-control" id="pwd" placeholder="Enter password" name="pwd">
				  </div>
				  <button type="button" id="loginBtn" class="btn btn-primary" style="width: 100%;">로그인</button>
				</form>
		</div>
</div>
<script>
$("#loginBtn").click(function(){
	if($("#userid").val()==""){
		alert("아이디를 입력하세요");
		$("#userid").focus();
		return false;
	}
	if($("#pwd").val()==""){
		alert("암호를 입력하세요");
		$("#pwd").focus();
		return false;
	}
	$.ajax({
		type : "post",
		url  : "login",
		data : {"userid":$("#userid").val(), "pwd":$("#pwd").val()},
		success : function(value){
			switch(value.trim()){
			case "0" : alert("로그인 성공"); location.href="/Tutoring/index.jsp"; break;
			case "1" : alert("관리자 로그인"); location.href="/Tutoring/member/Adminview"; break;
			case "2" : alert("비밀번호 오류"); break;
			case "-1": alert("회원이 아닙니다"); location.href="/Tutoring/member/insert"; break;
			default: alert(value.trim());
			}
		},
		error: function(e){
			alert("error:"+e);
		}
	})
})//loginBtn
</script>
<%@ include file="../include/footer.jsp" %>

 

  • 로그인에 성공했을경우 시작페이지로 이동하고 
  • 관리자로 로그인했을경우 관리자 페이지로 이동,
  • 회원이 아니라고 판단되었을 경우 회원가입페이지로 이동한다.

WMemberInsert.java (/Tutoring/member/insert)

(회원가입 링크에 해당하는 "/Tutoring/member/insert" 경로의 서블릿이다.)

package com.wmember.action;

import java.io.IOException;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.wmember.model.WMemberDAO;
import com.wmember.model.WMemberDTO;

/**
 * Servlet implementation class WMemberInsertAction
 */
@WebServlet("/member/insert")
public class WMemberInsertAction extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public WMemberInsertAction() {
        super();
        // TODO Auto-generated constructor stub
    }

/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    RequestDispatcher rd=request.getRequestDispatcher("join.jsp");
    rd.forward(request, response);
}

/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    request.setCharacterEncoding("utf-8");
    WMemberDAO dao=WMemberDAO.getInstance();
    WMemberDTO member=new WMemberDTO();
    member.setName(request.getParameter("name"));
    member.setUserid(request.getParameter("userid"));
    member.setPwd(request.getParameter("pwd"));
    member.setEmail(request.getParameter("email"));
    member.setPostcode(Integer.parseInt(request.getParameter("sample6_postcode")));
    member.setAddress(request.getParameter("sample6_address"));
    member.setDetailAddress(request.getParameter("sample6_detailAddress"));
    member.setExtraAddress(request.getParameter("sample6_extraAddress"));

    dao.memberInsert(member);
    response.sendRedirect("login");
    }

}

 

  • a링크를 통해 이동하였으므로 doGet에서 처리된다. RequestDispatcher의 forward 메소드로 join.jsp로 이동한다.

 

 


join.jsp

  • 아이디, 아이디중복확인 버튼, 이름, 비밀번호, 비밀번호 확인, 우편번호 입력 폼이다.
  • 우편번호는 다음 우편번호 API를 이용하였고 예제 자바스크립트 코드를 그대로 복사 붙여넣기했다. 
  • 회원정보 수정할때 주소를 다시 고칠 것을 생각하여 WMemberDB에서 우편번호, 주소, 상세주소, 여분의 주소 컬럼을 만들었다. 
  • 아이디 중복과 여백확인등은 member.js 파일을 만들어서 그곳에서 처리하였다.
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ include file="../include/header.jsp" %>
<script src="/Tutoring/js/member.js"></script>
<style>
img{
	display: inline-block;
	float: right;
}
#frm{
	width: 60%;
	height: auto;
	position: absolute;
	top: 50%;
	left: 35%;
	transform: translate(-50%, -50%);
}
.button{
	text-align: center;
	margin: 0 auto;
	padding: 20px;
}
</style>
<div class="container-fluid">
	<div class="row">
		<div class="col-md-7">
			<img src="/Tutoring/img/join.jpg" alt="joinImage">
		</div>
		<div class="col-md-5">
			<form action="insert" method="post" id="frm">
			  <br/><br/>
			  <div class="input-group mb-3">
			    <div class="input-group-prepend">
			      <span class="input-group-text">아이디</span>
			    </div>
			      <input type="text" class="form-control" id="userid" name="userid" readonly="readonly" size=20>
			    <div class="col align-self-end" >
			          <button  type="button"  id="idcheckBtn"  class="btn btn-primary">중복확인</button>
			   	</div>
			  </div>
			  <br/>
			   
			  <div class="input-group mb-3">
			    <div class="input-group-prepend">
			      <span class="input-group-text">이름</span>
			    </div>
			      <input type="text" class="form-control" id="name" name="name">
			  </div>
			  <br/>
			  
			  <div class="input-group mb-3">
			    <div class="input-group-prepend">
			      <span class="input-group-text">비밀번호</span>
			    </div>
			    <input type="password" class="form-control" placeholder="6자리 이상" id="pwd" name="pwd">
			    <input type="password" class="form-control" placeholder="비밀번호 확인" id="pwd_check" name="pwd_check">
			  </div>
			  <br/>
			  
			  <div class="input-group mb-3">
			    <div class="input-group-prepend">
			      <span class="input-group-text">이메일</span>
			    </div>
			      <input type="text" class="form-control" id="email" name="email" placeholder="email@email.com">
			  </div>
			  <br/>
			    
			  <div class="input-group mb-3">
			    <div class="input-group-prepend">
			      <span class="input-group-text">우편번호</span>
			    </div>
			      <input type="text" id="sample6_postcode" name="sample6_postcode" readonly="readonly" class="form-control">
			    <div class="col align-self-end" >
			      <input type="button" onclick="sample6_execDaumPostcode()" value="우편번호" class="btn btn-primary"><br>
			   	</div>
			  </div>
			  <br/>  
			
			  <div class="input-group mb-3">
			    <div class="input-group-prepend">
			      <span class="input-group-text">주소</span>
			    </div>
			    <input type="text" id="sample6_address" name="sample6_address" placeholder="주소" class="form-control"><br>
			  </div>
			
			  <div class="input-group mb-3">
				<input type="text" id="sample6_detailAddress" name="sample6_detailAddress" placeholder="상세주소" class="form-control">
				<input type="text" id="sample6_extraAddress" name="sample6_extraAddress" placeholder="참고항목" class="form-control">
			  </div>
			    
			  <div class="button">
			 	  <input type="reset" class="btn btn-gray" value="취소">
			 	  <button  id="send"  class="btn btn-primary">회원가입</button>
			  </div>
	  </div>
	</form>
	</div>
</div>
<%@ include file="../include/footer.jsp" %>
<script src="https://t1.daumcdn.net/mapjsapi/bundle/postcode/prod/postcode.v2.js"></script>
<script>
    function sample6_execDaumPostcode() {
        new daum.Postcode({
            oncomplete: function(data) {
                // 팝업에서 검색결과 항목을 클릭했을때 실행할 코드를 작성하는 부분.

                // 각 주소의 노출 규칙에 따라 주소를 조합한다.
                // 내려오는 변수가 값이 없는 경우엔 공백('')값을 가지므로, 이를 참고하여 분기 한다.
                var addr = ''; // 주소 변수
                var extraAddr = ''; // 참고항목 변수

                //사용자가 선택한 주소 타입에 따라 해당 주소 값을 가져온다.
                if (data.userSelectedType === 'R') { // 사용자가 도로명 주소를 선택했을 경우
                    addr = data.roadAddress;
                } else { // 사용자가 지번 주소를 선택했을 경우(J)
                    addr = data.jibunAddress;
                }

                // 사용자가 선택한 주소가 도로명 타입일때 참고항목을 조합한다.
                if(data.userSelectedType === 'R'){
                    // 법정동명이 있을 경우 추가한다. (법정리는 제외)
                    // 법정동의 경우 마지막 문자가 "동/로/가"로 끝난다.
                    if(data.bname !== '' && /[동|로|가]$/g.test(data.bname)){
                        extraAddr += data.bname;
                    }
                    // 건물명이 있고, 공동주택일 경우 추가한다.
                    if(data.buildingName !== '' && data.apartment === 'Y'){
                        extraAddr += (extraAddr !== '' ? ', ' + data.buildingName : data.buildingName);
                    }
                    // 표시할 참고항목이 있을 경우, 괄호까지 추가한 최종 문자열을 만든다.
                    if(extraAddr !== ''){
                        extraAddr = ' (' + extraAddr + ')';
                    }
                    // 조합된 참고항목을 해당 필드에 넣는다.
                    document.getElementById("sample6_extraAddress").value = extraAddr;
                
                } else {
                    document.getElementById("sample6_extraAddress").value = '';
                }

                // 우편번호와 주소 정보를 해당 필드에 넣는다.
                document.getElementById('sample6_postcode').value = data.zonecode;
                document.getElementById("sample6_address").value = addr;
                // 커서를 상세주소 필드로 이동한다.
                document.getElementById("sample6_detailAddress").focus();
            }
        }).open();
    }
</script>

 


 

 

http://postcode.map.daum.net/guide

 

Daum 우편번호 서비스

우편번호 검색과 도로명 주소 입력 기능을 너무 간단하게 적용할 수 있는 방법. Daum 우편번호 서비스를 이용해보세요. 어느 사이트에서나 무료로 제약없이 사용 가능하답니다.

postcode.map.daum.net

 


member.js

email의 경우 정규식을 입력하여 정확하게 입력하도록 유도했다.

id중복확인 버튼을 누를 경우 idCheck.jsp 새 창이 뜬다. 

var reg_email = /^([0-9a-zA-Z_\.-]+)@([0-9a-zA-Z_-]+)(\.[0-9a-zA-Z_-]+){1,2}$/;


$(document).ready(function(){
	$("#send").click(function(){
		//아이디가 공백일때
		if($("#userid").val()==""){
			alert("아이디를 입력하세요");
			$("#userid").focus();
			return false;
		}
		//암호가 공백일때
		if($("#pwd").val()==""){
			alert("암호를 입력하세요");
			$("#pwd").focus();
			return false;
		}
		//암호확인이 공백일때
		if($("#pwd_check").val()==""){
			alert("암호확인 필수");
			$("#pwd_check").focus();
			return false;
		}
		//암호 일치확인
		if($("#pwd").val()!=$("#pwd_check").val()){
			alert("암호 불일치");
			$("#pwd_check").focus();
			return false;
		}
		if($("#pwd").val().length<6){
	        alert("비밀번호는 6글자 이상이어야 합니다.");
	        pw1.value="";
	        pw1.focus();
	        return false;
	    }
		//이름이 공백일때
		if($("#name").val()==""){
			alert("이름을 입력하세요");
			return false;
		}
		//이메일이 공백일때
		if($("#email").val()==""){
			alert("이메일을 입력하세요");
			return false;
		}
		//이메일 양식
		if(!$("#email").val().match(reg_email)){
			alert("이메일을 정확하게 입력하세요");
			$("#email").focus();
			return false;
		}
		$("#frm").submit();
	})//send
	
	//아이디 중복체크 버튼
	$("#idcheckBtn").click(function(){
		window.open("idCheck", "", "width=600 height=500")
	}); //idcheckBtn
	
	//id중복확인 사용버튼
	$("#useBtn").click(function(){
		if($("#userid").val()==""){
			alert("아이디를 입력하세요");
			$("#userid").focus();
			return false;
		}
		$.ajax({
			type: "post",
			url : "idCheck",
			data: {"userid":$("#userid").val()},
			success: function(val){
				if(val.trim()=="yes"){
					alert("사용가능한 아이디");
					$(opener.document).find("#userid").val($("#userid").val());
					self.close();
				}else if(val.trim()=="no"){
					alert("중복된 아이디");
					$("#userid").val("");
				}
			},
			error: function(e){
				alert("error:"+e);
			}
		}); //ajax
	}) //useBtn
	
});//document

 

  • ajax를 이용하여 post방식으로 WMemberIdCheck.java 서블릿으로 이동하고 받아온 값에 따라 alert창을 다르게 띄운다. 사용가능한 아이디일 경우 회원가입 창의 userid칸에 그 값이 담긴다.

 


idCheck.jsp

  • member.js에서 팝업된 화면으로 id입력 칸과 사용여부 버튼이 있다.
  • member.js를 포함하고 있으므로 사용여부 버튼 ("#useBtn")을 누를경우 WMemberIdCheck.java로 이동한다.
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js"></script>
<script src="/Tutoring/js/member.js"></script>

<div class="container">
    <div class="row">
	    <div class="col">
	      <br/>
	      <input type="text" class="form-control" id="userid" placeholder="Enter id" name="userid" >
	    </div>
      	<div class="col align-self-end" >
          <button  type="button"  id="useBtn"  class="btn btn-primary">사용여부</button>
   		</div>
    </div>
</div>

 

 


WMemberIdCheck.java

(아이디 중복확인 체크 서블릿)

package com.wmember.action;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.wmember.model.WMemberDAO;

/**
 * Servlet implementation class MemberIdCheck
 */
@WebServlet("/member/idCheck")
public class WMemberIdCheck extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public WMemberIdCheck() {
        super();
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		RequestDispatcher rd=request.getRequestDispatcher("idCheck.jsp");
		rd.forward(request, response);
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.setCharacterEncoding("utf-8");
		String userid=request.getParameter("userid");
		WMemberDAO dao=WMemberDAO.getInstance();
		String flag=dao.idCheck(userid);
		response.setContentType("text/html;charset=utf-8");
		PrintWriter out=response.getWriter();                     
		out.println(flag);
	}
}

 

  • ajax에서 post방식으로 넘어왔으므로 doPost내에서 실행된다. 파라미터 값으로 userid를 받아와서 WMemberDAO.java의 idCheck메소드로 이동한다.
  • flag 값을 받아와서 다시 idCheck.jsp로 이동

 

<WMemberDAO.java의 idCheck메소드>

 

//아이디 중복확인 사용하기 버튼
	public String idCheck(String userid) {
		Connection con=null;
		Statement st=null;
		ResultSet rs=null;
		String flag="yes"; //사용가능
		try {
			con=getConnection();
			String sql="select * from wmember where userid='"+userid+"'";
			st=con.createStatement();
			rs=st.executeQuery(sql);
			if(rs.next()) {
				flag="no"; //사용불가능
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			closeConnection(con, st, rs);
		}
		return flag;
	}

 


다시 회원가입 join.jsp로 돌아와서.. 버튼 id가 send, form action의 경로는 insert, 방식은 post임을 확인할 수 있다.

 

<form action="insert" method="post" id="frm">
<button  id="send"  class="btn btn-primary">회원가입</button>

 

member.js에서 공백확인 등을 거치고 폼이 submint 되면 insert서블릿으로 이동한다.

 

$("#frm").submit();

 


WMemberInsertAction.java

(앞에서 본 회원가입 서블릿으로 doPost부분만 가져왔다.)

 

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.setCharacterEncoding("utf-8");
		WMemberDAO dao=WMemberDAO.getInstance();
		WMemberDTO member=new WMemberDTO();
		member.setName(request.getParameter("name"));
		member.setUserid(request.getParameter("userid"));
		member.setPwd(request.getParameter("pwd"));
		member.setEmail(request.getParameter("email"));
		member.setPostcode(Integer.parseInt(request.getParameter("sample6_postcode")));
		member.setAddress(request.getParameter("sample6_address"));
		member.setDetailAddress(request.getParameter("sample6_detailAddress"));
		member.setExtraAddress(request.getParameter("sample6_extraAddress"));
		
		dao.memberInsert(member);
		response.sendRedirect("login");
	}

 

 


<WMemberDAO.java의 memberInsert메소드>

 

//회원가입
	public void memberInsert(WMemberDTO vo) {
		Connection con=null;
		PreparedStatement ps=null;
		
		try {
			con=getConnection();
			String sql="INSERT INTO wmember(num, name, userid, pwd, email, address, "
					+ "classnum, reg_date, postcode, detailaddress, extraaddress, admin)"
					+ "VALUES(wmember_seq.nextval,?,?,?,?,?,0,sysdate,?,?,?,0)";
			ps=con.prepareStatement(sql);
			ps.setString(1, vo.getName());
			ps.setString(2, vo.getUserid());
			ps.setString(3, vo.getPwd());
			ps.setString(4, vo.getEmail());
			ps.setString(5, vo.getAddress());
			ps.setInt(6, vo.getPostcode());
			ps.setString(7, vo.getDetailAddress());
			ps.setString(8, vo.getExtraAddress());
			ps.executeUpdate();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			closeConnection(con, ps);
		}
	}

 

 

 


https://github.com/kkj0712/JspProject_Tutoring

 

kkj0712/JspProject_Tutoring

Contribute to kkj0712/JspProject_Tutoring development by creating an account on GitHub.

github.com

 

+ Recent posts