1. init 메서드 실행
@Override
public void init(ServletConfig config) throws ServletException {
String propertyConfig = config.getInitParameter("propertyConfig");
System.out.println("propertyConfig = " + propertyConfig);
- propertyConfig는 서블릿의 초기화 파라미터인 "command.properties"의 파일 이름을 가져온다.
- config.getInitParameter("propertyConfig")로 가져온 이 값은 나중에 프로퍼티 파일을 로드할 때 사용된다.
propertyConfig = command.properties
2. 프로퍼티 파일의 실제 경로 설정
서블릿에서 설정한 초기화 파라미터에 해당하는 파일을 찾기 위해 해당 파일의 실제 경로를 설정다.
// 서블릿이 실행되는 웹 애플리케이션의 실제 경로
String realFolder = config.getServletContext().getRealPath("/WEB-INF");
String realPath = realFolder + "/" + propertyConfig;
System.out.println("realPath = " + realPath);
- getRealPath("/WEB-INF")는 애플리케이션 내에서 WEB-INF 폴더의 실제 경로를 가져온다.
- realPath는 이 경로에 command.properties 파일 이름을 붙여 프로퍼티 파일의 실제 위치를 나타낸다.
realPath = D:\Web\workspace\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\memberMVC\WEB-INF/command.properties
3. 프로퍼티 파일 로드 및 파싱
FileInputStream fin = null;
Properties properties = new Properties();
try {
fin = new FileInputStream(realPath);
properties.load(fin);
System.out.println("properties = "+properties);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
fin.close();
} catch (IOException e) {
e.printStackTrace();
}
}
- FileInputStream으로 realPath 경로에 있는 command.properties 파일을 읽어온다.
- properties.load(fin)은 이 파일의 내용을 읽어서 properties 객체에 저장한다.
- properties 객체는 키-값 쌍으로 구성된다.
properties = {/member/writeForm.do=member.service.WriteFormService,
/member/loginForm.do=member.service.LoginFormService,
/member/checkId.do=member.service.CheckIdService}
컬렉션
1. Collection => 순서, 중복
2. Set => 순서x, 중복x
3. Map <Key,Value>
4. 프로퍼티 파일의 각 키-값 쌍을 이용해 클래스 인스턴스화
Iterator<Object> it = properties.keySet().iterator();
- properties.keySet()은 프로퍼티 파일의 모든 키를 가져온다.
- properties에 똑같은 내용이 들어가면 set으로 바꾸겠다라는 의미 !
command.properties
#요청=클래스명
/member/writeForm.do=member.service.WriteFormService
/member/writeForm.do=member.service.WriteFormService
/member/writeForm.do=member.service.WriteFormService
/member/writeForm.do=member.service.WriteFormService
/member/loginForm.do=member.service.LoginFormService
/member/checkId.do=member.service.CheckIdService
똑같은 내용을 이렇게나 많이 넣어도 똑같이 출력되는 것을 확인할 수 있다.
properties = {/member/writeForm.do=member.service.WriteFormService,
/member/loginForm.do=member.service.LoginFormService,
/member/checkId.do=member.service.CheckIdService}
똑같은 내용이 여러개 들어가버리면
set형식으로 바꿔버린다. set은 중복을 허용안하기 때문에 위에처럼 뜨는 것 !!
그리고 접근지정자 iterator를 만들어놓고 내가 하나하나의 요청과 클래스에 접근할 수 있는 것이다.
String "String" 차이점은?
String - 문자열을 처리할 수 있는 자료형
"String" - 그냥 글자라는 것
key: /member/writeForm.do
className: " member.service.WriteFormService" ----- 그냥 글씨이다. new할 수 없다.
이걸 new로 하려면 자료형으로 바꿔야한다.
하지만 얘네는 그냥 글씨이다. 우리가 원하는 건 객체형이라는 것 !!!
key: /member/ loginForm.do
className: "member.service. LoginFormService "
또 로그인할 때는 이 부분이므로 자료형이 계속해서 달라진다.
Class<?> classType = Class.forName(className);
그러므로 일단 자바의 클래스타입으로 몰아붙이는 것이다. (드라이버 로딩할 때도 써먹음)
일단 모르면 클래스타입으로 하고 Object로 생성해버리는 것
Object ob = classType.getConstructor().newInstance();
메모리에 new해서 클래스를 생성했기 때문에 갖다쓸 수 있는 것이다.
ob = member.service.WriteFormService@2a991776 --- 이렇게 객체가 되는 것이다.
category = /member/checkId.do
그래서 이렇게 요청이 들어오면 우리가 할 수 있는 것이다.
map.put(key, ob);
- 만들어진 인스턴스는 map.put(key, ob)를 통해 map에 저장된다. key는 요청 URL 패턴이고, ob는 그 요청을 처리할 서비스 객체이다.
로그인
memberLoginForm.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>로그인 페이지</title>
<style type="text/css">
body {
background-color: #FFE2FA;
font-family: 'Arial', sans-serif;
margin: 0;
padding: 0;
display: flex;
justify-content: center;
align-items: center;
height: 50vh;
flex-direction: column;
}
table {
width: 500px;
margin: auto;
background-color: white;
border-radius: 10px;
padding: 20px;
}
th {
padding: 10px 15px;
text-align: left;
color: #333;
font-size: 16px;
}
td {
padding: 10px 10px;
}
div {
color: red;
font-size: 10pt;
font-weight: bold;
margin-top: 5px;
}
input[type="text"], input[type="password"] {
width: 100%;
padding: 8px;
border: 1px solid #CCC;
border-radius: 5px;
}
input[type="button"], input[type="submit"] {
background-color: #FF9ADB;
border: none;
font-size: 16px;
padding: 10px 15px;
border-radius: 5px;
cursor: pointer;
color: white;
transition: background-color 0.3s ease;
}
input[type="button"]:hover, input[type="submit"]:hover {
background-color: #FF70C0;
}
img {
margin: 20px 0;
cursor: pointer;
}
</style>
</head>
<body>
<img src="../image/free-icon-love-4096198.png" alt="홈" width="60" height="60" onclick="location.href='../index.jsp'" />
<form id="loginForm">
<table>
<tr>
<th>아이디</th>
<td>
<input type="text" name="id" id="id" placeholder="아이디 입력" />
<div id="idDiv"></div>
</td>
</tr>
<tr>
<th>비밀번호</th>
<td>
<input type="password" name="pwd" id="pwd" placeholder="비밀번호 입력" />
<div id="pwdDiv"></div>
</td>
</tr>
<tr>
<td colspan="2" align="center">
<input type="submit" value="로그인" id="loginBtn"/>
<input type="button" value="회원가입" onclick="location.href='memberWriteForm.jsp'" />
</td>
</tr>
</table>
<!-- 쿠키 = <span></span> -->
</form>
url: '/memberMVC/member/login.do' ------ 이제는 jsp로 보내는 것이 아닌 거 확인 !!
<script src="../js/member.js"></script>
<script type="text/javascript" src="http://code.jquery.com/jquery-3.7.1.min.js"></script>
<script type="text/javascript">
$('#loginBtn').click(function(event) {
event.preventDefault(); // 기본 제출 동작 방지
$('#idDiv').empty();
$('#pwdDiv').empty();
if ($('#id').val() == '') {
$('#idDiv').html('아이디를 입력하세요.');
} else if ($('#pwd').val() == '') {
$('#pwdDiv').html('비밀번호를 입력하세요.');
} else {
$.ajax({
type: 'POST',
url: '/memberMVC/member/login.do',
data: {
'id': $('#id').val(),
'pwd': $('#pwd').val()
},
dataType: 'text', // 서버로부터 순수한 텍스트만 받음
success: function(data) {
console.log(data);
if (data.trim() === 'fail') {
alert("아이디 또는 비밀번호가 틀렸습니다.");
} else {
alert(data.trim() + "님이 로그인하였습니다.");
location.href = '../index.jsp'
}
},
error: function(e) {
console.log(e);
}
});
}
});
</script>
</body>
</html>
command.properties - /member/login.do 만들기
#요청=클래스명
#회원가입
/member/writeForm.do=member.service.WriteFormService
/member/checkId.do=member.service.CheckIdService
#로그인
/member/loginForm.do=member.service.LoginFormService
/member/login.do=member.service.LoginService
ControlServlet.java
초기화 (init 메서드)
ControlServlet의 init 메서드는 command.properties 파일을 읽어서 요청 경로와 처리 클래스를 매핑하는 Map을 초기화한다. 이 과정에서 /member/login.do 경로와 member.service.LoginService 클래스의 인스턴스도 Map에 저장된다.
// command.properties 파일에서 클래스 정보를 읽어 Map에 저장
FileInputStream fin = new FileInputStream(realPath);
Properties properties = new Properties();
properties.load(fin);
Iterator<Object> it = properties.keySet().iterator();
while (it.hasNext()) {
String key = (String) it.next(); // 요청 경로
String className = properties.getProperty(key); // 클래스 이름
Class<?> classType = Class.forName(className);
Object ob = classType.getConstructor().newInstance();
map.put(key, ob); // Map에 저장
}
요청 처리 (execute 메서드)
클라이언트가 /member/login.do URL로 요청을 보내면 doGet 또는 doPost 메서드가 호출되고,
이 메서드는 execute 메서드를 호출한다.
- 요청 url 경로 추출
String category = request.getServletPath(); // '/member/login.do'
- map에서 해당경로에 매핑된 CommandProcess 객체를 찾는다.
CommandProcess com = (CommandProcess) map.get(category); // LoginService 인스턴스
- com.requestPro(request, response) 메서드를 호출하여 요청을 처리한다.
String view = com.requestPro(request, response);
- 반환된 view 경로로 RequestDispatcher를 사용해 포워딩한다
RequestDispatcher dispatcher = request.getRequestDispatcher(view);
dispatcher.forward(request, response);
CommandProcess.java(부모)
LoginService.java (상속받음)
LoginService.java
package member.service;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import com.control.CommandProcess;
import member.bean.MemberDTO;
import member.dao.MemberDAO;
public class LoginService implements CommandProcess {
@Override
public String requestPro(HttpServletRequest request, HttpServletResponse response) throws Throwable {
//데이터
request.setCharacterEncoding("UTF-8");
String id = request.getParameter("id");
String pwd = request.getParameter("pwd");
//DB
MemberDAO memberDAO = MemberDAO.getInstance();
MemberDTO memberDTO = memberDAO.memberLogin(id, pwd);
if(memberDTO == null)
return "/member/loginFail.jsp";
else {
//세션
HttpSession session = request.getSession(); //세션생성
// 세션에 저장
session.setAttribute("memName", memberDTO.getName());
session.setAttribute("memId", id);
session.setAttribute("memEmail", memberDTO.getEmail1() + "@" + memberDTO.getEmail2());
session.setAttribute("memDTO", memberDTO);
return "/member/loginOk.jsp";
}
}
}
1. 데이터 받음 ( id, pwd )
2. DB로 간다. ( MemberDAO)
3. return 해준다. ( "/member/loginOk.jsp" "/member/loginFail.jsp" )
loginOk.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
${sessionScope.memName}
sessionScope: 세션에 저장된 값을 참조할 때 사용한다. 세션은 사용자가 웹 애플리케이션에 접속한 순간부터 접속을 종료하거나 일정 시간이 지나기 전까지 유지되는 정보를 저장하는 공간이다.
sessionScope에 저장된 memName이라는 속성 값을 가져옴
loginFail.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
fail
return시키면 반드시 ControlServelt.java로 왔다가
jsp로 가는 것이다 !!!!
그 때 오는 jsp는 위에서 우리가 return 해준 값으로 !!
마지막으로 ajax로 도착 !!!
memberLoginForm.jsp
<script src="../js/member.js"></script>
<script type="text/javascript" src="http://code.jquery.com/jquery-3.7.1.min.js"></script>
<script type="text/javascript">
$('#loginBtn').click(function(event) {
event.preventDefault(); // 기본 제출 동작 방지
$('#idDiv').empty();
$('#pwdDiv').empty();
if ($('#id').val() == '') {
$('#idDiv').html('아이디를 입력하세요.');
} else if ($('#pwd').val() == '') {
$('#pwdDiv').html('비밀번호를 입력하세요.');
} else {
$.ajax({
type: 'POST',
url: '/memberMVC/member/login.do',
data: {
'id': $('#id').val(),
'pwd': $('#pwd').val()
},
dataType: 'text', // 서버로부터 순수한 텍스트만 받음
success: function(data) {
console.log(data);
if (data.trim() === 'fail') {
alert("아이디 또는 비밀번호가 틀렸습니다.");
} else {
alert(data.trim() + "님이 로그인하였습니다.");
}
},
error: function(e) {
console.log(e);
}
});
}
});
</script>
홈화면
memberLoginForm.jsp - 로그인 성공하면 홈화면으로 이동하게하기 (여기서도 jsp로 가라 !! 하면 안된다 !!)
success: function(data) {
console.log(data);
if (data.trim() === 'fail') {
alert("아이디 또는 비밀번호가 틀렸습니다.");
} else {
alert(data.trim() + "님이 로그인하였습니다.");
location.href = '/memberMVC/index.do'
}
},
command.properties - /index.do 추가하기
#요청=클래스명
#메인화면
/index.do=main.IndexService
#회원가입
/member/writeForm.do=member.service.WriteFormService
/member/checkId.do=member.service.CheckIdService
#로그인
/member/loginForm.do=member.service.LoginFormService
/member/login.do=member.service.LoginService
Package: main
IndexService.java
package main;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.control.CommandProcess;
public class IndexService implements CommandProcess {
@Override
public String requestPro(HttpServletRequest request, HttpServletResponse response) throws Throwable {
return "/index.jsp";
}
}
index.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>메인화면</title>
<style type="text/css">
body {
background-color: #FFE2FA;
margin: 0;
display: flex;
flex-direction: column;
align-items: center;
}
h2 {
margin-top: 50px;
}
.nav-bar {
margin-top: 20px;
padding: 10px 20px;
}
.nav-bar h3 {
display: inline-block;
margin: 0 10px;
}
.nav-bar h3 a {
text-decoration: none;
font-size: 16px;
padding: 8px 12px;
color: black;
}
.nav-bar h3 a:hover {
color: gray;
}
</style>
</head>
<body>
<h2>메인화면</h2>
<div class="nav-bar">
<c:if test="${sessionScope.memId == null}">
<h3><a href="/memberMVC/member/writeForm.do">회원가입</a></h3>
<h3><a href="/memberMVC/member/loginForm.do">로그인</a></h3>
</c:if>
<c:if test="${sessionScope.memId != null}">
<h3><a href="/memberMVC/member/logout.do">로그아웃</a></h3>
<h3><a href="/memberMVC/member/updateForm.do">회원정보수정</a></h3>
</c:if>
</div>
</body>
</html>
http://localhost:8080/memberMVC/index.do
로그아웃
command.properties - 로그아웃 추가
#요청=클래스명
#메인화면
/index.do=main.IndexService
#회원가입
/member/writeForm.do=member.service.WriteFormService
/member/checkId.do=member.service.CheckIdService
#로그인
/member/loginForm.do=member.service.LoginFormService
/member/login.do=member.service.LoginService
/member/logout.do=member.service.LogoutService
LogoutService.java
package member.service;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import com.control.CommandProcess;
public class LogoutService implements CommandProcess {
@Override
public String requestPro(HttpServletRequest request, HttpServletResponse response) throws Throwable {
HttpSession session = request.getSession();// 세션 생성
session.removeAttribute("memName");
session.removeAttribute("memId");
//session.invalidate();
return "/member/memberLogout.jsp";
}
}
이미지 눌렀을 때 index.do로 가게 다 바꾸기 !!
<img src="../image/free-icon-love-4096198.png" alt="홈" width="60" height="60" onclick="location.href='/memberMVC/index.do'" />
회원가입
memberLoginForm.jsp
<tr>
<td colspan="2" align="center">
<input type="submit" value="로그인" id="loginBtn"/>
<input type="button" value="회원가입" onclick="location.href='/memberMVC/member/writeForm.do'" />
</td>
</tr>
memberWriteForm.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>회원가입 페이지</title>
<style type="text/css">
body {
background-color: #FFE2FA;
font-family: 'Arial', sans-serif;
margin: 0;
padding: 0;
display: flex;
justify-content: center;
align-items: center;
height: 80vh;
flex-direction: column;
}
table {
border-collapse: collapse;
border-radius: 10px;
background-color: white;
width: 700px;
padding: 15px;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
margin: 0 auto;
}
th, td {
padding: 8px 10px;
text-align: left;
font-size: 14px;
}
th {
color: #333;
font-size: 16px;
}
td {
color: #333;
}
div {
color: red;
font-size: 8pt;
font-weight: bold;
margin-top: 5px;
}
input[type="text"], input[type="password"], select {
margin-top: 5px;
padding: 5px;
border: 1px solid #CCC;
border-radius: 5px;
box-sizing: border-box;
}
input[type="text"][size], input[type="password"][size] {
width: auto;
}
input[type="button"], input[type="submit"], input[type="reset"] {
background-color: #FF9ADB;
border: none;
font-size: 14px;
padding: 6px 10px;
border-radius: 5px;
cursor: pointer;
color: white;
transition: background-color 0.3s ease;
margin: 4px;
}
input[type="button"]:hover, input[type="submit"]:hover, input[type="reset"]:hover {
background-color: #FF70C0;
}
img {
margin-bottom: 15px;
cursor: pointer;
display: block;
}
table td[colspan="2"] {
text-align: center;
}
</style>
</head>
<body>
<img src="../image/free-icon-love-4096198.png" alt="홈" width="60" height="60" onclick="location.href='/memberMVC/index.do'" />
<form name="memberWriteForm" method="post" action="/memberMVC/member/write.do">
<table>
<tr>
<th>이름</th>
<td>
<input type="text" name="name" id="name" placeholder="이름 입력" size="15"/>
<div id="nameDiv"></div>
</td>
</tr>
<tr>
<th>아이디</th>
<td>
<input type="text" name="id" id="id" placeholder="아이디 입력" size="15"/>
<input type="hidden" id="check" value=""/>
<div id="idDiv"></div>
</td>
</tr>
<tr>
<th>비밀번호</th>
<td>
<input type="password" name="pwd" id="pwd" placeholder="비밀번호 입력" size="25"/>
<div id="pwdDiv"></div>
</td>
</tr>
<tr>
<th>재확인</th>
<td>
<input type="password" name="repwd" id="repwd" placeholder="비밀번호 입력" size="25"/>
<div id="repwdDiv"></div>
</td>
</tr>
<tr>
<th>성별</th>
<td>
<input type="radio" name="gender" value="0" checked/> 남자
<input type="radio" name="gender" value="1"/> 여자
</td>
</tr>
<tr>
<th>이메일</th>
<td>
<input type="text" name="email1" size="15"/> @
<input type="text" name="email2" id="email2" size="15"/>
<input type="text" name="email3" id="email3" list="email3_list" size="15" oninput="change()"/>
<datalist id="email3_list">
<option value="직접입력">직접입력</option>
<option value="naver.com"></option>
<option value="gmail.com"></option>
<option value="daum.net"></option>
</datalist>
</td>
</tr>
<tr>
<th>휴대전화</th>
<td>
<select name="tel1" style="width: 70px;">
<option value="010">010</option>
<option value="011">011</option>
<option value="019">019</option>
</select>
-
<input type="text" name="tel2" size="4" maxlength="4"/>
-
<input type="text" name="tel3" size="4" maxlength="4"/>
</td>
</tr>
<tr>
<th>주소</th>
<td>
<input type="text" name="zipcode" id="zipcode" placeholder="우편번호" size="6" readonly/>
<input type="button" value="우편번호 검색" onclick="checkPost()"/><br>
<input type="text" name="addr1" id="addr1" placeholder="주소" size="50" readonly/><br>
<input type="text" name="addr2" id="addr2" placeholder="상세주소" size="50"/>
</td>
</tr>
<tr>
<td colspan="2" align="center">
<input type="submit" value="회원가입" onclick="memberWrite(event)" />
<input type="reset" value="다시입력" />
</td>
</tr>
</table>
</form>
<script src="//t1.daumcdn.net/mapjsapi/bundle/postcode/prod/postcode.v2.js"></script>
<script type="text/javascript" src="http://code.jquery.com/jquery-3.7.1.min.js"></script>
<script type="../js/member.js"></script>
</body>
</html>
<script type="text/javascript">
// 아이디 중복 검사
$(function () {
$('#id').on('focusout', function(){
$('#idDiv').empty(); // 메시지 초기화
let id = $('#id').val();
if (id === '') {
$('#idDiv').html('아이디를 입력하세요.').css('color', 'red');
return;
}
$.ajax({
type: 'post',
url: '/memberMVC/member/checkId.do',
data: {'id': id},
dataType: 'text',
success: function(data){
if (data.trim() === 'exist') {
$('#idDiv').html('이미 사용 중인 아이디입니다.').css('color', 'red');
} else {
$('#idDiv').html('사용가능한 아이디입니다.').css('color', 'green');
$('#check').val($('#id').val()); // 중복 체크가 완료된 아이디 저장
}
},
error: function(e){
console.log(e);
}
});
});
});
</script>
</body>
</html>
member.js
//회원가입
function memberWrite(e){
let isValid = true; // 유효성 검사를 통과하면 true, 아니면 false
document.getElementById("nameDiv").innerHTML = "";
document.getElementById("idDiv").innerHTML = "";
document.getElementById("pwdDiv").innerHTML = "";
document.getElementById("repwdDiv").innerHTML = "";
if(document.memberWriteForm.name.value == ""){
document.getElementById("nameDiv").innerHTML = "이름을 입력해주세요.";
e.preventDefault();
isValid = false;
}
if(document.getElementById("id").value == ""){
document.getElementById("idDiv").innerHTML = "아이디를 입력해주세요.";
e.preventDefault();
isValid = false;
}
if(document.getElementById("pwd").value == ""){
document.getElementById("pwdDiv").innerHTML = "비밀번호를 입력해주세요.";
e.preventDefault();
isValid = false;
}
if(document.getElementById("pwd").value != document.getElementById("repwd").value){
document.getElementById("repwdDiv").innerHTML = "비밀번호가 맞지 않습니다.";
e.preventDefault();
isValid = false;
}
// 중복 체크 확인
if(document.getElementById("check").value != document.getElementById("id").value){
document.getElementById("idDiv").innerHTML = "중복체크를 해주세요!";
e.preventDefault();
isValid = false;
}
if(isValid)
document.memberWriteForm.submit();
}
command.properties
#회원가입
/member/writeForm.do=member.service.WriteFormService
/member/checkId.do=member.service.CheckIdService
/member/write.do=member.service.WriteService
WriteService.java
한글처리할 필요없다. 왜? 항상 ControlServlet.java로 가서 execute에서 한글처리를 했기 때문 !
package member.service;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.control.CommandProcess;
import member.bean.MemberDTO;
import member.dao.MemberDAO;
public class WriteService implements CommandProcess {
@Override
public String requestPro(HttpServletRequest request, HttpServletResponse response) throws Throwable {
//데이터
String name = request.getParameter("name");
String id = request.getParameter("id");
String pwd = request.getParameter("pwd");
String gender = request.getParameter("gender");
String email1 = request.getParameter("email1");
String email2 = request.getParameter("email2");
String tel1 = request.getParameter("tel1");
String tel2 = request.getParameter("tel2");
String tel3 = request.getParameter("tel3");
String zipcode = request.getParameter("zipcode");
String addr1 = request.getParameter("addr1");
String addr2 = request.getParameter("addr2");
MemberDTO memberDTO = new MemberDTO();
memberDTO.setName(name);
memberDTO.setId(id);
memberDTO.setPwd(pwd);
memberDTO.setGender(gender);
memberDTO.setEmail1(email1);
memberDTO.setEmail2(email2);
memberDTO.setTel1(tel1);
memberDTO.setTel2(tel2);
memberDTO.setTel3(tel3);
memberDTO.setZipcode(zipcode);
memberDTO.setAddr1(addr1);
memberDTO.setAddr2(addr2);
//DB
MemberDAO memberDAO = MemberDAO.getInstance();
memberDAO.memberWrite(memberDTO);
return "/member/memberWrite.jsp";
}
}
memberWrite.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<script type="text/javascript">
window.onload = function(){
alert("회원가입을 축하합니다.");
location.href = "/memberMVC/index.do"
}
</script>
</body>
</html>
회원정보 수정
memberUpdateForm.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@page import="member.bean.MemberDTO"%>
<%@page import="member.dao.MemberDAO"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>회원정보 수정</title>
<style type="text/css">
body {
background-color: #FFD7F8;
font-family: 'Arial', sans-serif;
margin: 0;
padding: 0;
display: flex;
justify-content: center;
align-items: center;
height: 80vh;
flex-direction: column;
}
table {
border-collapse: collapse;
border-radius: 10px;
background-color: white;
width: 700px;
padding: 15px;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
margin: 0 auto;
}
th, td {
padding: 8px 10px;
text-align: left;
font-size: 14px;
}
th {
color: #333;
font-size: 16px;
}
td {
color: #333;
}
div {
color: red;
font-size: 8pt;
font-weight: bold;
margin-top: 5px;
}
input[type="text"], input[type="password"], select {
margin-top: 5px;
padding: 5px;
border: 1px solid #CCC;
border-radius: 5px;
box-sizing: border-box;
}
input[type="text"][size], input[type="password"][size] {
width: auto;
}
input[type="button"], input[type="submit"], input[type="reset"] {
background-color: #FF9ADB;
border: none;
font-size: 14px;
padding: 6px 10px;
border-radius: 5px;
cursor: pointer;
color: white;
transition: background-color 0.3s ease;
margin: 4px;
}
input[type="button"]:hover, input[type="submit"]:hover, input[type="reset"]:hover {
background-color: #FF70C0;
}
img {
margin-bottom: 15px;
cursor: pointer;
display: block;
}
table td[colspan="2"] {
text-align: center;
}
</style>
</head>
<body>
<img src="../image/free-icon-love-4096198.png" alt="홈" width="60" height="60" onclick="location.href='../index.jsp'" style="cursor: pointer;" />
<form name="memberUpdateForm" method="post" action="memberMVC/member/update.do">
<table>
<tr>
<th>이름</th>
<td>
<input type="text" name="name" id="name" value="${memberDTO.name}" size="15"/>
<div id="nameDiv"></div>
</td>
</tr>
<tr>
<th>아이디</th>
<td>
<input type="text" name="id" id="id" value="${memberDTO.id}" readonly />
</td>
</tr>
<tr>
<th>비밀번호</th>
<td>
<input type="password" name="pwd" id="pwd" placeholder="비밀번호 입력" size="25"/>
<div id="pwdDiv"></div>
</td>
</tr>
<tr>
<th>재확인</th>
<td>
<input type="password" name="repwd" id="repwd" placeholder="비밀번호 입력" size="25"/>
<div id="repwdDiv"></div>
</td>
</tr>
<tr>
<th>성별</th>
<td>
<input type="radio" name="gender" value="0" ${memberDTO.gender == '0' ? 'checked' : ''}/> 남자
<input type="radio" name="gender" value="1" ${memberDTO.gender == '1' ? 'checked' : ''}/> 여자
</td>
</tr>
<tr>
<th>이메일</th>
<td>
<input type="text" name="email1" value="${memberDTO.email1}" size="15"/> @
<input type="text" name="email2" id="email2" value="${memberDTO.email2}" size="15"/>
<input type="text" name="email3" id="email3" list="email3_list" size="15" oninput="change()"/>
<datalist id="email3_list">
<option value="직접입력">직접입력</option>
<option value="naver.com"></option>
<option value="gmail.com"></option>
<option value="daum.net"></option>
</datalist>
</td>
</tr>
<tr>
<th>휴대전화</th>
<td>
<select name="tel1" style="width: 70px;">
<option value="010">010</option>
<option value="011">011</option>
<option value="019">019</option>
</select>
-
<input type="text" name="tel2" value="${memberDTO.tel2}" size="4" maxlength="4"/>
-
<input type="text" name="tel3" value="${memberDTO.tel3}" size="4" maxlength="4"/>
</td>
</tr>
<tr>
<th>주소</th>
<td>
<input type="text" name="zipcode" id="zipcode" value="${memberDTO.zipcode}" placeholder="우편번호" size="6" readonly/>
<input type="button" value="우편번호 검색" onclick="checkPost()"/><br>
<input type="text" name="addr1" id="addr1" value="${memberDTO.addr1}" placeholder="주소" size="50" readonly/><br>
<input type="text" name="addr2" id="addr2" value="${memberDTO.addr2}" placeholder="상세주소" size="50"/>
</td>
</tr>
<tr>
<td colspan="2" align="center">
<input type="submit" value="회원정보수정" id="updateBtn"/>
<input type="reset" value="다시입력" onclick="location.reload()"/>
</td>
</tr>
</table>
</form>
<script type="text/javascript" src="http://code.jquery.com/jquery-3.7.1.min.js"></script>
<script src="//t1.daumcdn.net/mapjsapi/bundle/postcode/prod/postcode.v2.js"></script>
<script src="../js/member.js"></script>
<script type="text/javascript">
window.onload = function(){
document.memberUpdateForm.gender['${memberDTO.gender}'].checked = true;
document.memberUpdateForm.tel1.value = '${memberDTO.tel1}';
}
</script>
</body>
</html>
사용자가 수정한 회원 정보를 폼에 입력하고 "회원정보수정" 버튼을 클릭하면
폼 데이터는 POST 방식으로 member/update.do로 전달된다.
command.properties
#회원정보 수정
/member/updateForm.do=member.service.UpdateFormService
UpdateFormService.java
회원 정보 수정 화면으로 이동할 때 사용자의 정보를 불러오는 역할을 한다.
package member.service;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import com.control.CommandProcess;
import member.bean.MemberDTO;
import member.dao.MemberDAO;
public class UpdateFormService implements CommandProcess {
@Override
public String requestPro(HttpServletRequest request, HttpServletResponse response) throws Throwable {
// 세션에서 사용자 ID를 가져옴
HttpSession session = request.getSession();
String id = (String) session.getAttribute("memId");
// DB에서 회원 정보 가져오기
MemberDAO memberDAO = MemberDAO.getInstance();
MemberDTO memberDTO = memberDAO.getMember(id);
// 회원 정보를 request에 저장 (JSP에서 사용)
request.setAttribute("memberDTO", memberDTO);
return "/member/memberUpdateForm.jsp";
}
}
- UpdateFormService는 세션에서 사용자 ID를 가져와 데이터베이스에서 해당 회원 정보를 조회하고 이를 memberUpdateForm.jsp로 전달한다. 불러온 정보를 보고 이제 회원정보 수정을 할 수 있는 것이다 !
member.js
//회원정보 수정
$('#updateBtn').on('click', function(event){
event.preventDefault();
$('#nameDiv').empty();
$('#pwdDiv').empty();
$('#repwdDiv').empty();
let isValid = true;
// 이름 검사
if($('#name').val().trim() == ''){
$('#nameDiv').html('비밀번호를 입력하세요.').css('color', 'red');
$('#name').focus();
isValid = false;
}
// 비밀번호 검사
if($('#pwd').val().trim() == ''){
$('#pwdDiv').html('비밀번호를 입력하세요.').css('color', 'red');
$('#user_pwd').focus();
isValid = false;
}
// 비밀번호 확인 검사
if($('#repwd').val() == ''){
$('#repwdDiv').html('비밀번호 확인을 해주세요.').css('color', 'red');
$('#repwd').focus();
isValid = false;
} else if($('#pwd').val() != $('#repwd').val()){
$('#repwdDiv').html('비밀번호가 일치하지 않습니다.').css('color', 'red');
$('#repwdDiv').val('');
$('#repwdDiv').focus();
isValid = false;
}
if(isValid){
$.ajax({
type: 'post',
url: ' ${ pageContext.request.contextPath }/member/update.do',
data: $('form').serialize(),
dataType: 'text',
success: function(data){
alert('회원정보가 수정되었습니다.');
window.location.href = " ${ pageContext.request.contextPath }/index.do";
},
error: function(e){
console.log(e);
}
});
}
});
command.properties
/member/update.do=member.service.UpdateService
UpdateService.java
수정된 회원 정보를 데이터베이스에 저장하는 역할을 한다.
public class UpdateService implements CommandProcess {
@Override
public String requestPro(HttpServletRequest request, HttpServletResponse response) throws Throwable {
// 폼 데이터 가져오기
String id = request.getParameter("id");
String name = request.getParameter("name");
String pwd = request.getParameter("pwd");
String gender = request.getParameter("gender");
String email1 = request.getParameter("email1");
String email2 = request.getParameter("email2");
String tel1 = request.getParameter("tel1");
String tel2 = request.getParameter("tel2");
String tel3 = request.getParameter("tel3");
String zipcode = request.getParameter("zipcode");
String addr1 = request.getParameter("addr1");
String addr2 = request.getParameter("addr2");
// DTO에 데이터 저장
MemberDTO memberDTO = new MemberDTO();
memberDTO.setId(id);
memberDTO.setName(name);
memberDTO.setPwd(pwd);
memberDTO.setGender(gender);
memberDTO.setEmail1(email1);
memberDTO.setEmail2(email2);
memberDTO.setTel1(tel1);
memberDTO.setTel2(tel2);
memberDTO.setTel3(tel3);
memberDTO.setZipcode(zipcode);
memberDTO.setAddr1(addr1);
memberDTO.setAddr2(addr2);
// 데이터베이스 업데이트
MemberDAO memberDAO = MemberDAO.getInstance();
memberDAO.memberUpdate(memberDTO);
return "../index.jsp";
}
}
- UpdateService는 사용자가 제출한 폼 데이터를 request.getParameter()를 통해 받아 MemberDTO 객체에 저장하게된다.
- 그리고 MemberDAO를 통해 데이터베이스에 변경된 정보를 업데이트하고 완료되면 홈 화면으로 리다이렉트한다.
원래는 ~~~Service.java 파일에서 jsp파일을 ControlService.java 파일로 가서
view = com.requestPro(request, response); 여기서 받아서
//forward
RequestDispatcher dispatcher = request.getRequestDispatcher(view); //상대번지
dispatcher.forward(request, response); //제어권 넘기기
forward하는 작업을 해준다 !!
근데 여기서는 update하고 나서 따로 jsp파일로 가도 할게 없다 !
그럴 때 어떻게 하면 좋을까 !?
밑에처럼 아예 return "none"을 반환하는 것이다.
UpdataService.java
package member.service;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import com.control.CommandProcess;
import member.bean.MemberDTO;
import member.dao.MemberDAO;
public class UpdateService implements CommandProcess {
@Override
public String requestPro(HttpServletRequest request, HttpServletResponse response) throws Throwable {
String id = request.getParameter("id");
String name = request.getParameter("name");
String pwd = request.getParameter("pwd");
String gender = request.getParameter("gender");
String email1 = request.getParameter("email1");
String email2 = request.getParameter("email2");
String tel1 = request.getParameter("tel1");
String tel2 = request.getParameter("tel2");
String tel3 = request.getParameter("tel3");
String zipcode = request.getParameter("zipcode");
String addr1 = request.getParameter("addr1");
String addr2 = request.getParameter("addr2");
MemberDTO memberDTO = new MemberDTO();
memberDTO.setId(id); // 세션에서 가져온 ID 설정
memberDTO.setName(name);
memberDTO.setPwd(pwd);
memberDTO.setGender(gender);
memberDTO.setEmail1(email1);
memberDTO.setEmail2(email2);
memberDTO.setTel1(tel1);
memberDTO.setTel2(tel2);
memberDTO.setTel3(tel3);
memberDTO.setZipcode(zipcode);
memberDTO.setAddr1(addr1);
memberDTO.setAddr2(addr2);
// DB
MemberDAO memberDAO = MemberDAO.getInstance();
memberDAO.memberUpdate(memberDTO); // 회원 정보 업데이트
return "none";
}
}
그럼 이제 여기로 넘와서 view의 값이 none이면 그냥 바로 ajax로 return하게 하는 것이다.
ControlService.java
protected void execute(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println();
if(request.getMethod().equals("POST"))
request.setCharacterEncoding("UTF-8");
//http://localhost:8080/memberMVC/member/writeForm.do
//요청한 URL에서 "/member/writeForm.do" 뜯어오기
String category = request.getServletPath(); //'/member/checkId.do' 추출
System.out.println("category = " + category);
// Map을 이용하여 Key에 해당하는 값을 꺼내온다. member.service.WriteFormService
CommandProcess com = (CommandProcess)map.get(category); // 자식 = (자식)부모 // CheckIdService를 찾음
String view = null;
try {
view = com.requestPro(request, response);
} catch (Throwable e) {
e.printStackTrace();
}
if(view.equals("none"))
return;
//forward
RequestDispatcher dispatcher = request.getRequestDispatcher(view); //상대번지
dispatcher.forward(request, response); //제어권 넘기기
}
여기서 return하게 되면
member.js
if(isValid){
$.ajax({
type: 'post',
url: '/memberMVC/member/update.do',
data: $('form').serialize(),
dataType: 'text',
success: function(data){
alert('회원정보가 수정되었습니다.');
window.location.href = "../index.jsp";
},
error: function(e){
console.log(e);
}
});
}
여기로 와서 회원정보가 수정되었습니다가 뜨는 것 !!
/memberMVC 이런식으로 다 적게되면 나중에 프로젝트명이 바뀌면 굉장히 번거로워진다.
그러므로 밑에처럼 하면 좋다 !!
index.jsp
<body>
<h2>메인화면</h2>
Context = ${pageContext.request.getContextPath()}
<div class="nav-bar">
<c:if test="${sessionScope.memId == null}">
<h3><a href="/memberMVC/member/writeForm.do">회원가입</a></h3>
<h3><a href="/memberMVC/member/loginForm.do">로그인</a></h3>
</c:if>
<c:if test="${sessionScope.memId != null}">
<h3><a href="/memberMVC/member/logout.do">로그아웃</a></h3>
<h3><a href="/memberMVC/member/updateForm.do">회원정보수정</a></h3>
</c:if>
</div>
</body>
Context = ${pageContext.request.getContextPath()}
Context = ${ pageContext.request.contextPath }
두 개 다 같은 코드
이유 : 메소드 호출시 접두사 set/get를 생략 할 수 있다 메소드명을 변수명처럼 사용 할 수 있다
<c:set var="context" value="${ pageContext.request.contextPath }"></c:set>
<body>
<h2>메인화면</h2>
Context = ${ pageContext.request.contextPath }
<c:set var="context" value="${ pageContext.request.contextPath }"></c:set>
<div class="nav-bar">
<c:if test="${sessionScope.memId == null}">
<h3><a href="${context}/member/writeForm.do">회원가입</a></h3>
<h3><a href="${context}/member/loginForm.do">로그인</a></h3>
</c:if>
<c:if test="${sessionScope.memId != null}">
<h3><a href="${context}/member/logout.do">로그아웃</a></h3>
<h3><a href="${context}/member/updateForm.do">회원정보수정</a></h3>
</c:if>
</div>
</body>
memberWriteForm.jsp
<form name="memberWriteForm" method="post" action="${ pageContext.request.contextPath }/member/write.do">
근데 약간 저걸로 다 바꿨을 때 오류나는 부분들이 있다. 얘를 들면 member.js는 바꾸면 얘가 인식을 못한다.
그 부분은 바꾸면 안될듯~?
'JSP & Servlet' 카테고리의 다른 글
DAY 54 - ProjectMVC 목록 / 상세보기 (2024.09.20) (0) | 2024.09.20 |
---|---|
DAY 53 - projectMVC - 로그인 / 로그아웃 / 회원가입 / 회원정보수정 / 글쓰기 / 글목록 (0) | 2024.09.19 |
DAY 51 - EL_JSTL ( 2024.09.12 ) (0) | 2024.09.12 |
DAY 51 - MVC ( 2024.09.12 ) (2) | 2024.09.12 |
DAY 50 - EL_JSTL ( 2024.09.11 ) (4) | 2024.09.11 |