Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
Tags
- 배열
- 인코딩
- 입력메소드
- 페이징
- 검색기능
- 별찍기
- redirect
- 내일배움카드
- 회원정보수정
- 권한변경
- jdbc환경설정
- 관리자회원조회
- forward
- jdbc설정
- 국민취업지원제도
- 회원탈퇴
- live server 환경설정
- 정처기
- jsp기본
- 페이지 재사용
- 국취제
- 내배카
- 로그아웃
- 국비학원
- mvc
- Git
- emmet환경설정
- 비밀번호변경
- 비밀번호암호화
- github
Archives
- Today
- Total
기록
*78일차 (비밀번호 변경 / 관리자회원 조회 / 권한변경 / 검색) 본문
@비밀번호 변경
1. 비번변경 버튼 추가 (memberView.jsp)
<input type="button" value="비밀번호수정" onclick="location.href='<%= request.getContextPath() %>/member/passwordUpdate';"/>
2.비번 서블릿 생성 (PasswordUpdateServlet.java)
- doGet | doPost 사용
package member.controller;
import java.io.IOException;
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 common.HelloMvcUtils;
import member.model.dto.Member;
import member.model.service.MemberService;
/**
* Servlet implementation class PasswordUpdateServlet
*/
@WebServlet("/member/passwordUpdate")
public class PasswordUpdateServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
private MemberService memberService = new MemberService();
/**
* 패스워드 수정폼 요청
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.getRequestDispatcher("/WEB-INF/views/member/passwordUpdate.jsp")
.forward(request, response);
}
/**
* 패스워드 수정 요청
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try {
// 1. 사용자입력값 처리
String memberId = request.getParameter("memberId");
String oldPassword = HelloMvcUtils.encrypt(request.getParameter("oldPassword"), memberId);
String newPassword = HelloMvcUtils.encrypt(request.getParameter("newPassword"), memberId);
System.out.println("memberId = " + memberId);
System.out.println("oldPassword = " + oldPassword);
System.out.println("newPassword = " + newPassword);
// 2. 업무로직 - 기존비밀번호가 일치하는 경우에만 비밀번호를 수정
Member member = memberService.findByMemberId(memberId);
String msg = "";
String location = request.getContextPath();
if(member != null && oldPassword.equals(member.getPassword())) {
// 비밀번호 수정
Member updateMember = new Member();
updateMember.setMemberId(memberId);
updateMember.setPassword(newPassword);
int result = memberService.updatePassword(updateMember);
msg = "비밀번호를 성공적으로 변경했습니다.";
location += "/member/memberView";
}
else {
msg = "기존 비밀번호가 일치하지 않습니다.";
location += "/member/passwordUpdate";
}
// 3. 리다이렉트처리
request.getSession().setAttribute("msg", msg);
response.sendRedirect(location);
} catch (Exception e) {
e.printStackTrace();
throw e;
}
}
}
3.비번 jsp 생성 (PasswordUpdate.jsp)
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ include file="/WEB-INF/views/common/header.jsp" %>
<section id=enroll-container>
<h2>비밀번호 변경</h2>
<form
name="passwordUpdateFrm"
action="<%=request.getContextPath()%>/member/passwordUpdate"
method="post" >
<table>
<tr>
<th>현재 비밀번호</th>
<td><input type="password" name="oldPassword" id="oldPassword" required></td>
</tr>
<tr>
<th>변경할 비밀번호</th>
<td>
<input type="password" name="newPassword" id="newPassword" required>
</td>
</tr>
<tr>
<th>비밀번호 확인</th>
<td>
<input type="password" id="newPasswordCheck" required><br>
</td>
</tr>
<tr>
<td colspan="2" style="text-align: center;">
<input type="submit" value="변경" />
</td>
</tr>
</table>
<input type="hidden" name="memberId" value="<%= loginMember.getMemberId() %>" />
</form>
</section>
<script>
newPasswordCheck.onblur = () => {
if(newPassword.value !== newPasswordCheck.value){
alert("두 비밀번호가 일치하지 않습니다.");
return false; // 폼 유효성 검사에서 사용
}
return true;
};
document.passwordUpdateFrm.onsubmit = () => {
// password 영문자/숫자/특수문자!@#$%^&*()
if(!/^[A-Za-z0-9!@#$%^&*()]{4,}$/.test(oldPassword.value)){
alert("기존 비밀번호는 영문자/숫자/특수문자!@#$%^&*()로 4글자 이상이어야 합니다.");
return false;
}
if(!/^[A-Za-z0-9!@#$%^&*()]{4,}$/.test(newPassword.value)){
alert("새 비밀번호는 영문자/숫자/특수문자!@#$%^&*()로 4글자 이상이어야 합니다.");
return false;
}
if(!newPasswordCheck.onblur()){
return false; // 폼 제출을 방지
}
}
</script>
<%@ include file="/WEB-INF/views/common/footer.jsp" %>
- id는 노출할 필요없어서 hidden
- 평문으로는 비교불가라 암호화함
4. updatePassword 생성 (MemberService.java)
public int updatePassword(Member member) {
int result = 0;
Connection conn = getConnection();
try {
result = memberDao.updatePassword(conn, member);
commit(conn);
} catch (Exception e) {
rollback(conn);
throw e;
} finally {
close(conn);
}
return result;
}
- alt + shift + z → try~catch
5. updatePassword 생성 (MemberDAO)
public int updatePassword(Connection conn, Member member) {
int result = 0;
PreparedStatement pstmt = null;
String sql = prop.getProperty("updatePassword");
try {
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, member.getPassword());
pstmt.setString(2, member.getMemberId());
result = pstmt.executeUpdate();
} catch (Exception e) {
throw new MemberException("비밀번호 수정 오류!", e);
} finally {
close(pstmt);
}
return result;
}
- 6번에서 ?가 2개이므로 2개 채워줌
6.properties에 관련 작성
updateMemberRole = update member set member_role = ? where member_id = ?
- 홍길동 비번 2345
@관리자의 회원조회
- 관리자일때 할 수 있는 기능들
1.header.jsp
<% if(loginMember != null && loginMember.getMemberRole() == MemberRole.A) { %>
<li class="admin"><a href="<%= request.getContextPath() %>/admin/memberList">회원관리</a></li>
<% } %>
- admin일때만 회원관리가 보임
2.admin은 별개의 package에서 관리할 것
- AdminMemberListServlet
- doGet
try {
// 1. 업무로직
List<Member> list = memberService.findAll();
System.out.println("list = " + list);
// 2. view단 처리
request.setAttribute("list", list);
request.getRequestDispatcher("/WEB-INF/views/admin/memberList.jsp")
.forward(request, response);
} catch (Exception e) {
e.printStackTrace();
throw e;
}
3. findAll 생성 (MemberService.java)
public List<Member> findAll() {
Connection conn = getConnection();
List<Member> list = memberDao.findAll(conn);
close(conn);
return list;
}
4. findAll 생성 (MemberDao.java)
public List<Member> findAll(Connection conn) {
PreparedStatement pstmt = null;
ResultSet rset = null;
List<Member> list = new ArrayList<>();
String sql = prop.getProperty("findAll");
try {
pstmt = conn.prepareStatement(sql);
rset = pstmt.executeQuery();
while(rset.next()) {
Member member = handleMemberResultSet(rset);
list.add(member);
}
} catch (Exception e) {
throw new MemberException("관리자 회원목록 조회 오류", e);
} finally {
close(rset);
close(pstmt);
}
return list;
}
- 1건 조회시 member객체 하나 or null 리턴
- n건 조회시 여러건의 member객체를 가진 list or 빈 list
*ResultSet을 받아서 맴버객체로 반환 (리팩토리)
- 우클릭 - Refactor - Extract Method
5.memberList.jsp
<%@page import="java.util.List"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ include file="/WEB-INF/views/common/header.jsp" %>
<%
List<Member> list = (List<Member>) request.getAttribute("list");
%>
<!-- 관리자용 admin.css link -->
<link rel="stylesheet" href="<%=request.getContextPath()%>/css/admin.css" />
<style>
div#search-container {width: 100%; margin:0 0 10px 0; padding:3px; background-color: rgba(0, 188, 212, 0.3);}
div#search-memberId {display: inline-block;}
div#search-memberName{display:none;}
div#search-gender{display:none;}
</style>
<section id="memberList-container">
<h2>회원관리</h2>
<div id="search-container">
<label for="searchType">검색타입 :</label>
<select id="searchType">
<option value="member_id">아이디</option>
<option value="member_name">회원명</option>
<option value="gender">성별</option>
</select>
<div id="search-memberId" class="search-type">
<form action="<%=request.getContextPath()%>/admin/memberFinder">
<input type="hidden" name="searchType" value="member_id"/>
<input type="text" name="searchKeyword" size="25" placeholder="검색할 아이디를 입력하세요."/>
<button type="submit">검색</button>
</form>
</div>
<div id="search-memberName" class="search-type">
<form action="<%=request.getContextPath()%>/admin/memberFinder">
<input type="hidden" name="searchType" value="member_name"/>
<input type="text" name="searchKeyword" size="25" placeholder="검색할 이름을 입력하세요."/>
<button type="submit">검색</button>
</form>
</div>
<div id="search-gender" class="search-type">
<form action="<%=request.getContextPath()%>/admin/memberFinder">
<input type="hidden" name="searchType" value="gender"/>
<input type="radio" name="searchKeyword" value="M" checked> 남
<input type="radio" name="searchKeyword" value="F"> 여
<button type="submit">검색</button>
</form>
</div>
</div>
<table id="tbl-member">
<thead>
<tr>
<th>아이디</th>
<th>이름</th>
<th>회원권한</th>
<th>성별</th>
<th>생년월일</th>
<th>이메일</th>
<th>전화번호</th>
<th>주소</th>
<th>취미</th>
<th>가입일</th>
</tr>
</thead>
<tbody>
<%
if(list != null && !list.isEmpty()){
for(Member member : list){
%>
<tr>
<td><%= member.getMemberId() %></td>
<td><%= member.getMemberName() %></td>
<td>
<select class="member-role" data-member-id="<%= member.getMemberId() %>">
<option value="<%= MemberRole.A %>" <%= member.getMemberRole() == MemberRole.A ? "selected" : "" %>>관리자</option>
<option value="<%= MemberRole.U %>" <%= member.getMemberRole() == MemberRole.U ? "selected" : "" %>>일반회원</option>
</select>
</td>
<td><%= member.getGender() != null ? member.getGender() : "" %></td>
<td><%= member.getBirthday() != null ? member.getBirthday() : "" %></td>
<td><%= member.getEmail() != null ? member.getEmail() : "" %></td>
<td><%= member.getPhone() %></td>
<td><%= member.getAddress() != null ? member.getAddress() : "" %></td>
<td><%= member.getHobby() != null ? member.getHobby() : "" %></td>
<td><%= member.getEnrollDate() %></td>
</tr>
<%
}
}
else {
%>
<tr>
<td colspan="10">조회된 회원이 없습니다.</td>
</tr>
<%
}
%>
</tbody>
</table>
</section>
<form
action="<%= request.getContextPath() %>/admin/memberRoleUpdate"
name="updateMemberRoleFrm"
method="POST">
<input type="hidden" name="memberId" />
<input type="hidden" name="memberRole" />
</form>
<script>
searchType.addEventListener('change', (e) => {
const {value} = e.target; // 구조분해할당
console.log(value);
document.querySelectorAll(".search-type").forEach((div) => {
div.style.display = "none";
});
let id = "";
switch(value){
case "member_id": id = "search-memberId"; break;
case "member_name": id = "search-memberName"; break;
case "gender": id = "search-gender"; break;
}
document.querySelector(`#\${id}`).style.display = "inline-block";
});
document.querySelectorAll(".member-role").forEach((select) => {
select.addEventListener('change', (e) => {
// console.dir(e.target);
// console.log(e.target.dataset.memberId); // key값을 조회시에는 camelcasing으로 참조
// console.log(e.target.value); // "U" "A"
const memberId = e.target.dataset.memberId;
const memberRole = e.target.value;
// jsp에서 js의 Template String문법 사용시 반드시 escaping처리할 것
// (jsp의 EL문법과 충돌)
if(confirm(`[\${memberId}]의 권한을 [\${memberRole}]로 변경하시겠습니까?`)){
const frm = document.updateMemberRoleFrm;
frm.memberId.value = memberId;
frm.memberRole.value = memberRole;
frm.submit();
}
else {
e.target.querySelector("[selected]").selected = true;
}
});
});
</script>
<%@ include file="/WEB-INF/views/common/footer.jsp" %>
@권한변경
document.querySelectorAll(".member-role").forEach((select) => {
select.addEventListener('change', (e) => {
// console.dir(e.target);
// console.log(e.target.dataset.memberId); // key값을 조회시에는 camelcasing으로 참조
// console.log(e.target.value); // "U" "A"
const memberId = e.target.dataset.memberId;
const memberRole = e.target.value;
// jsp에서 js의 Template String문법 사용시 반드시 escaping처리할 것
// (jsp의 EL문법과 충돌)
if(confirm(`[\${memberId}]의 권한을 [\${memberRole}]로 변경하시겠습니까?`)){
const frm = document.updateMemberRoleFrm;
frm.memberId.value = memberId;
frm.memberRole.value = memberRole;
frm.submit();
}
else {
e.target.querySelector("[selected]").selected = true;
}
});
- 각각의 태그에 대해 배열이 넘어옴
@검색
1.검색기능추가 form (memberList.jsp)
<div id="search-container">
<label for="searchType">검색타입 :</label>
<select id="searchType">
<option value="member_id">아이디</option>
<option value="member_name">회원명</option>
<option value="gender">성별</option>
</select>
<div id="search-memberId" class="search-type">
<form action="<%=request.getContextPath()%>/admin/memberFinder">
<input type="hidden" name="searchType" value="member_id"/>
<input type="text" name="searchKeyword" size="25" placeholder="검색할 아이디를 입력하세요."/>
<button type="submit">검색</button>
</form>
</div>
<div id="search-memberName" class="search-type">
<form action="<%=request.getContextPath()%>/admin/memberFinder">
<input type="hidden" name="searchType" value="member_name"/>
<input type="text" name="searchKeyword" size="25" placeholder="검색할 이름을 입력하세요."/>
<button type="submit">검색</button>
</form>
</div>
<div id="search-gender" class="search-type">
<form action="<%=request.getContextPath()%>/admin/memberFinder">
<input type="hidden" name="searchType" value="gender"/>
<input type="radio" name="searchKeyword" value="M" checked> 남
<input type="radio" name="searchKeyword" value="F"> 여
<button type="submit">검색</button>
</form>
</div>
</div>
2. AdminMemberFinderListServlet
- /admin/memberFinder
- doGet
- 결과를 html로 반환 → jsp에서 처리
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 1. 사용자입력값처리
String searchType = request.getParameter("searchType"); // member_id member_name gender
String searchKeyword = request.getParameter("searchKeyword");
Map<String, String> param = new HashMap<>();
param.put("searchType", searchType);
param.put("searchKeyword", searchKeyword);
System.out.println("param = " + param);
// 2. 업무로직
List<Member> list = memberService.findBy(param);
System.out.println("list = " + list);
// 3. view단처리
request.setAttribute("list", list);
request.getRequestDispatcher("/WEB-INF/views/admin/memberList.jsp")
.forward(request, response);
}
- select * from member where member_id like '%abc%'
- select * from member where member_name like '%박%'
- select * from member where gender like 'M'
- select * from member where # like ?
- jdbc에는 테이블명/컬럼명을 대체해주는 기능이 없음
- #을 이용한 이유 : 문자열의 replace를 이용하여 값을 대체함
3.MemberDao
public List<Member> findBy(Connection conn, Map<String, String> param) {
PreparedStatement pstmt = null;
ResultSet rset = null;
List<Member> list = new ArrayList<>();
String sql = prop.getProperty("findBy");
sql = sql.replace("#", param.get("searchType"));
System.out.println("sql = " + sql);
try {
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, "%" + param.get("searchKeyword") + "%");
rset = pstmt.executeQuery();
while(rset.next()) {
Member member = handleMemberResultSet(rset);
list.add(member);
}
} catch (Exception e) {
throw new MemberException("관리자 회원검색 오류", e);
} finally {
close(rset);
close(pstmt);
}
return list;
}
'학원 > 강의' 카테고리의 다른 글
*80일차- ncs테스트(요구사항 확인) (0) | 2022.05.20 |
---|---|
*79일차 (UML) (0) | 2022.05.19 |
*77일차 (회원정보수정 / 비밀번호 암호화) (0) | 2022.05.17 |
*76일차 (회원가입 / 중복아이디 체크) (0) | 2022.05.16 |
*75일차 (로그인/로그아웃/session/cookie) (0) | 2022.05.13 |