학원에서 일주일간 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>
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
'Learning > JSP' 카테고리의 다른 글
JSP 개인프로젝트-영어 학습 사이트 만들기 (강의목록 전체보기, 상세보기) (0) | 2020.08.18 |
---|---|
JSP 개인프로젝트-영어 학습 사이트 만들기 (관리자 기능) (0) | 2020.08.18 |
파일 전송 (0) | 2020.08.06 |
게스트북 (평가리스트) 만들기 (0) | 2020.08.06 |
로그인, 회원가입, 게시판 만들기 2 (0) | 2020.07.30 |