WEB/JSTL
[JSTL] 로그인, 회원가입, 로그아웃
hvoon
2022. 9. 9. 20:28
sql로 회원 정보 입력
create table member(
name varchar2(30),
userid varchar2(30),
pwd varchar2(30),
email varchar2(30),
phone varchar2(30),
admin number(1) default 0, --0: 일반 사용자, 1:관리자
primary key(userid)
);
insert into member values('이소미','somi','1234','gmd@anver.com',
'010-1234-1234',0);
insert into member values('하상오','sang12','1234','h12@naver.com',
'010-5555-6666',0);
insert into member values('김윤승','light','1234','yoon1@daum.net',
'010-9999-1111',0);
update member set admin=1 where userid='somi';

회원가입 시 필요한 변수 Dto 생성
package com.jstl.dto;
public class MemberDto {
private String name;
private String userid;
private String pwd;
private String email;
private String phone;
private int admin;
public void setAdmin(int admin) {
this.admin = admin;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getUserid() {
return userid;
}
public void setUserid(String userid) {
this.userid = userid;
}
public String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public int getAdmin() {
return admin;
}
}
로그인 시작 화면
1. 주소창 외부로 노출되지 않게 LoginForm 불러오기
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>index.jsp</title>
</head>
<body>
<%
// response.sendRedirect("member/loginForm.jsp");
response.sendRedirect("login.do");
// Servlet을 거쳐서 forwarding된 페이지는 외부로 노출되지 않음
%>
</body>
</html>
2. Servlet 생성


package com.jstl.member;
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 javax.servlet.http.HttpSession;
import com.jstl.dao.MemberDao;
import com.jstl.dto.MemberDto;
@WebServlet("/login.do")
public class LoginServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public LoginServlet() {
super();
}
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException,
IOException {
// get으로 호출됐을 때 실행
String url="member/loginForm.jsp";
HttpSession session=request.getSession();
if(session.getAttribute("loginUser")!=null) {
//만약 현재 누군가 로그인해 있다면
url="main.do";
}
RequestDispatcher rd
=request.getRequestDispatcher("member/loginForm.jsp");
rd.forward(request, response);
}
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException,
IOException {
// post로 호출됐을 때 실행
request.setCharacterEncoding("UTF-8");
// 전달된 아이디 비번 변수에 저장
String userid=request.getParameter("userid");
String pwd=request.getParameter("pwd");
// 전달된 userid로 member 테이블에서 회원을 검색하고,
// 검색결과에 따라 pwd와 비교해서 정상 로그인 여부를 결정함
// 로그인이 실패했을 때를 대비해서 포워딩할 경로를 먼저 설정함
String url="member/loginForm.jsp";
// Dao의 회원검색 메서드를 호출하기 위해서 객체를 생성함
MemberDao mdao=MemberDao.getInstance();
// 전달된 userid를 전달인수로 하는
// getMember() 메서드를 호출해서
// 해당 회원의 정보를 dto에 담아서 리턴받음
MemberDto mdto=mdao.getMember(userid);
if(mdto==null) {// 아이디가 없음
request.setAttribute("message", "아이디가 없습니다");
} else if(mdto.getPwd()==null) {// 저장된 비밀번호가 null
request.setAttribute("message",
"(시스템 오류1)관리자에게 문의");
} else if(!mdto.getPwd().equals(pwd)) {// 비밀번호 틀림
request.setAttribute("message", "비밀번호가 틀립니다");
} else if(mdto.getPwd().equals(pwd)) {// 정상 로그인
url="main.do";
// 로그인한 사람의 정보(mdto)를 session에 저장함.
// session은 각 페이지에 있는 request 객체에서
// 얻어 쓸 수 있는데 jsp 페이지에서는
// 그 페이지가 갖고 있는 request 안의 session을
// 별도 작업없이 그냥 사용해도 되지만,
// servlet에서는 request를 전달인수로 받아서
// 매개변수에 저장된 형태로 쓰기 때문에
// 별도로 추출하는 동작이 필요함
HttpSession session=request.getSession();
// request와 response는 jsp 페이지에 있는 객체임
session.setAttribute("loginUser", mdto);
} else {// 어쨌든 로그인 실패
request.setAttribute("message",
"(시스템 오류2)관리자에게 문의");
}
RequestDispatcher dp
=request.getRequestDispatcher(url);
dp.forward(request, response);
}
}
3) loginForm
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>loginForm.jsp</title>
<script type="text/javascript">
function loginCheck(){
if(document.frm.userid.value==""){
alert("아이디를 입력하세요");
document.frm.userid.focus();
return false;
}
if(document.frm.pwd.value==""){
alert("비밀번호를 입력하세요");
document.frm.pwd.focus();
return false;
}
return true;
}
</script>
</head>
<body>
<form action="login.do" method="post" name="frm">
<table>
<tr><td> 아이디 </td><td>
<input type="text" name="userid"></td></tr>
<tr><td> 암 호 </td><td>
<input type="password" name="pwd"></td></tr>
<tr><td colspan="2" align="center">
<input type="submit" value="로그인"
onClick="return loginCheck()">
<!--
loginCheck() 함수의 리턴값을 다시 form에 리턴해줌으로써 폼의 동작이
action에 지정한 곳으로 계속 이동을 진행할지 아니면 멈출지를 결정함
-->
<input type="reset" value="취소">
<input type="button" value="회원가입"
onClick="location.href='join.do'">
</td></tr>
<tr><td colspan="2">${message}</td></tr>
</table>
</form>
</body>
</html>


로그인 후
1. MainServlet
package com.jstl.member;
import java.io.IOException;
import java.util.ArrayList;
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.jstl.dao.MemberDao;
import com.jstl.dto.MemberDto;
@WebServlet("/main.do")
public class MainServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public MainServlet() {
super();
}
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException,
IOException {
request.setCharacterEncoding("UTF-8");
String url="member/main.jsp"; // 원래 목적지
HttpSession session=request.getSession();
// 로그인한 사람이 없으면 목적지를 loginForm으로 변경
if(session.getAttribute("loginUser")==null)
url="member/loginForm.jsp";
// 전체 회원의 정보를 조회해서 ArrayList에 담고,
// main.jsp로 포워딩함
MemberDao mdao=MemberDao.getInstance();
ArrayList<MemberDto> list=mdao.selectMember();
// 조회된 내용을 request에 저장
request.setAttribute("mList", list);
RequestDispatcher dp=request.getRequestDispatcher(url);
dp.forward(request, response);
}
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException,
IOException {
doGet(request, response);
}
}
2. main.jsp
<%@ 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">
<title>main.jsp</title>
<script type="text/javascript">
function withDrawConfirm(){
var bool=confirm('정말로 탈퇴하시겠습니까?');
if(bool){
location.href="withdraw.do?userid="+"${loginUser.userid}";
} else{
return;
}
}
</script>
</head>
<body>
<table>
<tr><td>${loginUser.name}(${loginUser.userid })님이 로그인하셨습니다
</td></tr>
<tr><td> email: ${loginUser.email }</td></tr>
<tr><td> 전화번호: ${loginUser.phone }</td></tr>
<tr><td><input type="button" value="로그아웃"
onClick="location.href='logout.do'"/>
<!--
어떤 태그이든 onClick 속성을 써서 페이지 이동을 하고자 한다면
위와 같이 location.href를 onClick 속성에 지정해서 이동.
onClick 속성에는 페이지 이동 기능이 없기 때문에 페이지만 쓴다고
이동하지 않으니 반드시 location.href로 페이지를 지정해야함.
-->
<input type="button" value="회원정보변경"
onClick="location.href='update.do?userid=${loginUser.userid }'">
<%--EL 또는 JSP의 <%=%>는 문자 데이터들 사이에 껴들어서
조합문자데이터 구성 가능함 --%>
<input type="button" value="회원 탈퇴"
onClick="withDrawConfirm();">
</td></tr>
</table>
<br><br>
<c:if test="${loginUser.admin==1 }">
<table width="800" bgcolor="black" cellspacing="1">
<tr bgcolor="white"><th>아이디</th><th>이름</th>
<th>전화번호</th><th>이메일</th>
<th>등급</th><th>등급변경</th>
</tr>
<c:forEach items="${mList}" var="member">
<tr bgcolor="white" align="center">
<td>${member.userid}</td><td>${member.name}</td>
<td>${member.phone}</td><td>${member.email}</td>
<td>
<c:choose>
<c:when test="${member.admin==1}">관리자
</c:when>
<c:otherwise>일반사용자</c:otherwise>
</c:choose>
</td>
<td>
<c:choose>
<c:when test="${member.admin==1}">
<input type="button" value="일반으로 변경"
onClick="location.href='editadmin.do?userid=${member.userid }&admin=${member.admin }'"/>
</c:when>
<c:otherwise>
<input type="button" value="관리자로 변경"
onClick="location.href='editadmin.do?userid=${member.userid }&admin=${member.admin }'"/>
</c:otherwise>
</c:choose>
</td>
</tr>
</c:forEach>
</table>
</c:if>
</body>
</html>
회원가입 하기
1. JoinServlet
package com.jstl.member;
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.jstl.dao.MemberDao;
import com.jstl.dto.MemberDto;
@WebServlet("/join.do")
public class JoinServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public JoinServlet() {
super();
}
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException,
IOException {
RequestDispatcher dp
=request.getRequestDispatcher("member/joinForm.jsp");
dp.forward(request, response);
}
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException,
IOException {
request.setCharacterEncoding("UTF-8");
MemberDao mdao=MemberDao.getInstance();
MemberDto mdto=new MemberDto();
mdto.setName(request.getParameter("name"));
mdto.setUserid(request.getParameter("userid"));
mdto.setPwd(request.getParameter("pwd"));
mdto.setEmail(request.getParameter("email"));
mdto.setPhone(request.getParameter("phone"));
mdto.setAdmin(Integer.parseInt(request.getParameter("admin")));
int result=mdao.insertMember(mdto);
if(result==1) request.setAttribute("message", "회원가입 완료");
else request.setAttribute("message", "회원가입 실패");
RequestDispatcher dp
=request.getRequestDispatcher("member/loginForm.jsp");
dp.forward(request, response);
}
}
2. joinForm
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>joinForm.jsp</title>
<script type="text/javascript">
function idCheck(){
if(document.frm.userid.value==''){
alert('아이디를 먼저 입력하고 중복체크 버튼을 클릭하세요');
document.frm.userid.focus();
return;
}
var inputid=document.frm.userid.value;
// 사용하고자 입력한 아이디를 변수에 저장
var opt=
'toolbar=no, menubar=no, scrollbars=yes, width=800px, height=200px';
window.open('idcheck.do?userid='+inputid, 'id-check', opt);
// 서블릿을 호출하고 포웓딩된 페이지가 팝업창에 열릴 예정임.
// 그래서 첫번째 요소는 서블릿의 urlmapping 이름을 씀.
// 서블릿 호출 시 파라미터를 위와 같이 호출되는 주소 뒤에
// ? 함께 전달 가능
}
function joinCheck(){
if(document.frm.name.value==''){
alert('이름은 필수입력 사항입니다');
document.frm.name.focus();
return false;
}
if(document.frm.userid.value.length==0){
alert('아이디는 필수입력 사항입니다');
document.frm.userid.focus();
return false;
}
if(document.frm.pwd.value.length==0){
alert('비밀번호는 필수입력 사항입니다');
document.frm.pwd.focus();
return false;
}
if(document.frm.userid.value!=document.frm.reid.value){
alert("아이디 중복체크를 하지 않았습니다");
document.frm.userid.focus();
return false;
}
if(document.frm.pwd.value!=document.frm.pwd_check.value){
alert("비밀번호 확인이 일치하지 않습니다");
document.frm.pwd.focus();
return false;
}
return true;
}
</script>
</head>
<body>
<h2>회원 가입</h2> '*' 표시 항목은 필수 입력 항목입니다.
<form action="join.do" method="post" name="frm">
<table>
<tr><td>이름</td><td><input type="text" name="name"
size="20"> *</td></tr>
<tr><td>아이디</td><td><input type="text" name="userid"
size="20"> *
<input type="button" value="중복 체크"
onClick="idCheck();"/>
<input type="hidden" name="reid" value=""></td>
<!--
reid 태그는 아이디 중복체크 후 사용 가능한 아이디라면
사용할 아이디를 reid 태그의 value값으로 저장함.
그리고 나중에 현재 아이디가 입력된 userid와
reid 값이 같은 값인지 보고 중복 체크 여부를 체크함
-->
</tr>
<tr><td>비밀번호</td><td><input type="password" name="pwd"
size="20"> *</td></tr>
<tr><td>비밀번호 확인</td>
<td><input type="password" name="pwd_check"
size="20"> *</td></tr>
<tr><td>이메일</td><td><input type="text" name="email"
size="20"> </td></tr>
<tr><td>전화번호</td><td><input type="text" name="phone"
size="20"> </td></tr>
<tr><td>등급</td><td><input type="radio" name="admin"
value="0" checked="checked">일반회원
<input type="radio" name="admin" value="1">관리자</td>
</tr>
<tr><td colspan="2" align="center">
<input type="submit" value="회원 가입"
onClick="return joinCheck()"/>
<input type="reset" value="취소"></td></tr>
</table>
</form>
</body>
</html>


ID 중복 체크
1. idCheckServlet
package com.jstl.member;
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.jstl.dao.MemberDao;
@WebServlet("/idcheck.do")
public class idCheckServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public idCheckServlet() {
super();
}
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException,
IOException {
request.setCharacterEncoding("UTF-8");
String userid=request.getParameter("userid");
MemberDao mdao=MemberDao.getInstance();
int result=mdao.confirmId(userid);
// userid가 사용가능한지 판단하는 메서드 호출
//MemberDto mdto=mdao.getMember(userid);
//if(mdto==null) result=-1;
//else result=1;
// 리턴값이 1이면 사용불가능(다른 사람이 사용중)
// -1이면 사용 가능
request.setAttribute("result", result);
request.setAttribute("userid", userid);
// 중복체크한 아이디와 결과를 모두 리퀘스트에 담음
RequestDispatcher dp=
request.getRequestDispatcher("member/idcheck.jsp");
dp.forward(request, response);
}
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException,
IOException {
doGet(request, response);
}
}
2. idcheckform
<%@ 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">
<title>idcheck.jsp</title>
<script type="text/javascript">
function idok(id){
opener.document.frm.userid.value=id;
opener.document.frm.reid.value=id;
self.close();
}
</script>
</head>
<body>
<c:choose>
<c:when test="${result==1}">
${userid}는 이미 사용 중인 아이디입니다.
<script type="text/javascript">
// 팝업창을 오픈한 주체: opener
opener.document.frm.userid.value='';
opener.document.frm.reid.value='';
</script>
</c:when>
<c:otherwise>
${userid}는 사용 가능한 아이디입니다.
<input type="button" value="사용할게요"
onClick="idok('${userid}');">
</c:otherwise>
</c:choose>
<br><br>
<!-- 첫번째 체크한 아이디 말고 다른 아이디를 체크하기 위한 폼 -->
<form action="idcheck.do" method="get" name="frm">
아이디: <input type="text" name="userid" value="${userid}">
<input type="submit" value="중복 체크">
</form>
</body>
</html>

Dao
package com.jstl.dao;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import com.jstl.dto.MemberDto;
public class MemberDao {
private MemberDao() {}
private static MemberDao itc=new MemberDao();
public static MemberDao getInstance() {return itc;}
// 연결 객체 준비
Connection con=null;
PreparedStatement pstmt=null;
ResultSet rs=null;
// 연결 정보
String driver="oracle.jdbc.OracleDriver";
String url="jdbc:oracle:thin:@localhost:1521:xe";
String id="scott";
String pwd= "tiger";
private Connection getConnection() {
Connection con=null;
try{
Class.forName(driver);
con=DriverManager.getConnection(url, id, pwd);
} catch(ClassNotFoundException e){e.printStackTrace();
} catch(SQLException e){e.printStackTrace();}
return con;
}
private void close() {
try{
if(rs!=null) rs.close();
if(pstmt!=null) pstmt.close();
if(con!=null) con.close();
} catch(Exception e){e.printStackTrace();}
}
public MemberDto getMember(String userid) {
MemberDto mdto=null;
// 전달된 userid로 검색해서 해당 회원이 없으면
// null 값이 리턴되도록
// dto의 초기값 null임
// 조회된 회원이 있는 경우에 new MemberDto가 실행되어
// 회원의 각 정보를 저장하고 리턴함
String sql="select*from member where userid=?";
con=getConnection();
try {
pstmt=con.prepareStatement(sql);
pstmt.setString(1, userid);
rs=pstmt.executeQuery();
if(rs.next()) {
mdto=new MemberDto();
mdto.setName(rs.getString("name"));
mdto.setUserid(rs.getString("userid"));
mdto.setPwd(rs.getString("pwd"));
mdto.setEmail(rs.getString("email"));
mdto.setPhone(rs.getString("phone"));
mdto.setAdmin(rs.getInt("admin"));
}
} catch(SQLException e){e.printStackTrace();
} finally{close();}
return mdto;
}
public ArrayList<MemberDto> selectMember() {
ArrayList<MemberDto> list=new ArrayList<>();
String sql="select*from member";
con=getConnection();
try {
pstmt=con.prepareStatement(sql);
rs=pstmt.executeQuery();
while(rs.next()) {
MemberDto mdto=new MemberDto();
mdto.setUserid(rs.getString("userid"));
mdto.setName(rs.getString("name"));
mdto.setPwd(rs.getString("pwd"));
mdto.setPhone(rs.getString("phone"));
mdto.setEmail(rs.getString("email"));
mdto.setAdmin(rs.getInt("admin"));
list.add(mdto);
// 검색결과를 리스트에 레코드단위로 추가
}
} catch(SQLException e){e.printStackTrace();
} finally{close();}
return list;
}
public int confirmId(String userid) {
int result=-1;
String sql="select*from member where userid=?";
con=getConnection();
try {
pstmt=con.prepareStatement(sql);
pstmt.setString(1,userid);
rs=pstmt.executeQuery();
if(rs.next()) result=1;
} catch (SQLException e) { e.printStackTrace();
} finally {close();}
return result;
}
public int insertMember(MemberDto mdto) {
int result=0;
String sql="insert into member(userid,name,pwd,phone,email,"
+ "admin) values(?,?,?,?,?,?)";
con=getConnection();
try {
pstmt=con.prepareStatement(sql);
pstmt.setString(1,mdto.getUserid());
pstmt.setString(2,mdto.getName());
pstmt.setString(3,mdto.getPwd());
pstmt.setString(4,mdto.getPhone());
pstmt.setString(5,mdto.getEmail());
pstmt.setInt(6,mdto.getAdmin());
result=pstmt.executeUpdate();
} catch (SQLException e) { e.printStackTrace();
} finally {close();}
return result;
}
}


로그아웃(LogoutServlet)
package com.jstl.member;
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 javax.servlet.http.HttpSession;
@WebServlet("/logout.do")
public class LogoutServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public LogoutServlet() {
super();
}
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException,
IOException {
HttpSession session=request.getSession();
session.invalidate();
RequestDispatcher rd=request.getRequestDispatcher("member/loginForm.jsp");
rd.forward(request, response);
}
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException,
IOException {
doGet(request, response);
}
}