[JSP] 웹 쇼핑몰 페이지 만들기 (2)

yeju·2023년 6월 22일
0

연습

목록 보기
5/7

📝 Step 7. 다국어 처리

상품 등록 페이지의 언어를 한국어/영어 전환 가능하게 만들기
JSTL fmt 태그메세지 처리 태그 를 이용해 구현한다. 라이브러리 파일과 언어별로 메세지를 저장해놓은 리소스 번들 파일 (*.properties)이 필요하다.

1. 한글/영문 리소스번들 작성하기

src/main/java/resourceBundle 패키지에 저장

파일명 : message.properties

title = 상품 등록
productId = 상품 코드
pname = 상품명
unitPrice = 가격
description = 상세 설명
manufacturer = 제조사

...
파일명 : message_en.properties

title = Product Addition
productId = Product ID
pname = Name
unitPrice = Unit Price
description = Description
manufacturer = Manufacturer

...

2. 상품 등록 페이지 다국어 처리


JSTL 라이브러리 jstl-1.2.jar/webapp/WEB-INF/lib 폴더에 저장
상품 등록 페이지 addProduct.jsptaglib 태그를 추가
fmt 태그를 사용해 미리 만들어둔 번들 파일을 등록하고 다국어 처리할 부분 태그 수정

<fmt:setLocale value="적용할 언어 이름" />
<fmt:bundle basename="리소스 번들 이름(_언어명 제외)">
	<fmt:message key="키 이름" />
</fmt:bundle>
[수정 전]
...
<div class="form-group row">
	<label class="col-sm-2">상품 코드</label>
</div>
...
  
[수정 후]
<fmt:setLocale value='<%= request.getParameter("language") %>' />
<fmt:bundle basename="resourceBundle.message">
    ...
	<div class="form-group row">
		<label class="col-sm-2"><fmt:message key="productId" /></label>
	</div>
    ...
</fmt:bundle>
[언어 전환 메뉴 추가]
...
<div class="container">
  <div class="text-right">
      <a href="?language=ko">한국어</a> | <a href="?language=en">English</a>
  </div>
...

전체 코드

파일명 : addProduct.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!-- taglib 디렉티브 태그로 사용할 태그 라이브러리 연결 -->
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
  
...

  <body>
	
  <fmt:setLocale value='<%= request.getParameter("language") %>' />
  <fmt:bundle basename="resourceBundle.message">

    <!-- menu -->
    <jsp:include page="menu.jsp" />

    <!-- jumbotron -->
    <div class="jumbotron">
      <div class="container">
        <h1 class="display-3"><fmt:message key="title"/></h1>
      </div>
    </div>

    <div class="container">
      <div class="text-right">
        <a href="?language=ko">한국어</a> | <a href="?language=en">English</a>
      </div>
      <form name="newProduct" action="./processAddProduct.jsp" class="form-horizontal" method="post" enctype="multipart/form-data">
        <div class="form-group row">
          <label class="col-sm-2"><fmt:message key="productId" /></label>
          <div class="col-sm-3">
            <input type="text" name="productId" class="form-control">
          </div>
        </div>
        <div class="form-group row">
          <label class="col-sm-2"><fmt:message key="pname" /></label>
          <div class="col-sm-3">
            <input type="text" name="name" class="form-control">
          </div>
        </div>
        <div class="form-group row">
          <label class="col-sm-2"><fmt:message key="unitPrice" /></label>
          <div class="col-sm-3">
            <input type="text" name="unitPrice" class="form-control">
          </div>
        </div>
        <div class="form-group row">
          <label class="col-sm-2"><fmt:message key="description" /></label>
          <div class="col-sm-5">
            <textarea name="description" cols="50" rows="2" class="form-control"></textarea>
          </div>
        </div>
        <div class="form-group row">
          <label class="col-sm-2"><fmt:message key="manufacturer" /></label>
          <div class="col-sm-3">
            <input type="text" name="manufacturer" class="form-control">
          </div>
        </div>
        <div class="form-group row">
          <label class="col-sm-2"><fmt:message key="category" /></label>
          <div class="col-sm-3">
            <!--<input type="text" name="category" class="form-control"> -->
            <select name="category" class="custom-select">
              <option value="Smart Phone"><fmt:message key="category_SmartPhone" /></option>
              <option value="Notebook"><fmt:message key="category_Notebook" /></option>
              <option value="Tablet"><fmt:message key="category_Tablet" /></option>
              <option value="Others"><fmt:message key="category_Others" /></option>
            </select>
          </div>
        </div>
        <div class="form-group row">
          <label class="col-sm-2"><fmt:message key="unitsInStock" /></label>
          <div class="col-sm-3">
            <input type="text" name="unitsInStock" class="form-control">
          </div>
        </div>
        <div class="form-group row">
          <label class="col-sm-2"><fmt:message key="condition" /></label>
          <div class="col-sm-5">
            <input type="radio" name="condition" value="New">
            <fmt:message key="condition_New" />
            <input type="radio" name="condition" value="Old">
            <fmt:message key="condition_Old" />
            <input type="radio" name="condition" value="Refurbished">
            <fmt:message key="condition_Refurbished" />
          </div>
        </div>
        <div class="form-group row">
          <label class="col-sm-2"><fmt:message key="productImage" /></label>
          <div class="col-sm-5">
            <input type="file" name="productImage" class="form-control">
          </div>
        </div>
        <div class="form-group row">
          <div class="col-sm-offset-2 col-sm-10">
            <input type="submit" class="btn btn-primary" value="<fmt:message key="button" />">
          </div>
        </div>
      </form>
      <hr>
    </div>
  </fmt:bundle>
  

📝 Step 8. 시큐리티 처리

상품 등록 페이지에 접근할 시 로그인을 통해 접근 권한을 인증하는 기능을 추가한다.
web.xml 파일에 보안 구성을 작성해 구현한다.

1. 웹 서버에 사용자 역할 설정, web.xml 에 보안 구성 작성

Servers/Tomcat v9.0 Server at localhost-config 폴더의 tomcat-users.xml 에서
웹 서버의 사용자와 역할 설정

<tomcat-users>
  ...
  <role rolename="tomcat"/>
  <role rolename="role1"/>
  <role rolename="admin"/>
  <user username="tomcat" password="tomcat" roles="tomcat"/>
  <user username="both" password="both" roles="tomcat,role1"/>
  <user username="role1" password="role1" roles="role1"/>
  <user username="admin" password="admin" roles="admin"/>
  ...
</tomcat-users>

프로젝트 폴더의 web.xml보안 구성 작성

<web-app>
  ...
  <!-- 시큐리티 처리할 역할 지정 -->
  <security-role>
  	<description></description>
  	<role-name>admin</role-name>
  </security-role>
  <!-- 시큐리티 처리 내용 정의 -->
  <security-constraint>
  	<display-name>WebMarket Security</display-name>
  	<!-- 어떤 리소스에 접근할 때 보안 처리할지 지정 -->
  	<web-resource-collection>
  		<web-resource-name>WebMarket</web-resource-name>
  		<description></description>
  		<url-pattern>/addProduct.jsp</url-pattern>
  	</web-resource-collection>
  	<!-- 누가 접근할 때 허락할지 지정 -->
  	<auth-constraint>
  		<description>권한 관리자명</description>
  		<role-name>admin</role-name>
  	</auth-constraint>
  </security-constraint>
  <!-- 인증 방식 지정 -->
  <login-config>
  	<!-- 폼 태그에 입력받아 인증(페이지 따로 필요) -->
  	<auth-method>FORM</auth-method>
  	<form-login-config>
  		<form-login-page>/login.jsp</form-login-page>
  		<form-error-page>/login_failed.jsp</form-error-page>
  	</form-login-config>
  </login-config>
  ...
<web-app>
  

2. 로그인 페이지 구현


인증 페이지로 설정한 login.jsp , login_failed.jsp 페이지 구현
form 태그의 속성은 action="j_security_check"
아이디 input 태그의 속성은 name="j_username"
비밀번호 input 태그의 속성은 name="j_password" 로 필수 지정

파일명 : login.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Login</title>
<link rel="stylesheet" href="./resources/css/bootstrap.min.css">
</head>
<body>
	<!-- menu -->
    <jsp:include page="menu.jsp" />
    
    <!-- jumbotron -->
    <div class="jumbotron">
        <div class="container">
            <h1 class="display-3">로그인</h1>
        </div>
    </div>
    
    <div class="container" align="center">
    	<div class="col-md-4 col-md-offset-4">
    		<h3 class="form-signin-heading">Please sign in</h3>
    		<%
    			String error = (String) session.getAttribute("error");
    			if(error != null) {
    				// error 값이 존재하면 해당 내용 실행
    				out.println("<div class='alert alert-danger'>");
    				out.println("아이디와 비밀번호를 확인해 주세요.");
    				out.println("</div>");
    			}
    		%>
    		<form class="form-signin" action="j_security_check" method="post">
    			<div class="form-group">
    				<label for="inputUserName" class="sr-only">User Name</label>
    				<input type="text" class="form-control" placeholder="ID" name="j_username" required autofocus>
    			</div>
    			<div class="form-group">
    				<label for="inputPassword" class="sr-only">Password</label>
    				<input type="password" class="form-control" placeholder="Password" name="j_password" required>
    			</div>
    			<button class="btn btn-lg btn-success btn-block" type="submit">로그인</button>
    		</form>
    	</div>
    </div>
    
    <!-- footer -->
    <jsp:include page="footer.jsp" />
</body>
</html>
파일명 : login_failed.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
	// error 파라미터를 가지고 로그인 페이지로 다시 이동(오류 메세지 출력)
	session.setAttribute("error","1");
	response.sendRedirect("login.jsp");
%>

상품 등록 페이지에 로그아웃 버튼 추가

파일명 : addProduct.jsp

...
<div class="container">
    <div class="text-right">
    	<a href="?language=ko">한국어</a> | <a href="?language=en">English</a>
    	<a href="logout.jsp" class="btn btn-sm btn-success pull-right ml-2"><fmt:message key="logout" /></a>
    </div>
...
</div>
...

📝 Step 9. 예외 처리

상품 상세 페이지에서 ?id=상품 아이디 로 상품 정보를 출력하는데, 이 때 상품 특정을 위한 id값이 잘못되었을 때접근하려는 페이지 주소가 없을 때 보여줄 오류 페이지를 만들어 연결한다.

1. 오류 페이지 작성

파일명 : exceptionNoProductId.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="./resources/css/bootstrap.min.css">
</head>
<body>
	<!-- menu -->
    <jsp:include page="menu.jsp" />
    
    <!-- jumbotron -->
    <div class="jumbotron">
        <div class="container">
            <h2 class="alert alert-danger">해당 상품이 존재하지 않습니다.</h2>
        </div>
    </div>

    <div class="container">
    	<p><%= request.getRequestURL() %>?<%= request.getQueryString() %></p>
    	<p><a href="products.jsp" class="btn btn-secondary">상품 목록 &raquo;</a></p>
    </div>
</body>
</html>
파일명 : exceptionNoPage.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="./resources/css/bootstrap.min.css">
</head>
<body>
	<!-- menu -->
    <jsp:include page="menu.jsp" />
    
    <!-- jumbotron -->
    <div class="jumbotron">
        <div class="container">
            <h2 class="alert alert-danger">요청하신 페이지를 찾을 수 없습니다.</h2>
        </div>
    </div>

    <div class="container">
    	<p><%= request.getRequestURL() %></p>
    	<p><a href="products.jsp" class="btn btn-secondary">상품 목록 &raquo;</a></p>
    </div>
</body>
</html>

2. 오류 페이지 호출하도록 코드 수정하기

상품 상세 페이지의 errorPage 속성으로 오류 페이지 연결
web.xml 에 404 오류 코드 처리 페이지 연결

파일명 : product.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%-- 에러 발생하면 이동할 페이지 추가 --%>
<%@ page errorPage="exceptionNoProductId.jsp" %>
...
파일명 : web.xml

<web-app>
	...
	<!-- 예외 처리 설정 -->
	<error-page>
  		<error-code>404</error-code>
  		<location>/exceptionNoPage.jsp</location>
	</error-page>
</web-app>

📝 Step 10. 로그 파일 만들기

필터를 이용하여 페이지에 접근할 때마다 내용을 기록하는 로그 파일을 작성한다.
해당 내용을 필터 클래스로 구현하고 web.xml 에 내용을 작성한다. 파일 형태로 출력하기 위해 java.io 패키지의 FileWriter , PrintWriter 클래스를 이용한다.

1. 필터로 사용할 클래스 작성

package filter;

import javax.servlet.*;
import javax.servlet.http.*;
import java.util.*;
import java.io.IOException;
import java.io.FileWriter;
import java.io.PrintWriter;
import java.text.DateFormat;
import java.text.SimpleDateFormat;

public class LogFileFilter implements Filter {
	
	PrintWriter writer;

	@Override
	public void destroy() {
		// 다 쓴 스트림 닫아주기
		writer.close();
	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {
		writer.println("  접속한 클라이언트 IP : " + request.getRemoteAddr());
		
		long start = System.currentTimeMillis();
		writer.println("  접근한 URL 경로 : " + getURLPath(request));
		writer.println("  요청 처리 시작 시각 : " + getCurrentTime());
		
		chain.doFilter(request, response);
		
		long end = System.currentTimeMillis();
		writer.println("  요청 처리 종료 시각 : " + getCurrentTime());
		writer.println("  요청 처리 소요 시간 : " + (end-start) + "ms");
		writer.println("========================================");
	}

	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
		// web.xml에 설정해둔 파일 경로+파일명 가져오기
		String filename = filterConfig.getInitParameter("filename");
		
		if(filename == null) {
			throw new ServletException("로그 파일의 이름을 찾을 수 없습니다.");
		}
		
		// 내용을 작성할 로그 파일을 새로 생성하기
		try {
			writer = new PrintWriter(new FileWriter(filename, true), true);
		} catch (IOException e) {
			throw new ServletException("로그 파일을 열 수 없습니다.");
		}
		
		System.out.println("로그 파일을 찾았습니다.");
	}
	
	private String getURLPath(ServletRequest request) {
		HttpServletRequest req;
		String currentPath = "";
		String queryString = "";
		if(request instanceof HttpServletRequest) {
			req = (HttpServletRequest) request;
			currentPath = req.getRequestURI();
			queryString = req.getQueryString();
			queryString = (queryString == null) ? "" : "?" + queryString;
		}
		return currentPath + queryString;
	}
	
	private String getCurrentTime() {
		DateFormat formatter = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
		Calendar calendar = Calendar.getInstance();
		calendar.setTimeInMillis(System.currentTimeMillis());
		return formatter.format(calendar.getTime());
	}
	
}

2. web.xml 파일에 필터 설정

파일명 : web.xml

<web-app>
	...
	<filter>
 	<!-- 필터 이름과 필터로 사용할 클래스 지정 -->
  	<filter-name>LogFileFilter</filter-name>
  	<filter-class>filter.LogFileFilter</filter-class>
  	<!-- 초기 파라미터 설정 -->
  	<init-param>
  		<param-name>filename</param-name>
  		<param-value>C:\\logs\\webmarket.log</param-value>
  	</init-param>
  </filter>
  <!-- 필터를 적용할 리소스 지정 -->
  <filter-mapping>
  	<filter-name>LogFileFilter</filter-name>
  	<!-- webapp 안의 모든 페이지에 적용 -->
  	<url-pattern>/*</url-pattern>
  </filter-mapping>
</web-app>


📝 Step 11. 장바구니 페이지 만들기

장바구니에 상품을 추가하고 세션의 속성을 이용해 추가한 상품들을 장바구니 페이지에서 확인하거나 삭제할 수 있도록 한다.

1. 상품 클래스에 멤버 변수 추가

public class Product implements Serializable {
	...
	private int quantity; // 장바구니에 담은 개수
    ...
    // getter/setter
    public int getQuantity() {
		return quantity;
	}
	public void setQuantity(int quantity) {
		this.quantity = quantity;
	}
}

2. 상품 상세 페이지

상품 상세 페이지에 장바구니에 추가 버튼, 장바구니 페이지 이동 버튼 추가

파일명 : product.jsp

<script>
  function addToCart() {
  	if (confirm("상품을 장바구니에 추가하시겠습니까?")) {
  		// addForm 폼 태그 제출하기
  		document.addForm.submit();
  	} else {
  		document.addForm.reset();
  	}
  }
</script>

...
<h4><%= rs.getInt("p_unitPrice") %>원</h4>
<p>
    <!-- 제출을 위해 form 태그로 수정 -->
    <!-- 제출 시 상품 아이디 가지고 addCart.jsp로 이동 -->
  	<form name="addForm" action="./addCart.jsp?id=<%= rs.getString("p_id") %>" method="post">
		<a href="#" class="btn btn-info" onclick="addToCart()">상품 주문 &raquo;</a>
		<a href="./cart.jsp" class="btn btn-warning">장바구니 &raquo;</a>
		<a href="./products.jsp" class="btn btn-secondary">상품 목록 &raquo;</a>
	</form>
</p>
...

3. 장바구니 등록 처리 페이지 작성

파일명 : addCart.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="java.util.ArrayList" %>
<%@ page import="dto.Product" %>
<%@ page import="dao.ProductRepository" %>
<%
	// 상품 id 받아오기
	String id = request.getParameter("id");
	
	// id 값이 존재하지 않거나 공백이면
	if(id == null || id.trim().equals("")) {
		response.sendRedirect("products.jsp");
		return;
	}
	
	ProductRepository dao = ProductRepository.getInstance();
	
	Product product = dao.getProductById(id);
	if(product == null) {
		// id에 해당하는 상품이 존재하지 않으면 해당 에러 페이지로 이동
		response.sendRedirect("exceptionNoProductId.jsp");
	}
	
	ArrayList<Product> goodsList = dao.getAllProducts();
	
	Product goods = new Product();
	// 전체 상품 목록에서 다시 해당 상품이 있는지 체크하고 goods에 주소 담기
	for(int i=0; i<goodsList.size(); i++) {
		goods = goodsList.get(i);
		if (goods.getProductId().equals(id)) {
			break;
		}
	}
	
	// 세션에서 cartlist 속성 가져와 list에 주소 담기
	ArrayList<Product> list = (ArrayList<Product>) session.getAttribute("cartlist");
	// 없으면 ArrayList 새로 만들어 세션 속성으로 저장 
	if(list == null) {
		list = new ArrayList<Product>();
		session.setAttribute("cartlist", list);
	}
	
	int cnt = 0;
	Product goodsQnt = new Product();
	// 장바구니 목록에서 수량 체크하기
	for(int i=0; i<list.size(); i++) {
		goodsQnt = list.get(i);
		// 추가하려는 상품과 동일한 상품이 list에 있으면
		if(goodsQnt.getProductId().equals(id)) {
			cnt++;
			// cnt 1 증가
			int orderQuantity = goodsQnt.getQuantity() + 1;
			// 수량 수정
			goodsQnt.setQuantity(orderQuantity);
		}
	}
	
	if(cnt == 0) {
		// 동일한 상품이 없으면 아까 만든 goods를 수량 1로 설정하고 list에 추가
		goods.setQuantity(1);
		list.add(goods);
	}
	
	response.sendRedirect("product.jsp?id="+id);
%>

4. 장바구니 페이지 작성

파일명 : cart.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="java.util.ArrayList" %>
<%@ page import="dto.Product" %>
<%@ page import="dao.ProductRepository" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<!-- 세션 id 가져오기 -->
<%
	String cartId = session.getId();
%>
<title>장바구니</title>
<link rel="stylesheet" href="./resources/css/bootstrap.min.css">
</head>
<body>
	<!-- menu -->
    <jsp:include page="menu.jsp" />
    
    <!-- jumbotron -->
    <div class="jumbotron">
        <div class="container">
            <h1 class="display-3">장바구니</h1>
        </div>
    </div>

    <div class="container">
    	<div class="row">
    		<table width="100%;">
    			<tr>
    				<td align="left"><a href="./deleteCart.jsp?cartId=<%= cartId %>" class="btn btn-danger">삭제하기</a></td>
    				<td align="right"><a href="#" class="btn btn-success">주문하기</a></td>
    			</tr>
    		</table>
    	</div>
    	<div style="padding-top:50px;">
    		<table class="table table-hover">
    			<tr>
    				<th>상품</th>
    				<th>가격</th>
    				<th>수량</th>
    				<th>소계</th>
    				<th>비고</th>
    			</tr>
    			<%
					int sum = 0;
    			// 세션에서 cartlist 속성 가져오기
    			ArrayList<Product> cartList = (ArrayList<Product>) session.getAttribute("cartlist");
    			for(int i=0; i<cartList.size(); i++) {
    				// 장바구니 목록 하나씩 출력하기
    				Product product = cartList.get(i);
    				int total = product.getUnitPrice() * product.getQuantity();
    				sum += total;
    			%>
    			
    			<tr>
    				<td><%= product.getProductId() %> - <%= product.getPname() %></td>
    				<td><%= product.getUnitPrice() %></td>
    				<td><%= product.getQuantity() %></td>
    				<td><%= total %></td>
    				<td><a href="./removeCart.jsp?id=<%= product.getProductId() %>" class="badge badge-danger">삭제</a></td>
    			</tr>
    			
    			<%
    			}
				%>
				<tr>
					<th></th>
					<th></th>
					<th>총액</th>
					<th><%= sum %></th>
					<th></th>
				</tr>				
    		</table>
    		<a href="./products.jsp" class="btn btn-secondary">&laquo; 쇼핑 계속하기</a>
    	</div>
    	<hr>
    </div>
    
    <!-- footer -->
    <jsp:include page="footer.jsp" />
</body>
</html>

5. 개별 상품 장바구니에서 삭제, 장바구니 전체 삭제 처리 페이지 작성

개별 상품 장바구니에서 삭제

파일명 : removeCart.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="java.util.ArrayList" %>
<%@ page import="dto.Product" %>
<%@ page import="dao.ProductRepository" %>
<%
	// 상품 id 받아오기
	String id = request.getParameter("id");
	
	// id 값이 존재하지 않거나 공백이면
	if(id == null || id.trim().equals("")) {
		response.sendRedirect("products.jsp");
		return;
	}
	
	ProductRepository dao = ProductRepository.getInstance();
	
	Product product = dao.getProductById(id);
	if(product == null) {
		// id에 해당하는 상품이 존재하지 않으면 해당 에러 페이지로 이동
		response.sendRedirect("exceptionNoProductId.jsp");
	}
	
	ArrayList<Product> cartList = (ArrayList<Product>) session.getAttribute("cartlist");
	
	Product goodsQnt = new Product();
	for(int i=0; i<cartList.size(); i++) {
		goodsQnt = cartList.get(i);
		// 삭제하려는 상품과 동일한 상품이 list에 있으면
		if(goodsQnt.getProductId().equals(id)) {
			cartList.remove(goodsQnt);
		}
	}
	
	response.sendRedirect("cart.jsp");
%>

장바구니 전체 삭제

파일명 : deleteCart.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="dto.Product" %>
<%@ page import="dao.ProductRepository" %>
<%
	// 장바구니 id 받아오기
	String id = request.getParameter("cartId");
	
	// id 값이 존재하지 않거나 공백이면
	if(id == null || id.trim().equals("")) {
		response.sendRedirect("cart.jsp");
		return;
	}
	
	// 세션의 모든 속성 삭제
	session.invalidate();
	
	response.sendRedirect("cart.jsp");
%>

📝 Step 12. 주문 처리 페이지 만들기

쿠키를 이용해 배송 정보, 주문 정보, 주문 완료/취소 페이지 작성

1. 장바구니 페이지 수정, 배송 정보 입력 페이지 작성


장바구니 페이지 cart.jsp 에서 주문하기 버튼을 누르면 배송 정보 입력 페이지 shippingInfo.jsp세션 id 를 파라미터로 가지고 이동

파일명: cart.jsp

...
<tr>
	<td align="left">
      <a href="./deleteCart.jsp?cartId=<%= cartId %>" class="btn btn-danger">삭제하기</a>
  </td>
	<td align="right">
      <a href="./shippingInfo.jsp?cartId=<%= cartId %>" class="btn btn-success">주문하기</a>
  </td>
</tr>
...

파일명 : shippingInfo.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="./resources/css/bootstrap.min.css">
</head>
<body>	
	<!-- menu -->
    <jsp:include page="menu.jsp" />
    
    <!-- jumbotron -->
    <div class="jumbotron">
        <div class="container">
            <h1 class="display-3">배송 정보</h1>
        </div>
    </div>
 
    <div class="container">
      	<!-- 제출 시 입력받은 파라미터를 가지고 processShippingInfo.jsp 로 이동 -->
    	<form action="./processShippingInfo.jsp" class="form-horizontal" method="post">
    		<input type="hidden" name="cartId" value="<%= request.getParameter("cartId") %>">
    		<div class="form-group row">
    			<label class="col-sm-2">성명</label>
    			<div class="col-sm-3">
    				<input type="text" name="name" class="form-control">
    			</div>
    		</div>
    		<div class="form-group row">
    			<label class="col-sm-2">배송일</label>
    			<div class="col-sm-3">
    				<input type="text" name="shippingDate" class="form-control">
    			</div> (yyyy/mm/dd)
    		</div>
    		<div class="form-group row">
    			<label class="col-sm-2">국가</label>
    			<div class="col-sm-3">
    				<input type="text" name="country" class="form-control">
    			</div>
    		</div>
    		<div class="form-group row">
    			<label class="col-sm-2">우편번호</label>
    			<div class="col-sm-3">
    				<input type="text" name="zipCode" class="form-control">
    			</div>
    		</div>
    		<div class="form-group row">
    			<label class="col-sm-2">주소</label>
    			<div class="col-sm-5">
    				<input type="text" name="addressName" class="form-control">
    			</div>
    		</div>
    		<div class="form-group row">
    			<div class="col-sm-offset-2 col-sm-10">
    				<a href="./cart.jsp?cartId=<%= request.getParameter("cartId") %>" class="btn btn-secondary" role="button">이전</a>
    				<input type="submit" class="btn btn-primary" value="등록">
    				<a href="./checkOutCancelled.jsp" class="btn btn-secondary" role="button">취소</a>
    			</div>
    		</div>
    	</form>
    	<hr>
    </div>
    
    <!-- footer -->
    <jsp:include page="footer.jsp" />
</body>
</html>

2. 배송 정보 등록 처리 페이지 작성

입력받은 배송 정보를 쿠키로 만들어 유효 시간을 설정하고 response에 추가해 orderConfirmation.jsp 페이지로 이동

파일명 : processShippingInfo.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="java.net.URLEncoder" %>
<%
	request.setCharacterEncoding("utf-8");
	
	Cookie cartId = new Cookie("Shipping_cartId", URLEncoder.encode(request.getParameter("cartId"), "utf-8"));
	Cookie name = new Cookie("Shipping_name",URLEncoder.encode(request.getParameter("name"), "utf-8"));
	Cookie shippingDate = new Cookie("Shipping_shippingDate",URLEncoder.encode(request.getParameter("shippingDate"), "utf-8"));
	Cookie country = new Cookie("Shipping_country",URLEncoder.encode(request.getParameter("country"), "utf-8"));
	Cookie zipCode = new Cookie("Shipping_zipCode",URLEncoder.encode(request.getParameter("zipCode"), "utf-8"));
	Cookie addressName = new Cookie("Shipping_addressName",URLEncoder.encode(request.getParameter("addressName"), "utf-8"));
	
	// 쿠키의 유효 시간 설정
	cartId.setMaxAge(24*60*60); // 24시간
	name.setMaxAge(24*60*60);
	zipCode.setMaxAge(24*60*60);
	country.setMaxAge(24*60*60);
	addressName.setMaxAge(24*60*60);
	
	// 쿠키 추가
	response.addCookie(cartId);
	response.addCookie(name);
	response.addCookie(shippingDate);
	response.addCookie(zipCode);
	response.addCookie(country);
	response.addCookie(addressName);
	
	response.sendRedirect("orderConfirmation.jsp");
%>

3. 주문 정보 페이지 작성


이전 페이지에서 가져온 쿠키로 배송 정보 출력,
세션에서 장바구니 목록을 가져와 구매 상품을 출력하고 최종 주문 확인
주문 완료 클릭 시 주문 완료 페이지로,
취소 클릭 시 주문 취소 페이지로 이동

파일명 : orderConfirmation.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="java.util.ArrayList" %>
<%@ page import="java.net.URLDecoder" %>
<%@ page import="dto.Product" %>
<%@ page import="dao.ProductRepository" %>

<%
	request.setCharacterEncoding("utf-8");

	String cartId = session.getId();
	
	String shipping_cartId = "";
	String shipping_name = "";
	String shipping_shippingDate = "";
	String shipping_country = "";
	String shipping_zipCode = "";
	String shipping_addressName = "";
	
	Cookie[] cookies = request.getCookies();
	
	if(cookies != null) {
		for(int i=0; i<cookies.length; i++) {
			Cookie thisCookie = cookies[i];
			String n = thisCookie.getName();
			
			if(n.equals("Shipping_cartId")) {
				shipping_cartId = URLDecoder.decode((thisCookie.getValue()),"utf-8");
			}
			if(n.equals("Shipping_name")) {
				shipping_name = URLDecoder.decode((thisCookie.getValue()),"utf-8");
			}
			if(n.equals("Shipping_shippingDate")) {
				shipping_shippingDate = URLDecoder.decode((thisCookie.getValue()),"utf-8");
			}
			if(n.equals("Shipping_country")) {
				shipping_country = URLDecoder.decode((thisCookie.getValue()),"utf-8");
			}
			if(n.equals("Shipping_zipCode")) {
				shipping_zipCode = URLDecoder.decode((thisCookie.getValue()),"utf-8");
			}
			if(n.equals("Shipping_addressName")) {
				shipping_addressName = URLDecoder.decode((thisCookie.getValue()),"utf-8");
			}
		}
	}
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>주문 정보</title>
<link rel="stylesheet" href="./resources/css/bootstrap.min.css">
</head>
<body>
	<!-- menu -->
    <jsp:include page="menu.jsp" />
    
    <!-- jumbotron -->
    <div class="jumbotron">
        <div class="container">
            <h1 class="display-3">주문 정보</h1>
        </div>
    </div>

    <div class="container col-8 alert alert-info">
    	<div class="text-center">
    		<h1>영수증</h1>
    	</div>
    	<div class="row justify-content-between">
    		<div class="col-4" align="left">
    			<strong>배송 주소</strong><br>
    			성명 : <%= shipping_name %><br>
    			우편번호 : <%= shipping_zipCode %><br>
    			주소 : <%= shipping_addressName %> (<%= shipping_country %>)<br>
    		</div>
    		<div class="col-4" align="right">
    			<p><em>배송일: <%= shipping_shippingDate %></em></p>
    		</div>
    	</div>
    	<div>
    		<table class="table table-hover">
    			<tr>
    				<th class="text-center">상품</th>
    				<th class="text-center">수량</th>
    				<th class="text-center">가격</th>
    				<th class="text-center">소계</th>
    			</tr>
	    		<%
	    		int sum = 0;
	    		ArrayList<Product> cartList = (ArrayList<Product>) session.getAttribute("cartlist");
	    		
	    		if(cartList == null) {
	    			cartList = new ArrayList<Product>();
	    		}
	    		
	    		for(int i=0; i < cartList.size(); i++) {
	    			// 상품 리스트 하나씩 출력하기
	    			Product product = cartList.get(i);
	    			int total = product.getUnitPrice() * product.getQuantity();
	    			sum = sum + total;
	    		%>
				<tr>
					<td class="text-center"><em><%= product.getPname() %></em></td>
					<td class="text-center"><em><%= product.getQuantity() %></em></td>
					<td class="text-center"><em><%= product.getUnitPrice() %>원</em></td>
					<td class="text-center"><em><%= total %>원</em></td>
				</tr>    		
	    		<%
	    		}
	    		%>
	    		<tr>
	    			<td></td>
	    			<td></td>
	    			<td class="text-right"><strong>총액: </strong></td>
	    			<td class="text-center text-danger"><strong><%= sum %></strong></td>
	    		</tr>
   			</table>
   			
   			<a href="./ShippingInfo.jsp?cartId=<%= shipping_cartId %>" class="btn btn-secondary" role="button">이전</a>
   			<a href="./thankCustomer.jsp" class="btn btn-secondary" role="button">주문 완료</a>
   			<a href="./checkOutCancelled.jsp" class="btn btn-secondary" role="button">취소</a>
    	</div>
    	<hr>
    </div>
    
    <!-- footer -->
    <jsp:include page="footer.jsp" />
</body>
</html>

4. 주문 완료, 취소 페이지 작성


파일명 : thankCustomer.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="java.net.URLDecoder" %>

<%
	String shipping_cartId = "";
	String shipping_name = "";
	String shipping_shippingDate = "";
	String shipping_country = "";
	String shipping_zipCode = "";
	String shipping_addressName = "";
	
	Cookie[] cookies = request.getCookies();
	
	if(cookies != null) {
		for(int i=0; i<cookies.length; i++) {
			Cookie thisCookie = cookies[i];
			String n = thisCookie.getName();
			
			if(n.equals("Shipping_cartId")) {
				shipping_cartId = URLDecoder.decode((thisCookie.getValue()),"utf-8");
			}
			if(n.equals("Shipping_shippingDate")) {
				shipping_shippingDate = URLDecoder.decode((thisCookie.getValue()),"utf-8");
			}
		}
	}
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>주문 완료</title>
<link rel="stylesheet" href="./resources/css/bootstrap.min.css">
</head>
<body>
	<!-- menu -->
    <jsp:include page="menu.jsp" />
    
    <!-- jumbotron -->
    <div class="jumbotron">
        <div class="container">
            <h1 class="display-3">주문 완료</h1>
        </div>
    </div>
    
    <div class="container">
    	<h2 class="alert alert-danger">주문해주셔서 감사합니다.</h2>
    	<p>주문은 <%= shipping_shippingDate %>에 배송될 예정입니다!</p>
    	<p>주문번호 : <%= shipping_cartId %></p>
    </div>
    
    <div class="container">
    	<p><a href="./products.jsp" class="btn btn-secondary">&laquo; 상품 목록</a></p>
    </div>    
</body>
</html>
<%
	session.invalidate();

	if(cookies != null) {
		for(int i=0; i<cookies.length; i++) {
			Cookie thisCookie = cookies[i];
			String n = thisCookie.getName();
			
			if(n.equals("Customer_Id")) {
				thisCookie.setMaxAge(0);
			}
			if(n.equals("Customer_name")) {
				thisCookie.setMaxAge(0);
			}
			if(n.equals("Customer_phoneNumber")) {
				thisCookie.setMaxAge(0);
			}
			if(n.equals("Customer_country")) {
				thisCookie.setMaxAge(0);
			}
			if(n.equals("Customer_zipCode")) {
				thisCookie.setMaxAge(0);
			}
			if(n.equals("Customer_addressName")) {
				thisCookie.setMaxAge(0);
			}
			
			if(n.equals("Shipping_cartId")) {
				thisCookie.setMaxAge(0);
			}
			if(n.equals("Shipping_name")) {
				thisCookie.setMaxAge(0);
			}
			if(n.equals("Shipping_shippingDate")) {
				thisCookie.setMaxAge(0);
			}
			if(n.equals("Shipping_country")) {
				thisCookie.setMaxAge(0);
			}
			if(n.equals("Shipping_zipCode")) {
				thisCookie.setMaxAge(0);
			}
			if(n.equals("Shipping_addressName")) {
				thisCookie.setMaxAge(0);
			}
			
			response.addCookie(thisCookie);
		}
	}
%>
파일명 : checkOutCancelled.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="./resources/css/bootstrap.min.css">
</head>
<body>
	<!-- menu -->
    <jsp:include page="menu.jsp" />
    
    <!-- jumbotron -->
    <div class="jumbotron">
        <div class="container">
            <h1 class="display-3">주문 취소</h1>
        </div>
    </div>
    
    <div class="container">
    	<h2 class="alert alert-danger">주문이 취소되었습니다.</h2>
    </div>
    
    <div class="container">
    	<p><a href="./products.jsp" class="btn btn-secondary">&laquo; 상품 목록</a></p>
    </div>    
</body>
</html>
profile
🌱

0개의 댓글