홈페이지 구현하기(4)
[ 포인트 구현 ]
- header.jsp 로그인시 포인트충전 메뉴 추가
<%if(login){ %>
<a href="<%=root%>/index.jsp">홈으로</a>
<a href="<%=root%>/member/logout.txt">로그아웃</a>
<a href="<%=root%>/member/mypage.jsp">내정보</a>
<a href="<%=root%>/point/charge.jsp">포인트충전</a>
<a href="#">게시판</a>
-MemberFilter에 필터 주소 추가 ( 로그인만 접속가능 )
@WebFilter(urlPatterns = "/point/*")
- 포인트 상품 조회 + 충전 기능 만들기
- 포인트 상품 조회 (CoinDao) 만들기
package home.beans;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;
public class CoinDao {
public static final String USERNAME = "계정아이디", PASSWORD = "계정비밀번호";
// 목록 조회 기능
public List<CoinDto> list() throws Exception {
Connection con = JdbcUtils.connect(USERNAME, PASSWORD);
String sql = "select * from coin order by coin_amount asc";
PreparedStatement ps = con.prepareStatement(sql);
ResultSet rs = ps.executeQuery();
// rs의 내용을 List에 복사
List<CoinDto> list = new ArrayList<>();
while (rs.next()) {
CoinDto coinDto = new CoinDto();
// (3개 항목 복사)
coinDto.setCoinNo(rs.getInt("coin_no"));
coinDto.setCoinName(rs.getString("coin_name"));
coinDto.setCoinAmount(rs.getInt("coin_amount"));
list.add(coinDto);
}
con.close();
return list;
}
public CoinDto get(int coinNo) throws Exception {
Connection con = JdbcUtils.connect(USERNAME, PASSWORD);
String sql = "select * from coin where coin_no = ?";
PreparedStatement ps = con.prepareStatement(sql);
ps.setInt(1, coinNo);
ResultSet rs = ps.executeQuery();
CoinDto coinDto;
if(rs.next()) {
coinDto = new CoinDto();
coinDto.setCoinNo(rs.getInt("coin_no"));
coinDto.setCoinName(rs.getString("coin_name"));
coinDto.setCoinAmount(rs.getInt("coin_amount"));
}
else {
coinDto = null;
}
con.close();
return coinDto;
}
}
- 포인트 상품 조회 (CoinDto) 만들기
package home.beans;
public class CoinDto {
private int coinNo;
private String coinName;
private int coinAmount;
public CoinDto() {
super();
}
public int getCoinNo() {
return coinNo;
}
public void setCoinNo(int coinNo) {
this.coinNo = coinNo;
}
public String getCoinName() {
return coinName;
}
public void setCoinName(String coinName) {
this.coinName = coinName;
}
public int getCoinAmount() {
return coinAmount;
}
public void setCoinAmount(int coinAmount) {
this.coinAmount = coinAmount;
}
@Override
public String toString() {
return "CoinDto [coinNo=" + coinNo + ", coinName=" + coinName + ", coinAmount=" + coinAmount + "]";
}
}
- 포인트 충전 페이지 (charge.jsp) 만들기
<%@page import="home.beans.CoinDto"%>
<%@page import="java.util.List"%>
<%@page import="home.beans.CoinDao"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%-- 입력 : 없음 --%>
<%-- 처리 : 포인트상품 목록 --%>
<%
CoinDao coinDao = new CoinDao();
List<CoinDto> list = coinDao.list();
%>
<%-- 출력 --%>
<jsp:include page="/template/header.jsp"></jsp:include>
<h2>포인트 충전</h2>
<h3>원하시는 상품을 선택하세요</h3>
<form action="charge.txt" method="post">
<table>
<tbody>
<%for(CoinDto coinDto : list){ %>
<tr>
<td><input type="radio" name="coinNo" value="<%=coinDto.getCoinNo()%>"></td>
<td><%=coinDto.getCoinName()%></td>
<td>(<%=coinDto.getCoinAmount()%> point)</td>
</tr>
<%} %>
</tbody>
<tfoot>
<tr align="center">
<td colspan="3">
<input type="submit" value="충전">
</td>
</tr>
</tfoot>
</table>
</form>
<jsp:include page="/template/footer.jsp"></jsp:include>
- 포인트 충전 처리 (PointChargeServlet.java) 만들기
package home.servlet.point;
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 home.beans.CoinDao;
import home.beans.CoinDto;
import home.beans.HistoryDao;
import home.beans.HistoryDto;
import home.beans.MemberDao;
@WebServlet(urlPatterns = "/point/charge.txt")
public class PointChargeServlet extends HttpServlet{
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
try {
//1
int coinNo = Integer.parseInt(req.getParameter("coinNo"));
//2
String memberId = (String)req.getSession().getAttribute("ses");
//3 - coin 단일조회
CoinDao coinDao = new CoinDao();
CoinDto coinDto = coinDao.get(coinNo);
//4 - history 등록
HistoryDto historyDto = new HistoryDto();
historyDto.setMemberId(memberId);
historyDto.setHistoryAmount(coinDto.getCoinAmount());
historyDto.setHistoryMemo("포인트상품 구매");
HistoryDao historyDao = new HistoryDao();
historyDao.insert(historyDto);
//5 - member 수정
//[1] 원래 포인트에서 현재 포인트만 추가 - 회원아이디, 추가된 포인트
//[2] history에서 해당 회원 내역을 전부 계산하여 재설정 - 회원아이디
MemberDao memberDao = new MemberDao();
memberDao.addPoint(memberId, coinDto.getCoinAmount());//1번 방식
//memberDao.refreshPoint(memberId);//2번 방식
//완료 시 redirect
resp.sendRedirect("charge_success.jsp");
}
catch(Exception e) {
e.printStackTrace();
resp.sendError(500);
}
}
}
- MemberDao 포인트 증가 감소 2가지 기능 추가
[1 - addPoint ] 원래 포인트에서 현재 포인트만 추가 - 회원아이디, 추가된 포인트
[2 - refreshPoint ] history에서 해당 회원 내역을 전부 계산하여 재설정 - 회원아이디
PointChargeServlet에서 사용
public boolean addPoint(String memberId, int coinAmount) throws Exception {
Connection con = JdbcUtils.connect(USERNAME, PASSWORD);
String sql = "update member "
+ "set member_point = member_point + ? "
+ "where member_id = ?";
PreparedStatement ps = con.prepareStatement(sql);
ps.setInt(1, coinAmount);
ps.setString(2, memberId);
int result = ps.executeUpdate();
con.close();
return result > 0;
}
public boolean refreshPoint(String memberId) throws Exception {
Connection con = JdbcUtils.connect(USERNAME, PASSWORD);
String sql = "update member set member_point = ("
+ "select sum(history_amount) from history where member_id = ?"
+ ") where member_id = ?";
PreparedStatement ps = con.prepareStatement(sql);
ps.setString(1, memberId);
ps.setString(2, memberId);
int result = ps.executeUpdate();
con.close();
return result > 0;
}
- 포인트 충전 완료 페이지 (charge_success.jsp) 만들기
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<jsp:include page="/template/header.jsp"></jsp:include>
<h2>포인트 충전 완료</h2>
<jsp:include page="/template/footer.jsp"></jsp:include>
포인트 내역 조회 만들기
SQL에 코드 먼저 입력
create table history(
history_no number primary key,
member_id references member(member_id) on delete cascade not null,
history_time date default sysdate not null,
history_memo varchar2(100),
history_amount number
);
create sequence history_seq;
- 포인트 내역 조회 (TotalHistoryDto) 만들기
package home.beans;
import java.sql.Date;
public class TotalHistoryDto {
private int historyNo;
private String memberId;
private Date historyTime;
private String historyMemo;
private int historyAmount;
private String cancel;
public TotalHistoryDto() {
super();
}
public int getHistoryNo() {
return historyNo;
}
public void setHistoryNo(int historyNo) {
this.historyNo = historyNo;
}
public String getMemberId() {
return memberId;
}
public void setMemberId(String memberId) {
this.memberId = memberId;
}
public Date getHistoryTime() {
return historyTime;
}
public void setHistoryTime(Date historyTime) {
this.historyTime = historyTime;
}
public String getHistoryMemo() {
return historyMemo;
}
public void setHistoryMemo(String historyMemo) {
this.historyMemo = historyMemo;
}
public int getHistoryAmount() {
return historyAmount;
}
public void setHistoryAmount(int historyAmount) {
this.historyAmount = historyAmount;
}
public String getCancel() {
return cancel;
}
public void setCancel(String cancel) {
this.cancel = cancel;
}
public boolean available() {
return this.cancel.equals("취소가능");
}
}
- 포인트 내역 조회 (TotalHistoryDao) 만들기
package home.beans;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;
public class TotalHistoryDao {
public static final String USERNAME = "계정아이디", PASSWORD = "계정비밀번호";
//회원의 포인트내역 조회 기능
//= HistoryDto 대신에 취소 여부도 알 수 있도록 새로 만든 TotalHistoryDto를 사용하여 조회
public List<TotalHistoryDto> findByMemberId(String memberId) throws Exception {
Connection con = JdbcUtils.connect(USERNAME, PASSWORD);
String sql = "select * from total_history where member_id = ? order by history_no desc";
PreparedStatement ps = con.prepareStatement(sql);
ps.setString(1, memberId);
ResultSet rs = ps.executeQuery();
//copy(rs --> List<TotalHistoryDto>)
List<TotalHistoryDto> list = new ArrayList<>();
while(rs.next()) {
TotalHistoryDto historyDto = new TotalHistoryDto();
historyDto.setHistoryNo(rs.getInt("history_no"));
historyDto.setMemberId(rs.getString("member_id"));
historyDto.setHistoryTime(rs.getDate("history_time"));
historyDto.setHistoryMemo(rs.getString("history_memo"));
historyDto.setHistoryAmount(rs.getInt("history_amount"));
historyDto.setCancel(rs.getString("cancel"));
list.add(historyDto);
}
con.close();
return list;
}
}
포인트 결제 취소 만들기
Dto는 입력 항목이 하나(=history_no)이기 때문에 만들 필요 없다
-> Dao만 있으면 된다.
- 포인트 결제 취소 (CancelDao) 만들기
package home.beans;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
public class CancelDao {
public static final String USERNAME = "계정아이디", PASSWORD = "계정비밀번호";
//1. 결제 취소 기능(C)
public void insert(int historyNo) throws Exception {
Connection con = JdbcUtils.connect(USERNAME, PASSWORD);
String sql = "insert into cancel values(?)";
PreparedStatement ps = con.prepareStatement(sql);
ps.setInt(1, historyNo);
ps.execute();
con.close();
}
//2. 결제 취소 가능 여부 확인 기능(R)
//= true가 반환되면 데이터가 없어서 결제 취소가 가능하다는 의미이다.
//= false가 반환되면 데이터가 있어서 결제 취소가 불가능하다는 의미이다.
public boolean available(int historyNo) throws Exception {
Connection con = JdbcUtils.connect(USERNAME, PASSWORD);
String sql = "select * from cancel where history_no = ?";
PreparedStatement ps = con.prepareStatement(sql);
ps.setInt(1, historyNo);
ResultSet rs = ps.executeQuery();
boolean exist = rs.next();
con.close();
return !exist;
}
}
- 포인트 취소 처리 (PointCancelServlet.java) 만들기
package home.servlet.point;
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 home.beans.CancelDao;
import home.beans.HistoryDao;
import home.beans.HistoryDto;
import home.beans.MemberDao;
@WebServlet(urlPatterns = "/point/cancel.txt")
public class PointCancelServlet extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
try {
//입력 : historyNo
int historyNo = Integer.parseInt(req.getParameter("historyNo"));
//처리
CancelDao cancelDao = new CancelDao();
if(cancelDao.available(historyNo)) {//취소가 가능하다면
cancelDao.insert(historyNo);//취소
//회원 포인트도 차감(historyNo ---> historyAmount ---> 차감)
HistoryDao historyDao = new HistoryDao();
HistoryDto historyDto = historyDao.get(historyNo);
MemberDao memberDao = new MemberDao();
memberDao.addPoint(historyDto.getMemberId(), -historyDto.getHistoryAmount());
//memberDao.removePoint(historyDto.getMemberId(), historyDto.getHistoryAmount());
//memberDao.refreshPoint(historyDto.getMemberId());
//성공페이지로 이동
resp.sendRedirect("cancel_success.jsp");
}
else {//취소가 불가능하다면(이미 취소된 내역이라면)
//오류페이지로 이동
resp.sendRedirect("cancel_fail.jsp");
}
}
catch(Exception e) {
e.printStackTrace();
resp.sendError(500);
}
}
}
- 포인트 취소 성공 페이지 (cancel_success.jsp) 만들기
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<jsp:include page="/template/header.jsp"></jsp:include>
<h2>결제 취소가 완료되었습니다.</h2>
<h5><a href="<%=request.getContextPath()%>">메인 페이지로</a></h5>
<h5><a href="<%=request.getContextPath()%>/member/mypage.jsp">내 정보 보기</a></h5>
<jsp:include page="/template/footer.jsp"></jsp:include>
- 포인트 취소 실패 페이지 (cancel_fail.jsp) 만들기
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<jsp:include page="/template/header.jsp"></jsp:include>
<h2>결제 취소 실패 - 이미 취소된 내역입니다.</h2>
<h5><a href="<%=request.getContextPath()%>">메인 페이지로</a></h5>
<h5><a href="<%=request.getContextPath()%>/member/mypage.jsp">내 정보 보기</a></h5>
<jsp:include page="/template/footer.jsp"></jsp:include>
- 내 정보 보기 (mypage.jsp) 코드 수정
SQL에 코드 먼저 입력
create view total_history as select
H.*,
nvl2(C.history_no, '취소불가', '취소가능') "cancel"
from history H left outer join cancel C on h.history_no = C.history_no;
<%@page import="home.beans.TotalHistoryDto"%>
<%@page import="home.beans.TotalHistoryDao"%>
<%@page import="java.text.DecimalFormat"%>
<%@page import="java.text.Format"%>
<%@page import="home.beans.HistoryDto"%>
<%@page import="home.beans.HistoryDao"%>
<%@page import="java.util.List"%>
<%@page import="home.beans.MemberDto"%>
<%@page import="home.beans.MemberDao"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%-- 입력 : 현재 로그인한 회원ID - String memberId --%>
<%
String memberId = (String) session.getAttribute("ses");
%>
<%-- 처리 : 회원정보(MemberDto) --%>
<%
MemberDao memberDao = new MemberDao();
MemberDto memberDto = memberDao.get(memberId);
// 새롭게 만든 뷰(total_history)를 이용하여 포인트 이력을 조회
TotalHistoryDao historyDao = new TotalHistoryDao();
List<TotalHistoryDto> historyList = historyDao.findByMemberId(memberId);
%>
<%-- 출력 --%>
<jsp:include page="/template/header.jsp"></jsp:include>
<h2>회원 상세 정보</h2>
<table border="1" width="300">
<tbody>
<tr>
<th width="25%">아이디</th>
<td><%=memberDto.getMemberId()%></td>
</tr>
<tr>
<th>닉네임</th>
<td><%=memberDto.getMemberNick()%></td>
</tr>
<tr>
<th>생년월일</th>
<td><%=memberDto.getMemberBirthDay()%></td>
</tr>
<tr>
<th>이메일</th>
<td><%=memberDto.getMemberEmailString()%></td>
</tr>
<tr>
<th>전화번호</th>
<td><%=memberDto.getMemberPhoneString()%></td>
</tr>
<tr>
<th>가입일시</th>
<td><%=memberDto.getMemberJoin()%></td>
</tr>
<tr>
<th>포인트</th>
<td><%=memberDto.getMemberPoint()%></td>
</tr>
<tr>
<th>등급</th>
<td><%=memberDto.getMemberGrade()%></td>
</tr>
</tbody>
</table>
<h3><a href="password.jsp">비밀번호 변경</a></h3>
<h3><a href="edit.jsp">개인정보 변경</a></h3>
<h3><a href="check.jsp">회원 탈퇴</a></h3>
<hr>
<!-- 포인트 내역 출력 -->
<h2>포인트 상세 내역</h2>
<table border="1" width="500">
<thead>
<tr>
<th>일시</th>
<th>금액</th>
<th>메모</th>
<th>cancel</th>
<th>취소</th>
</tr>
</thead>
<tbody>
<%Format f = new DecimalFormat("#,##0"); %>
<%for(TotalHistoryDto historyDto : historyList) { %>
<tr>
<td align="center"><%=historyDto.getHistoryTime()%></td>
<td align="right"><%=f.format(historyDto.getHistoryAmount())%></td>
<td align="left"><%=historyDto.getHistoryMemo()%></td>
<td><%=historyDto.getCancel()%></td>
<td>
<%if(historyDto.available()){ %>
<a href="../point/cancel.txt?historyNo=<%=historyDto.getHistoryNo()%>">취소</a>
<a href="<%=request.getContextPath()%>/point/cancel.txt?historyNo=<%=historyDto.getHistoryNo()%>">취소</a>
<%} %>
</td>
</tr>
<%} %>
</tbody>
</table>
<jsp:include page="/template/footer.jsp"></jsp:include>
홈페이지 - 관리자 기초 처리
SQL에 관리자로 먼저 설정하기위해 회원가입후 관리자 지정해주기
update member set member_grade='관리자' where member_id = 'homemaster';
- 관리자만 접속 가능 한 필터 (AdminFilter.java) 만들기
package home.filter;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
@WebFilter(urlPatterns = {"/admin/*"})
public class AdminFilter implements Filter{
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
/**
현재 세션에는 ses라는 이름으로 회원 아이디가 저장되어 있음
관리자인지 확인하려면
[1] 회원아이디를 이용하여 단일조회 실시(DB 접속)
[2] 로그인 성공 시 세션에 회원 권한(grade)도 저장
우리는 [2]를 사용하여 처리한다.
*/
HttpServletRequest req = (HttpServletRequest)request;
HttpServletResponse resp = (HttpServletResponse)response;
HttpSession session = req.getSession();
String grade = (String)session.getAttribute("grade");
boolean admin = grade != null && grade.equals("관리자");
if(admin) {
chain.doFilter(request, response);
}
else {
resp.sendError(403);//forbidden, 권한 부족
}
}
}
- hearder.jsp 코드 수정해서 grade 란 추가
String grade = (String)session.getAttribute("grade");
boolean admin = grade != null && grade.equals("관리자");
<h3>Apple 공식사이트 (ses = <%=ses%>, grade = <%=grade%>, login = <%=login%>)</h3>
- MemberLoginServlet에 로그인 시 회원 정보인 회원 등급을 grade라는 이름으로 저장
( 관리자 / 일반회원 구분하기 )
req.getSession().setAttribute("grade", memberDto.getMemberGrade());
- MemberQuitServlet, MemberLogoutServlet에 회원탈퇴, 로그아웃 시
사용자의 등급 정보를 삭제하기 추가
req.getSession().removeAttribute("grade");
- 관리자 메인 페이지 (home.jsp) 만들기
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<jsp:include page="/template/header.jsp"></jsp:include>
<h2>관리자 메인 페이지</h2>
<h4><a href="#">포인트상품 관리</a></h4>
<h4><a href="#">회원 관리</a></h4>
<h4><a href="#">사이트 통계</a></h4>
<jsp:include page="/template/footer.jsp"></jsp:include>
'Java 웹 개발' 카테고리의 다른 글
21.10.25 - 웹 개발 입문 51일차 (0) | 2021.10.25 |
---|---|
21.10.22 - 웹 개발 입문 50일차 (0) | 2021.10.23 |
21.10.20 - 웹 개발 입문 48일차 (0) | 2021.10.21 |
21.10.19 - 웹 개발 입문 47일차 (0) | 2021.10.19 |
21.10.18 - 웹 개발 입문 46일차 (0) | 2021.10.18 |