쌍용교육 -JSP수업 57~58일차 - ch06_mvcPageMVC(6)
ActionMap.properties 이름을 member.properties로 변경한다.
Web.xml 수정
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" id="WebApp_ID" version="4.0">
<display-name>ch06_mvcPage</display-name>
<servlet>
<servlet-name>DispatcherServlet</servlet-name>
<servlet-class>kr.controller.DispatcherServlet</servlet-class>
<init-param>
<param-name>propertiesPath</param-name>
<param-value>/WEB-INF/member.properties</param-value>
</init-param>
<multipart-config>
<max-file-size>5242880</max-file-size><!-- 5M 5메가 -->
<max-request-size>52428800</max-request-size><!-- 여러개 파일을 한번에 request(요청)할 때 쓰기 때문에 0을 하나 더 붙여서 50M로 늘림 -->
</multipart-config>
</servlet>
<servlet-mapping>
<servlet-name>DispatcherServlet</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.jsp</welcome-file>
<welcome-file>default.htm</welcome-file>
</welcome-file-list>
</web-app>
<수정내용>이름
<param-value>/WEB-INF/member.properties</param-value>
전달 파일 크기
<multipart-config>
<max-file-size>5242880</max-file-size><!-- 5M 5메가 -->
<max-request-size>52428800</max-request-size><!-- 여러개 파일을 한번에 request(요청)할 때 쓰기 때문에 0을 하나 더 붙여서 50M로 늘림 -->
</multipart-config>
kr.main.action => MainAction.java
경로만 먼저 반환해주고 추후 수정할 계획
package kr.main.action;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import kr.controller.Action;
public class MainAction implements Action{
@Override
public String execute(HttpServletRequest request, HttpServletResponse response) throws Exception {
//JSP 경로반환
return "/WEB-INF/views/main/main.jsp";
}
}
WEB-INF/views/main=>main.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>메인</title>
<link rel="stylesheet" href="${pageContext.request.contextPath}/css/style.css" type="text/css">
</head>
<body>
<div class="page-main">
<jsp:include page="/WEB-INF/views/common/header.jsp"/>
<div class="content-main">
<h4>메인 페이지</h4>
</div>
</div>
</body>
</html>
common => header.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!-- header 시작 -->
<div id="main_logo">
<h1 class="align-center">
<a href="${pageContext.request.contextPath}/main/main.do">회원제 게시판</a> <!-- 경로가 달라질 수 있는걸 방지하기위해 uri방식으로 명시한다. -->
</h1>
</div>
<div id="main_nav">
<ul>
<li>
<a href="${pageContext.request.contextPath}/board/list.do">게시판</a>
</li>
<c:if test="${!empty user_num}"><!-- empty는 null이거나 비어있다는 뜻 !를 쓰면서 비어있지않을 경우로 명시 -->
<li>
<a href="${pageContext.request.contextPath}/member/myPage.do">MY페이지</a>
</li>
</c:if>
<c:if test="${!empty user_num && !empty user_photo}"> <!-- 사진이 등록되어 있을 때 -->
<li class="menu-profile">
<img src="${pageContext.request.contextPath}/upload/${user_photo}" width="25" height="25" class="my-photo">
</li>
</c:if>
<c:if test="${!empty user_num && empty user_photo}"><!-- 사진이 등록이 되어있지 않을 때 -->
<li class="menu-profile">
<img src="${pageContext.request.contextPath}/images/face.png" width="25" height="25" class="my-photo">
</li>
</c:if>
<c:if test="${!empty user_num}"> <!-- 로그인이 되어있을 떄 -->
<li class="menu-logout">
[<span>${user_id}</span>]
<a href="${pageContext.request.contextPath}/member/logout.do">로그아웃</a>
</li>
</c:if>
<c:if test="${empty user_num}"><!-- 로그인이 안되어있을 떄 -->
<li>
<a href="${pageContext.request.contextPath}/member/registerUserForm.do">회원가입</a>
</li>
<li>
<a href="${pageContext.request.contextPath}/member/loginForm.do">로그인</a>
</li>
</c:if>
</ul>
</div>
<!-- header 끝 -->
WEB-INF => index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
response.sendRedirect(request.getContextPath()+"/main/main.do");
%>
css/style.css 수정
@charset "UTF-8";
/* 전체 레이아웃
----------------------*/
body{
width:960px;
margin:0 auto;
background:#E6E6E6;
}
a:link{
text-decoration:none;
color:#000000;
}
a:visited{
text-decoration:none;
color:#000000;
}
a:hover{
text-decoration:none;
color:#6C6C6C;
}
/* 페이지 레이아웃
----------------------*/
.page-main{
background:#FFFFFF;
margin:40px 0;
border-radius:5px;
box-shadow:0 2px 6px rgba(100,100,100,0.3);
min-height:650px;
}
.content-main{
padding:10px 20px;
}
/* 공통 메시지
----------------------*/
.result-display{
width:400px;
height:200px;
margin:50px auto;
border:1px solid #000;
display:flex;
align-items:center;/*세로 정렬*/
justify-content:center;/*가로 정렬*/
}
/* 공통 정렬
----------------------*/
.align-center{
text-align:center;
}
.align-right{
text-align:right;
}
/* 메뉴
----------------------*/
#main_logo{
padding-top:20px;
}
#main_nav{
padding:2px 10px 20px 10px;
height:20px;
background-color:#C1BFBF;
}
#main_nav ul{
list-style:none;
margin:0;
padding:0;
}
#main_nav ul li{
display:inline-block;
width:100px;
text-align:center;
vertical-align:middle;
padding-top:8px;
}
#main_nav ul li img.my-photo{
vertical-align:middle;
}
#main_nav ul li.menu-logout{
width:150px;
text-align:left;
}
/*목록*/
table{
width:100%;
border:1px solid #000;
border-collapse:collapse;
margin-top:5px;
}
table td, table th{
border:1px solid #000;
padding:5px;
}
/*등록, 수정폼*/
form{
width:500px;
margin:0 auto;
border:1px solid #000;
padding:10px 10px 10px 30px;
}
ul{
list-style:none;
}
label{
width:100px;
float:left; /*태그를 왼쪽으로 정렬*/
}
wepapp/sql =>table.sql
--회원관리
create table zmember(
mem_num number not null,
id varchar2(12) unique not null,
auth number(1) default 2 not null, --회원등급:0은탈퇴,1은정지회원,2는일반회원,9는관리자
constraint zmember_pk primary key (mem_num)
);
--회원상세
create table zmember_detail(
mem_num number not null,
name varchar2(30) not null,
passwd varchar2(12) not null,
phone varchar2(15) not null,
email varchar2(50) not null,
zipcode varchar2(5) not null,
address1 varchar2(90) not null,
address2 varchar2(90) not null,
photo varchar2(400),
reg_date date default sysdate not null,
modify_date date,
constraint zmember_detail_pk primary key (mem_num),
constraint zmember_detail_fk foreign key (mem_num)
references zmember (mem_num)
);
create sequence zmember_seq;
kr.member.vo => MemberVO
package kr.member.vo;
import java.sql.Date;
public class MemberVO {
private int mem_num; //회원 번호
private String id; //아이디
private int auth; //회원등급
private String name; //이름
private String passwd; //비밀번호
private String phone; //전화번호
private String email; //이메일
private String zipcode; //우편번호
private String address1; //주소
private String address2; //상세 주소
private String photo; //프로필사진
private Date reg_date; //가입일
private Date modify_date; //수정일
//비밀번호 일치 여부 체크
public boolean isCheckedPassword(String userPasswd) {
//회원등급(auth) :0탈퇴회원,1정지회원,2일반회원,9관리자
if(auth > 1 && passwd.equals(userPasswd)) {
return true;
}
return false;
}
public int getMem_num() {
return mem_num;
}
public void setMem_num(int mem_num) {
this.mem_num = mem_num;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public int getAuth() {
return auth;
}
public void setAuth(int auth) {
this.auth = auth;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPasswd() {
return passwd;
}
public void setPasswd(String passwd) {
this.passwd = passwd;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getZipcode() {
return zipcode;
}
public void setZipcode(String zipcode) {
this.zipcode = zipcode;
}
public String getAddress1() {
return address1;
}
public void setAddress1(String address1) {
this.address1 = address1;
}
public String getAddress2() {
return address2;
}
public void setAddress2(String address2) {
this.address2 = address2;
}
public String getPhoto() {
return photo;
}
public void setPhoto(String photo) {
this.photo = photo;
}
public Date getReg_date() {
return reg_date;
}
public void setReg_date(Date reg_date) {
this.reg_date = reg_date;
}
public Date getModify_date() {
return modify_date;
}
public void setModify_date(Date modify_date) {
this.modify_date = modify_date;
}
}
kr.member.dao=> MemberDAO
kr.member.action => RegisterUserFormAction.java
package kr.member.action;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import kr.controller.Action;
public class RegisterUserFormAction implements Action{
@Override
public String execute(HttpServletRequest request, HttpServletResponse response) throws Exception {
//JSP 경로 반환
return "/WEB-INF/views/member/registerUserForm.jsp";
}
}
WEB-INF/views/member=>registerUserForm.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>회원 가입</title>
<link rel="stylesheet" href="${pageContext.request.contextPath}/css/style.css" type="text/css">
</head>
<body>
<div class="page-main">
<jsp:include page="/WEB-INF/views/common/header.jsp"/>
<div class="content-main">
<h2>회원 가입</h2>
<form id="register_form" action="registerUser.do" method="post">
<ul>
<li>
<label for="id">아이디</label>
<input type="text" id="id" name="id" maxlength="12"
autocomplete="off" class="input-check">
<input type="button" value="ID중복체크" id="id_check">
<span id="message_id"></span>
<div class="form-notice">*영문 또는 숫자(4자~12자)</div>
</li>
<li>
<label for="name">이름</label>
<input type="text" id="name" name="name" maxlength="10" class="input-check">
</li>
<li>
<label for="passwd">비밀번호</label>
<input type="password" id="passwd" name="passwd" maxlength="10" class="input-check">
</li>
<li>
<label for="phone">전화번호</label>
<input type="text" id="phone" name="phone" maxlength="15" class="input-check">
</li>
<li>
<label for="email">이메일</label>
<input type="email" id="email" name="email" maxlength="50" class="input-check">
</li>
<li>
<label for="zipcode">우편번호</label>
<input type="text" id="zipcode" name="zipcode" maxlength="5"
autocomplete="off" class="input-check">
<input type="button" value="우편번호 찾기" onclick="execDaumPostcode()">
</li>
<li>
<label for="address1">주소</label>
<input type="text" id="address1" name="address1" maxlength="30" class="input-check">
</li>
<li>
<label for="address2">나머지 주소</label>
<input type="text" id="address2" name="address2" maxlength="30" class="input-check">
</li>
</ul>
<div class="align-center">
<input type="submit" value="등록">
<input type="button" value="홈으로"
onclick="location.href='${pageContext.request.contextPath}/main/main.do'">
</div>
</form>
<!-- 다음우편번호 API시작 -->
<!-- iOS에서는 position:fixed 버그가 있음, 적용하는 사이트에 맞게 position:absolute 등을 이용하여 top,left값 조정 필요 -->
<div id="layer" style="display:none;position:fixed;overflow:hidden;z-index:1;-webkit-overflow-scrolling:touch;">
<img src="//t1.daumcdn.net/postcode/resource/images/close.png" id="btnCloseLayer" style="cursor:pointer;position:absolute;right:-3px;top:-3px;z-index:1" onclick="closeDaumPostcode()" alt="닫기 버튼">
</div>
<script src="//t1.daumcdn.net/mapjsapi/bundle/postcode/prod/postcode.v2.js"></script>
<script>
// 우편번호 찾기 화면을 넣을 element
var element_layer = document.getElementById('layer');
function closeDaumPostcode() {
// iframe을 넣은 element를 안보이게 한다.
element_layer.style.display = 'none';
}
function 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 + ')';
}
//(주의)address1에 참고항목이 보여지도록 수정
// 조합된 참고항목을 해당 필드에 넣는다.
//(수정) document.getElementById("address2").value = extraAddr;
}
//(수정) else {
//(수정) document.getElementById("address2").value = '';
//(수정) }
// 우편번호와 주소 정보를 해당 필드에 넣는다.
document.getElementById('zipcode').value = data.zonecode;
//(수정) + extraAddr를 추가해서 address1에 참고항목이 보여지도록 수정
document.getElementById("address1").value = addr + extraAddr;
// 커서를 상세주소 필드로 이동한다.
document.getElementById("address2").focus();
// iframe을 넣은 element를 안보이게 한다.
// (autoClose:false 기능을 이용한다면, 아래 코드를 제거해야 화면에서 사라지지 않는다.)
element_layer.style.display = 'none';
},
width : '100%',
height : '100%',
maxSuggestItems : 5
}).embed(element_layer);
// iframe을 넣은 element를 보이게 한다.
element_layer.style.display = 'block';
// iframe을 넣은 element의 위치를 화면의 가운데로 이동시킨다.
initLayerPosition();
}
// 브라우저의 크기 변경에 따라 레이어를 가운데로 이동시키고자 하실때에는
// resize이벤트나, orientationchange이벤트를 이용하여 값이 변경될때마다 아래 함수를 실행 시켜 주시거나,
// 직접 element_layer의 top,left값을 수정해 주시면 됩니다.
function initLayerPosition(){
var width = 300; //우편번호서비스가 들어갈 element의 width
var height = 400; //우편번호서비스가 들어갈 element의 height
var borderWidth = 5; //샘플에서 사용하는 border의 두께
// 위에서 선언한 값들을 실제 element에 넣는다.
element_layer.style.width = width + 'px';
element_layer.style.height = height + 'px';
element_layer.style.border = borderWidth + 'px solid';
// 실행되는 순간의 화면 너비와 높이 값을 가져와서 중앙에 뜰 수 있도록 위치를 계산한다.
element_layer.style.left = (((window.innerWidth || document.documentElement.clientWidth) - width)/2 - borderWidth) + 'px';
element_layer.style.top = (((window.innerHeight || document.documentElement.clientHeight) - height)/2 - borderWidth) + 'px';
}
</script>
</div>
<!-- 다음우편번호 API 끝 -->
</div>
</body>
</html>
다음에 있는 우편번호를 사용해 정리한 txt파일
kr.member.action => RegisterUserAction.java
package kr.member.action;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import kr.controller.Action;
import kr.member.dao.MemberDAO;
import kr.member.vo.MemberVO;
public class RegisterUserAction implements Action{
@Override
public String execute(HttpServletRequest request, HttpServletResponse response) throws Exception {
//전송된 데이터 인코딩 타입 지정
request.setCharacterEncoding("utf-8");
//자바빈(VO)생성
MemberVO member = new MemberVO();
member.setId(request.getParameter("id"));
member.setName(request.getParameter("name"));
member.setPasswd(request.getParameter("passwd"));
member.setPhone(request.getParameter("phone"));
member.setEmail(request.getParameter("email"));
member.setZipcode(request.getParameter("zipcode"));
member.setAddress1(request.getParameter("address1"));
member.setAddress2(request.getParameter("address2"));
MemberDAO dao = MemberDAO.getInstance();
dao.insertMember(member);
request.setAttribute("result_title", "회원 가입 완료");
request.setAttribute("result_msg", "회원 가입이 완료되었습니다.");
request.setAttribute("result_url", request.getContextPath()+"/main/main.do");
return "/WEB-INF/views/common/result_view.jsp";
}
}
WEB-INF/views/common => result_view.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>${result.title}</title>
<link rel="stylesheet" href="${pageContext.request.contextPath}/css/style.css" type="text/css">
</head>
<body>
<div class="page-main">
<jsp:include page ="/WEB-INF/views/common/header.jsp"/>
<div class="content-main">
<h2>${result_title}</h2>
<div class="result-display">
<div class="align-center">
${result_msg}
<p>
<input type="button" value="확인" onclick="location.href='${result_url}'">
</div>
</div>
</div>
</div>
</body>
</html>
CheckDuplicatedIdAction (58일차 시작)
package kr.member.action;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.codehaus.jackson.map.ObjectMapper;
import kr.controller.Action;
import kr.member.dao.MemberDAO;
import kr.member.vo.MemberVO;
public class CheckDuplicatedIdAction implements Action {
@Override
public String execute(HttpServletRequest request, HttpServletResponse response) throws Exception {
//전송된 데이터 인코딩 타입 지정
request.setCharacterEncoding("utf-8");
//전송된 데이터 반환
String id = request.getParameter("id");
MemberDAO dao = MemberDAO.getInstance();
MemberVO member = dao.checkMember(id);
//mapAjax는 문자열 키와 값의 쌍을 저장할 수 있는 자료구조
Map<String,String> mapAjax = new HashMap<String,String>();
if(member == null) {//아이디 미중복
mapAjax.put("result", "idNotFound");//result가 key
}else {//아이디 중복
mapAjax.put("result", "idDuplicated");
}
/*
* JSON 형식으로 변환하기를 원하는 문자열을 HashMap에 key와 value의 쌍으로 저장한 후
* ObjectMapper의 writeValueAsString에 Map 객체를 전달해서 일반 문자열 데이터를
* JSON 형식의 문자열 데이터로 변환 후 반환
*/
//jar 파일을 받았기 떄문에 import 가능
ObjectMapper mapper = new ObjectMapper(); //ObjectMapper 클래스는 Java 객체를 JSON 문자열로 변환하거나 JSON 문자열을 Java 객체로 변환하는 데 사용
String ajaxData = mapper.writeValueAsString(mapAjax);
request.setAttribute("ajaxData", ajaxData);
return "/WEB-INF/views/common/ajax_view.jsp";
}
}
ajax_view.jsp
<%@ page language="java" contentType="text/plain; charset=UTF-8"
pageEncoding="UTF-8" trimDirectiveWhitespaces="true"%>
${ajaxData}
LoginFormAction
package kr.member.action;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import kr.controller.Action;
public class LoginFormAction implements Action{
@Override
public String execute(HttpServletRequest request, HttpServletResponse response) throws Exception {
//JSP 경로 반환
return "/WEB-INF/views/member/loginForm.jsp";
}
}
loginForm.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>로그인</title>
<link rel="stylesheet" href="${pageContext.request.contextPath}/css/style.css" type="text/css">
<script type="text/javascript" src="${pageContext.request.contextPath}/js/jquery-3.7.1.min.js"></script>
<script type="text/javascript">
$(function(){
$('#login_form').submit(function(){
if($('#id').val().trim()==''){
alert('아이디를 입력하세요');
$('#id').val('').focus();
return false;
}
if($('#passwd').val().trim()==''){
alert('비밀번호를 입력하세요');
$('#passwd').val('').focus();
return false;
}
});
});
</script>
</head>
<body>
<div class="page-main">
<jsp:include page="/WEB-INF/views/common/header.jsp"/>
<div class="content-main">
<h2>로그인</h2>
<form id="login_form" action="login.do" method="post">
<ul>
<li class="floating-label">
<input type="text" class="form-input" placeholder="아이디"
name="id" id="id" maxlength="12" autocomplete="off">
<label for="id">아이디</label>
</li>
<li class="floating-label">
<input type="password" class="form-input" placeholder="비밀번호"
name="passwd" id="passwd" maxlength="12"><!-- 비밀번호는 autocomplete="off"가 원래 기본값이므로 쓸 필요없음 -->
<label for="id">비밀번호</label>
</li>
</ul>
<div class="align-center">
<input type="submit" value="로그인">
<input type="button" value="홈으로" onclick="location.href='${pageContext.request.contextPath}/main/main.do'">
</div>
</form>
</div>
</div>
</body>
</html>
LoginAction
package kr.member.action;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import kr.controller.Action;
public class LogoutAction implements Action{
@Override
public String execute(HttpServletRequest request, HttpServletResponse response) throws Exception {
HttpSession session = request.getSession();
//로그아웃 처리
session.invalidate();
//메인으로 리다이렉트
return "redirect:/main/main.do";
}
}
login.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<c:choose>
<c:when test="${auth ==1}">
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>로그인 정보</title>
<link rel="stylesheet" href="${pageContext.request.contextPath}/css/style.css" type="text/css">
</head>
<body>
<div class="page-main">
<jsp:include page="/WEB-INF/views/common/header.jsp"/>
<div class="content-main">
<h2>회원 정보</h2>
<div class="result-display">
정지된 회원 ID입니다.<br>
<input type="button" value="홈으로" onclick="'${pageContext.request.contextPath}/main/main.do'">
</div>
</div>
</div>
</body>
</html>
</c:when>
<%-- auth가 1이 아닌 경우 --%>
<c:otherwise>
<script type="text/javascript">
//탈퇴회원인지를 알려주는 것도 개인정보 일 수 있기 때문에 아이디 비번 틀린것과 같이 묶는다.
alert('아이디 또는 비밀번호가 불일치합니다.');
history.go(-1);
</script>
</c:otherwise>
</c:choose>
css/style.css 수정(로그인부분. 목록위에 명시)
/* 로그인
----------------------*/
#login_form{
width:300px;
margin:0 auto;
padding:0;
border:none;
}
#login_form ul{
padding:0;
}
.floating-label{/*floating label 설정*/
position:relative;
}
.floating-label > .form-input{
width:300px;
height:32px;
padding:0.55rem 0.55rem;
}
.floating-label > label{
position:absolute;
top:0;
left:0;
padding:1.05rem 0.75rem;
transition:all 0.25s;
}
.floating-label > .form-input::placeholder{
color:transparent; /* 컬러가 투명한 형태 */
}
.floating-label > .form-input:focus,
.floating-label > .form-input:not(:placeholder-shown){
padding-top:1.125rem;
padding-bottom:0.125rem;
}
.floating-label > .form-input:focus + label,
.floating-label > .form-input:not(:placeholder-shown) + label{
opacity:0.65;
transform:scale(0.85) translateY(-0.5rem) translateX(-0.5rem);
}
LogoutAction
package kr.member.action;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import kr.controller.Action;
public class LogoutAction implements Action{
@Override
public String execute(HttpServletRequest request, HttpServletResponse response) throws Exception {
HttpSession session = request.getSession();
//로그아웃 처리
session.invalidate();
//메인으로 리다이렉트
return "redirect:/main/main.do";
}
}
MyPageAction
package kr.member.action;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import kr.controller.Action;
import kr.member.dao.MemberDAO;
import kr.member.vo.MemberVO;
public class MyPageAction implements Action{
@Override
public String execute(HttpServletRequest request, HttpServletResponse response) throws Exception {
HttpSession session = request.getSession();
Integer user_num = (Integer)session.getAttribute("user_num");
if(user_num == null) {//로그인이 되지 않은 경우
return "redirect:/member/loginForm.do";
}
//로그인이 된 경우
//회원정보
MemberDAO dao = MemberDAO.getInstance();
MemberVO member = dao.getMember(user_num);
request.setAttribute("member", member);
//JSP 경로 반환
return "/WEB-INF/views/member/myPage.jsp";
}
}
myPage.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>My Page</title>
<link rel="stylesheet" href="${pageContext.request.contextPath}/css/style.css" type="text/css">
<script type="text/javascript" src="${pageContext.request.contextPath}/js/jquery-3.7.1.min.js"></script>
<script type="text/javascript">
$(function(){
$('#photo_btn').click(function(){
$('#photo_choice').show();
$(this).hide(); //수정 버튼 감추기
});
//이미지 미리 보기
let photo_path = $('.my-photo').attr('src'); //처음화면에 보여지는 이미지 일기
$('#photo').change(function(){
let my_photo = this.files[0];
if(!my_photo){
//선택을 취소하면 원래 처음 화면으로 되돌림
$('.my-photo').attr('src',photo_path);
return;
}
if(my_photo.size > 1024*1024){
alert(Math.round(my_photo.size/1024)+'kbytes(1024kbytes까지만 업로드 가능)');
$('.my-photo').attr('src',photo_path);
$(this).val('');//선택한 파일 정보 지우기
return;
}
//화면에 이미지 미리 보기
const reader = new FileReader();
reader.readAsDataURL(my_photo);
reader.onload = function(){
$('.my-photo').attr('src',reader.result);
};
});//end of change
//이미지 미리보기 취소
$('#photo_reset').click(function(){
//초기 이미지 표시
$('.my-photo').attr('src',photo_path); //이미지 미리보기 전 이미지로 되돌리기
$('#photo').val('');
$('#photo_choice').hide();
$('#photo_btn').show(); //수정 버튼 표시
});
});
</script>
</head>
<body>
<div class="page-main">
<jsp:include page="/WEB-INF/views/common/header.jsp"/>
<div class="content-main">
<h2>회원정보</h2>
<div class="mypage-div">
<h3>프로필 사진</h3>
<ul>
<li>
<c:if test="${empty member.photo}"> <!-- 이미지가 비어있는 경우 -->
<img src="${pageContext.request.contextPath}/images/face.png"
width="200" height="200" class="my-photo">
</c:if>
<c:if test="${!empty member.photo}"> <!-- 이미지가 비어있는 경우 -->
<img src="${pageContext.request.contextPath}/upload/${member.photo}"
width="200" height="200" class="my-photo">
</c:if>
</li>
<li>
<div class="align-center">
<input type="button" value="수정" id="photo_btn">
</div>
<div id = "photo_choice" style="display:none;">
<input type="file" id="photo" accept="image/gif,image/png,image/jpeg">
<input type="button" value="전송" id="photo_submit">
<input type="button" value="취소" id="photo_reset">
</div>
</li>
</ul>
<h3>연락처<input type="button" value="연락처 수정" onclick="location.href='modifyUserForm.do'"></h3>
<ul>
<li>아이디 : ${member.id}</li>
<li>이름 : ${member.name}</li>
<li>전화번호 : ${member.phone}</li>
<li>이메일 : ${member.email}</li>
<li>우편번호 : ${member.zipcode}</li>
<li>주소 : ${member.address1} ${member.address2}</li>
<li>가입일 : ${member.reg_date}</li>
<c:if test="${!empty member.modify_date}">
<li>최근 정보 수정일 : ${member.modify_date}</li>
</c:if>
</ul>
<h3>비밀번호 수정</h3>
<h3>회원탈퇴</h3>
</div>
<div class="mypage-div">
<h3>관심 게시물 목록</h3>
</div>
<div class="mypage-end"></div>
</div>
</div>
</body>
</html>
css/style.css 수정(마이페이지부분. 목록위에 명시)
/* MY페이지
----------------------*/
.mypage-div{
width:48%;
float:left;
padding:5px;
}
.mypage-end{
clear:both;
}
.my-photo{
object-fit:cover;
/* 이미지가 정사각형이 아니라 직사각형 일경우 원 안에 보여지게 할 중심 이미지의 위치를 지정 */
object-position:top;
/* 사각형의 모서리 둥근 정도를 지정하는 속성, 50%를 지정하면 완전한 원 */
border-radius:50%;
}
UpdateMyPhotoAction
package kr.member.action;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.codehaus.jackson.map.ObjectMapper;
import kr.controller.Action;
import kr.member.dao.MemberDAO;
import kr.util.FileUtil;
public class UpdateMyPhotoAction implements Action{
@Override
public String execute(HttpServletRequest request, HttpServletResponse response) throws Exception {
Map<String, String> mapAjax = new HashMap<String,String>();
HttpSession session = request.getSession();
Integer user_num = (Integer)session.getAttribute("user_num");
if(user_num == null) {//로그인이 되지 않은 경우
mapAjax.put("result","logout");
}else {//로그인 된 경우
//전송된 데이터 인코딩 타입 지정
request.setCharacterEncoding("utf-8");
//파일 업로드 처리
String photo = FileUtil.createFile(request, "photo");
MemberDAO dao = MemberDAO.getInstance();
//프로필 사진 수정
dao.updateMyPhoto(photo, user_num);
//이전 파일 삭제 처리
String user_photo = (String)session.getAttribute("user_photo");
FileUtil.removeFile(request, user_photo);
//현재 파일로 세션 정보를 갱신(위에서 삭제처리 했기 때문에)
session.setAttribute("user_photo", photo);
mapAjax.put("result","success");
}
ObjectMapper mapper = new ObjectMapper();
String ajaxData = mapper.writeValueAsString(mapAjax);
request.setAttribute("ajaxData", ajaxData);
return "/WEB-INF/views/common/ajax_view.jsp";
}
}