Jam's story
[JSP] MVC2모델을 이용한 로그인 구현 본문
로그인
MemberDTO
package domain;
public class MemberDTO {
private String mem_code;
private String mem_id;
private String mem_pw;
private String mem_gender;
private String mem_name;
private String mem_tel;
private String mem_lan;
private String adr_code;
private int check;
public MemberDTO() {
super();
}
public MemberDTO(String mem_code, String mem_id, String mem_pw, String mem_gender, String mem_name, String mem_tel,
String mem_lan, String adr_code, int check) {
super();
this.mem_code = mem_code;
this.mem_id = mem_id;
this.mem_pw = mem_pw;
this.mem_gender = mem_gender;
this.mem_name = mem_name;
this.mem_tel = mem_tel;
this.mem_lan = mem_lan;
this.adr_code = adr_code;
this.check = check;
}
public int getCheck() {
return check;
}
public void setCheck(int check) {
this.check = check;
}
public String getMem_code() {
return mem_code;
}
public void setMem_code(String mem_code) {
this.mem_code = mem_code;
}
public String getMem_id() {
return mem_id;
}
public void setMem_id(String mem_id) {
this.mem_id = mem_id;
}
public String getMem_pw() {
return mem_pw;
}
public void setMem_pw(String mem_pw) {
this.mem_pw = mem_pw;
}
public String getMem_gender() {
return mem_gender;
}
public void setMem_gender(String mem_gender) {
this.mem_gender = mem_gender;
}
public String getMem_name() {
return mem_name;
}
public void setMem_name(String mem_name) {
this.mem_name = mem_name;
}
public String getMem_tel() {
return mem_tel;
}
public void setMem_tel(String mem_tel) {
this.mem_tel = mem_tel;
}
public String getMem_lan() {
return mem_lan;
}
public void setMem_lan(String mem_lan) {
this.mem_lan = mem_lan;
}
public String getAdr_code() {
return adr_code;
}
public void setAdr_code(String adr_code) {
this.adr_code = adr_code;
}
@Override
public String toString() {
return "MemberDTO [mem_code=" + mem_code + ", mem_id=" + mem_id + ", mem_pw=" + mem_pw + ", mem_gender="
+ mem_gender + ", mem_name=" + mem_name + ", mem_tel=" + mem_tel + ", mem_lan=" + mem_lan + ", adr_code="
+ adr_code + ", check=" + check + "]";
}
}
맥딜리버리메인.jsp에서 로그인 form 부분
<div class="tab-content clearfix">
<div class="tab-pane active" id="home-tab-login">
<!-- form 태그 액션 입력하는 부분 -->
<form method="post" accept-charset="utf-8" role="form" id="form_login_masthead" name="form_login_masthead" class="panel-home-masthead-form" data-required-symbol="false" novalidate="novalidate" action="<%=contextPath%>/md/logon.do">
<fieldset class="form-credentials">
<div class="list-group textfield-list-group">
<div class="list-group-item textfield-list-group-item">
<label class="sr-only" for="form_login_masthead_username">Email</label>
<!-- id 입력하는 부분 -->
<input type="text" autocomplete="off" name="userName" id="form_login_masthead_username" class="required email list-group-form-control" placeholder="아이디" value="" aria-required="true">
</div>
<div class="list-group-item textfield-list-group-item">
<label class="sr-only" for="form_login_masthead_password">Password</label>
<!-- password 입력하는 부분 -->
<input type="password" autocomplete="off" name="passWord" id="form_login_masthead_password" class="required list-group-form-control" placeholder="비밀번호" maxlength="20" value="" aria-required="true">
</div>
</div>
<div class="checkbox">
<div class="icheckbox checked" style="position: relative;"><input type="checkbox" name="rememberMe" id="form_login_masthead_rememberme" value="true" aria-invalid="false" style="position: absolute; opacity: 0;"><ins class="iCheck-helper" style="position: absolute; top: 0%; left: 0%; display: block; width: 100%; height: 100%; margin: 0px; padding: 0px; background: rgb(255, 255, 255); border: 0px; opacity: 0;"></ins></div><input type="hidden" name="_rememberMe" value="on">
<label for="form_login_masthead_rememberme" class="checkbox-label">자동 로그인</label>
</div>
</fieldset>
<fieldset class="form-actions">
<button type="submit" class="btn btn-default btn-red btn-block btn-xl btn-submit" onclick=" dataLayer.push({ 'event':'trackEvent', 'vpv':'vpv_signin', 'eventDetails.category':'signin', 'eventDetails.action':'click', 'eventDetails.label':'signin_homepage' }); ">로그인</button>
<p class="action-forgot-password "><a class="action-link" href="/kr/forgot-password.html">비밀번호 찾기</a></p>
</fieldset>
<input type="hidden" name="csrfValue" value="f70ad1a6a64894a61de8fa67def9cec9"></form>
<div class="frament-new-user section-border-top margin-bottom-0 centered-text">
<a class="btn btn-block btn-red btn-xl" style="margin-bottom: 4px;" onclick=" dataLayer.push({ 'event':'trackEvent', 'vpv':'vpv_enter_delivery_address', 'eventDetails.category':'registration', 'eventDetails.action':'click', 'eventDetails.label':'register_homepage' }); dataLayer.push({ 'event':'trackEvent', 'eventDetails.category':'i am new', 'eventDetails.action':'click home page', 'eventDetails.label':'register now' }); " href="guest.html">
<span>회원가입</span>
</a>
<a href="#member-benefits" class="h5 text-link" data-toggle="html-popover" data-container="body" data-placement="top" data-html="true" data-content-selector="#member-benefits" data-original-title="" title="">
<span class="text-default">회원가입 하시고 다양한 혜택을 누리세요</span>
<i class="mcd icon mcd-detail"></i>
</a>
<div id="member-benefits" class="popover-wrapper popover-details">
<div class="popover-wrapper">
<h5 class="text-default">신규 계정 생성</h5>
<div class="guest-order-note" style="max-width: 300px !important; width:300px !important;">맥딜리버리 회원에게만 제공되는 할인 및 프로모션 혜택을 누리고, 지난 주문 내역을 검색하거나 즐겨찾기 메뉴를 이용해서 더 빠르고 편리하게 맥딜리버리를 이용하세요.</div>
</div>
</div>
</div>
</div>
<div class="tab-pane" id="home-tab-new">
<div class="frament-guest-order">
<div class="guest-order-header">회원가입하지 않고 주문하기</div>
<div class="guest-order-note">온라인 결제로 즉시 주문</div>
<a class="btn btn-block btn-red btn-xl" onclick="dataLayer.push( { 'event': 'trackEvent', 'eventDetails.category': 'i am new', 'eventDetails.action': 'click home page', 'eventDetails.label': 'guest order' });" href="/kr/guest_address.html">비회원 주문</a>
</div>
</div>
</div>
</div>
</div>
로그인의 form 태그는
사용자의 정보이기 때문에 보안이 필요한데, GET의 경우 그대로 노출되는 반면, POST의 경우 감쌀 수 있기 때문에
post 방식을 사용하였습니다.
action="<%=contextPath%>/md/logon.do 의 명령을 걸어놓았습니다.
<form method="post" accept-charset="utf-8" role="form" id="form_login_masthead"
name="form_login_masthead" class="panel-home-masthead-form"
data-required-symbol="false" novalidate="novalidate"
action="<%=contextPath%>/md/logon.do">
web.xml
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>controller.DispatcherServlet</servlet-class>
<init-param>
<param-name>path</param-name>
<param-value>/McPromotion/command.properties</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
properties에 의해, 디스패쳐를 통해 command.MdMainLogonHandler로 이동한다 .
/md/logon.do = command.MdMainLogonHandler
command.MdMainLogonHandler
- 멤버객체를 만들었고, 입력받은 id와 password를 getparameter를 통해 받아온다
- service클래스의 loginMember 메소드에 id와 password를 매개변수로 넘겨준다.
- 멤버객체가 반환이 된다면 - > 멤버가 있다는 것을 의미하므로 세션설정
- HttpSession session = request.getSession(true); 세션을 새로 생성한다는것, defualt가 true
- setAttribute(이름, 값)으로 세션에 값을 저장하고 세션이 유지되는동안 값을 저장한다.
- (추가해야할 것 )session.setMaxInactiveInterval( )로 세션 유지시간 값 설정하기 (기본이 30분 )
package command;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import domain.MemberDTO;
import domain.PromotionDTO;
import domain.StoreLocDTO;
import service.MainBannerService;
import service.MemberService;
import service.PrmtService;
import service.StoreLocService;
public class MdMainLogonHandler implements CommandHandler{
@Override
public String process(HttpServletRequest request, HttpServletResponse response) throws Exception {
System.out.println("do_get호출 MdMainLogonHandler");
MemberService memberService = MemberService.getInstance();
String userId = request.getParameter("userName");
String userPwd = request.getParameter("passWord");
MemberDTO memberDTO = memberService.loginMember(userId,userPwd);
if(memberDTO == null) {
System.out.println(">회원 없음 상황 발생");
return "/mcNew/md/mdmain.do?logIn=error";
}else {
System.out.println(">회원 있음 상황 발생");
System.out.println(">memberDTO 갯수"+memberDTO.getAdr_code());
HttpSession session = request.getSession(true);
session.setAttribute("Member", memberDTO);
return "/mcNew/md/mdmain.do";
}
}
}
MemberService
- 멤버에 관한 서비스(회원가입, 로그인, 수정) 를 모두 처리하는 서비스
- 성능향상을 위해 싱글톤으로 구현하였고
- dao에서 로그인현황체크를하는 dao의 logongetCheck 메소드 반환값으로
- 로그인이 된 상태라면 dto 객체를 dao.login(con, userId, userPwd)로 받아온다.
- 로그인이 안된상태라면 (0이 반환되면 ) dto=null
package service;
import java.sql.Connection;
import java.sql.SQLException;
import javax.naming.NamingException;
import com.util.ConnectionProvider;
import com.util.JdbcUtil;
import domain.MemberDTO;
import persistence.MemberDAOImpl;
public class MemberService {
private MemberService() {}
private static MemberService instance = null;
public static MemberService getInstance() {
if(instance == null) {
instance = new MemberService();
}
return instance;
}
public MemberDTO loginMember( String userId, String userPwd){
Connection con = null;
try {
con = ConnectionProvider.getConnection();
MemberDAOImpl dao =MemberDAOImpl.getInstance();
MemberDTO dto = null;
MemberDTO dtoCheck = null;
dtoCheck = dao.loginCheck(con, userId, userPwd);
if(dtoCheck.getCheck()==0) {//판별해서 0나오면 그냥 dto 널값 반환
return dto;
}else {
dto = dao.login(con, userId, userPwd);
return dto;
}
} catch (NamingException | SQLException e) {
//e.printStackTrace();
throw new RuntimeException(e);
} finally {
JdbcUtil.close(con);
}
}
}
인터페이스DAO
package persistence;
import java.sql.Connection;
import java.sql.SQLException;
import domain.MemberDTO;
public interface MemberDAO {
//로그인
MemberDTO login(Connection conn, String userId, String userPwd) throws SQLException;
//로그인 맴버 있는지 확인
MemberDTO loginCheck(Connection conn, String userId, String userPwd) throws SQLException;
//회원가입
}
MemberDAOImpl
- 회원DTO에는 주소가 아닌, 주소 코드가 들어있었고 MEM_ADR 테이블에 주소코드와 메인주소 ,상세주소, 특이사항이 들어있었기 때문에 MEMBER테이블과 MEM_ADR 테이블을 LEFT JOIN해서 주소를 가져왔습니다.
- 맥도날드는 아이디와 비밀번호, 둘중에 하나만 일치하지 않아도 아이디 혹은 비밀번호가 일치하지 않습니다. 라고 나타나기 때문에 , sql 쿼리문을 매개변수로 받은 아이디와 비밀번호를 where 조건절에 저장하여 회원의 정보를 가져오도록 하였다. 처음에 MemberDTO 객체를 null로 선언해주고 결과값이 존재한다면, MemberDTO 객체에 setter를 이용하여 값을 저장해주고 객체를 반환
package persistence;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import com.util.JdbcUtil;
import domain.MemberDTO;
public class MemberDAOImpl implements MemberDAO{
private PreparedStatement pstmt = null;
private ResultSet rs = null;
private MemberDAOImpl(){}
private static MemberDAOImpl instance = new MemberDAOImpl();
public static MemberDAOImpl getInstance() {
return instance;
}
@Override
/* 아이디랑 패스워드를 받아서, 존재하면 멤버의 정보를 가져오는 메소드 */
public MemberDTO login(Connection conn, String userId, String userPwd) throws SQLException {
System.out.println(" login()- lmpl시작");
String sql = "select mem_code, mem_id, mem_pw, mem_gender, mem_name, mem_tel, mem_lan, ad.adr_main "
+ "from member m LEFT JOIN mem_adr ad ON(m.adr_code = ad.adr_code) "
+ "where m.mem_id= ? and m.mem_pw= ? ";
System.out.println(userId);
System.out.println(userPwd);
MemberDTO dto = null;
try {
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, userId);
pstmt.setString(2, userPwd);
rs = pstmt.executeQuery();
if ( rs.next() ) {
System.out.println("sql문 찍히나?");
do {
dto = new MemberDTO();
dto.setMem_code(rs.getString("mem_code"));
dto.setMem_id(rs.getString("mem_id"));
dto.setMem_pw(rs.getString("mem_pw"));
dto.setMem_gender(rs.getString("mem_gender"));
dto.setMem_name(rs.getString("mem_name"));
dto.setMem_tel(rs.getString("mem_tel"));
dto.setMem_lan(rs.getString("mem_lan"));
dto.setAdr_code(rs.getString("adr_main"));
System.out.println(dto.toString());
} while ( rs.next() );
} //
} finally {
JdbcUtil.close(pstmt);
JdbcUtil.close(rs);
} // finally
System.out.println(dto);
return dto;
}
@Override
public MemberDTO loginCheck(Connection conn, String userId, String userPwd) throws SQLException {
System.out.println(" loginCheck()- lmpl시작");
String sql = "select count(*) "
+ "FROM MEMBER "
+ "WHERE MEM_ID = ? AND MEM_PW = ? ";
System.out.println(userId);
System.out.println(userPwd);
MemberDTO dto = null;
try {
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, userId);
pstmt.setString(2, userPwd);
rs = pstmt.executeQuery();
if ( rs.next() ) {
System.out.println("sql 세강문 찍히나?");
do {
dto = new MemberDTO();
dto.setCheck(rs.getInt(1));
//의심 부분 1
System.out.println(dto.toString());
} while ( rs.next() );
} //
} finally {
JdbcUtil.close(pstmt);
JdbcUtil.close(rs);
} // finally
System.out.println(dto);
return dto;
}
}
핸들러의 이 부분으로 로그인이 성공한다면 세션에 반환받은 memberDTO객체를 설정해주고, main 홈페이지로 반환
실패한다면 메인홈페이지의 파라미터에 error를 달아 반환
if(memberDTO == null) {
System.out.println(">회원 없음 상황 발생");
return "/mcNew/md/mdmain.do?logIn=error";
}else {
System.out.println(">회원 있음 상황 발생");
System.out.println(">memberDTO 갯수"+memberDTO.getAdr_code());
HttpSession session = request.getSession(true);
session.setAttribute("Member", memberDTO);
return "/mcNew/md/mdmain.do";
}
로그아웃
로그아웃 버튼을 누르면 ,
<a class="list-item-target" onclick=" dataLayer.push({ 'event':'logout' });
" href="md_logout.jsp">로그아웃</a>
md_logout.jsp
세션에 설정한 Member(MemberDTO 로 반환되니, getMem_id를 통해 String으로 변환 )
로그아웃경고창 띄우고
session.invalidation()으로 세션을 할당 제거
<%@page import="domain.MemberDTO"%>
<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%
//세션 자동 삭제
//세션 강제 삭제
/* String logonID = (String)session.getAttribute("mem_id"); */
String logonID = ((MemberDTO)session.getAttribute("Member")).getMem_id();
System.out.print(logonID);
%>
<script>
alert("[<%= logonID%>]님 로그아웃 하셨습니다.")
</script>
<%
session.invalidate();
%>
<script>
location.href = "/mcNew/md/mdmain.do";
</script>
'JSP' 카테고리의 다른 글
[JSP] MVC2패턴으로 회원가입 구현 (0) | 2022.07.07 |
---|---|
[JSP] 구글 맵 api (0) | 2022.07.04 |
[JSP] JSON (0) | 2022.07.01 |
[JSP] AJAX (0) | 2022.06.30 |
[JSP] EmpDeptList를 MVC패턴으로 구현 (0) | 2022.06.29 |
Comments