빅데이터 Java 개발자 교육 - 54일차[JSP 실습 5(물품 주문하기)]

Jun_Gyu·2023년 4월 16일
0
post-thumbnail

이번 시간에는 물품과 물품들의 이미지 정보를 불러와 고객들이 주문을 할 수 있게 구성하고,

주문을 한 뒤에는 마이페이지의 4번째 주문내역의 목록에서 주문정보를 확인 가능하도록 기능을 구현 해보겠다.

물품 목록 생성하기

먼저 상품을 보여주는 메인 화면은 지난번 프론트엔드 학습 시간에 BootStrap예제를 이용하여 만들었다.

JSP

<div class="grid">
			<c:forEach var="obj" items="${list}">
			<a href="product.do?itemno=${obj.no}">
			 	<div class="item">
			 	<c:if test="${obj.imageNo != 0}">
			 		<img src="${pageContext.request.contextPath}/item/image?no=${obj.imageNo}"
			 			 style="width:100%; height:150px">
			 	</c:if>
			 	<c:if test="${obj.imageNo == 0}">
			 		<img src="${pageContext.request.contextPath}/resources/images.png"
			 			 style="width:100%; height:150px">
			 	</c:if>
			 		물품명 : ${obj.name}<br/>
			 		
			 		가격 : ${obj.price}원<br/>
			 		
			 		내용 : ${obj.content}<br/>
			 	</div>
			 </a>
			</c:forEach>
		</div>

그리드 박스 안에는 각 상품들의 제일 처음 등록된 사진과, 상품 설명들이 같이 출력되도록 코드를 구성했다.

또한 각각 이미지번호를 부여받아 서로 다른 이미지들이 나오도록 <c:forEach> 태그 사용했고, 만일 사진이 등록되지 않을시 기본이미지가 출력되도록 c:if문을 구성했다.

CSS

또한 화면에는 그리드 박스들이 일정한 간격을 유지하여 나오도록 위와같이 CSS의 스타일을 지정해줬다.

<style>
	.grid {
		display: grid;
		grid-template-columns: 1fr 1fr 1fr 1fr;
		column-gap: 10px;
		row-gap: 10px;
		
	}
	
	.item {
		padding: 10px;
		border: 1px solid #cccccc;
		min-height: 300px;
	}
	
	a {
		text-decoration: none;
		color: #111111;
	}
	
	a:hover .item {
		color: blue;
		border: 1px solid blue;
	}
</style>

지금까지는 물품 따로, 이미지 따로 DB에 저장해주었기 때문에, 외래키로 두가지 테이블을 묶어주고자 물품 DTO이미지번호를 저장할 변수를 생성해준다.

private long imageNo; // 대표 이미지번호를 저장할 임시변수

그 다음으로는 itemImageMapper에 item당 imageNo가 제일 작은 것을 반환하는 쿼리문 작성해주었다.

// 물품 이미지번호를 가장 작은것을 반환하며, 없을시 0을 반환.
	// 홈페이지 물품 이미지용
	@Select ( value = {
			 "	SELECT NVL(min(no),0) ",
			 "	FROM itemimage ",
			 "	WHERE itemno = #{itemno}	"
	} )
	public long selectItemImageMinOne(@Param("itemno") long itemno);

그리고 이렇게 Select된 물품들의 정보들을 CustomerHome 컨트롤러에서 반복문을 사용하여 list명칭에 결과를 담아 customer_home.jsp로 전송시켜 모두 출력되도록 구성해줬다.

protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		
	List<Item> list = MyBatisContext.getSqlSession().getMapper(ItemMapper.class)
    					.selectItemListAll();
	
	for(Item item: list) {
		// 먼저 대표 이미지번호를 저장해둘 변수를 Item dto에 생성해준뒤,
        // itemImageMapper에 이미지넘버를 불러오는 mapper를 작성한다.
		
		// mapper를 호출하여 해당물품의 가장 먼저 등록했던 이미지번호 1개를 가져온다.
		long imageNo = MyBatisContext.getSqlSession()
				  		.getMapper(ItemImageMapper.class)
				  		.selectItemImageMinOne(item.getNo());
		item.setImageNo(imageNo);
	}
	request.setAttribute("list", list);
	request.getRequestDispatcher("/WEB-INF/customer/home.jsp").forward(request, response);
	}

주문정보 불러오기

주문 정보들을 표시하기 위해 먼저 DB에 테이블부터 만들어주었다.

Table 생성(SQL)

-- 시퀀스 생성
CREATE SEQUENCE SEQ_PURCHASE_NO START WITH 1001 INCREMENT BY 1 NOCACHE NOMAXVALUE;

-- 테이블생성
CREATE TABLE purchase
(
  no   number default seq_purchase_no.nextval not null,
  cnt    NUMBER,
  itemno   NUMBER,
  customerid   VARCHAR2(50),
  regdate  TIMESTAMP   DEFAULT CURRENT_DATE,
  PRIMARY KEY(no),
  FOREIGN KEY(itemno) REFERENCES item(no),
  FOREIGN KEY(customerid) REFERENCES memtb(id)
);

DTO 생성

package webdto;

import java.util.Date;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;

@Getter
@Setter
@ToString
@NoArgsConstructor
@AllArgsConstructor
public class Purchase {
	private long no; // 시퀀스 사용
	private long cnt;
	private long itemno;
	private String customerid;
	private Date regdate; // 자동으로 들어감.

}

Mapper 구성

package webmapper;

import java.util.List;

import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;

import webdto.Purchase;
import webdto.PurchaseView;

@Mapper
public interface PurchaseMapper {

	// 주문 등록
	@Insert ( value = { 
			"	INSERT INTO purchase( cnt, itemno, customerid)	",
			"	VALUES(  #{obj.cnt}, #{obj.itemno}, #{obj.customerid}  )	" 
			} )
	public int insertPurchase(@Param("obj") Purchase obj);
	
//	-------------------------------------------------------------------------
	
	// 현재 로그인한 사용자가 주문한 내역 조회
	@Select ( value = {
				"	SELECT * FROM PURCHASE	",
				"	WHERE customerid =#{id}	"
			} )
	public List<Purchase> selectPurchaseMember(@Param("id") String id);
//	-------------------------------------------------------------------------
	
	// 주문 + 고객 + 물품 조인한 VIEW 만들기
	// 주문번호, 주문일자, 주문자아이디, 주문자이름, 물품명, 물품가격
	@Select( value = {
				"	SELECT * FROM purchaseview WHERE customerid=#{id}	"
			} )
	public List<PurchaseView> selectPurchaseViewMember(@Param("id") String id);
}

그리고 주문정보의 경우에는 마이페이지의 4번째 항목을 사용하여 출력했다.

JSP (customer_menu/menu4.jsp)

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<body style="color: rgba(123, 123, 102, 0.5);">
	<div id="layoutAuthentication">
		<div id="layoutAuthentication_content">
			<main>
				<div class="container">
					<div class="row justify-content-center">
						<div class="col-lg">
							<div class="card shadow-lg border-0 rounded-lg mt-5 mb-5">
								<div class="card-header">
									<h3 class="text-left font-weight-light my-4">주문내역 조회하기</h3>
								</div>
								<div class="card-body">
									<form class="form-inline d-flex justify-content-first"
										method="GET" th:action="@{/board/boardList}"
										th:value="${param.searchText}">
									</form>
									<table class="table">
										<thead>
											<tr>
												<th scope="col">주문번호</th>
												<th scope="col">물품번호</th>
												<th scope="col">주문수량</th>
												<th scope="col">주문자 아이디</th>
												<th scope="col">주문날짜</th>
											</tr>
										</thead>
										<tbody>
											<c:forEach var="obj" items="${list}">
												<tr>
													<td>${obj.no}</td>
													<td>${obj.itemno}</td>
													<td>${obj.cnt}</td>
													<td>${obj.customerid}</td>
													<td>${obj.regdate}</td>
												</tr>
											</c:forEach>
										</tbody>
									</table>
									<hr />
									<div class="col-auto pull-end">
										<ul id="pagination-demo"
											class="pagination-sm d-flex justify-content-center"></ul>
									</div>

								</div>
							</div>
						</div>
					</div>
				</div>
			</main>
		</div>
	</div>

위의 내용을

<c:if test="${param.menu == 4}">
			<jsp:include page="../customer_menu/menu4.jsp"></jsp:include>
		</c:if>

Mypage에서 불러오는 식으로 추가했다.

로그인 이전화면 Filter

지금까지는 로그인 유효성을 검사하기 위한 Filter를 하나만 생성해두고 사용했다.

하지만, 물품 주문화면과 같은 경우 사용자가 도달한 화면에서 로그인 후 다시 홈화면으로 되돌아간다면 접근성의 면에서도 다소 불편함이 존재하기 때문에 로그인의 이전 화면으로 다시 되돌아 갈 수 있도록 아래의 이전 세션 이동용 필터를 추가하였다.

package filter;

import java.io.IOException;

import jakarta.servlet.Filter;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;
import jakarta.servlet.annotation.WebFilter;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;

// home(0) -> login(x) OR logout(x) -> home(o)
// board(o) -> login(x) -> board(O)
// 로그인후 이전페이지 이동을 위한 필터
/* 필터를 사용할 주소창을 입력 */
@WebFilter(urlPatterns = { "/customer/*"})
public class UrlFilter implements Filter {
	@Override
	public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2)
			throws IOException, ServletException {
		HttpServletRequest request = (HttpServletRequest) arg0; // arg0은 request
		HttpSession httpSession = request.getSession();
		String uri = request.getRequestURI();

		if ( !uri.contains("login.do") && !uri.contains("logout.do")) { // 세션에 등록된 UID 객체가 없으면 다시 로그인 페이지로 보냄.
			// home.do   			=> null		 => queryString이 null.
			// product.do?itemno=33 => itemno=33 => queryString이 itemno=33.('?'는 없음!)
			String queryString = request.getQueryString();
			
			if(queryString == null) {
				httpSession.setAttribute("url", request.getRequestURI());
				System.out.println("url 필터 : " + request.getRequestURI());
			}
			else {
				httpSession.setAttribute("url", request.getRequestURI()+"?"+queryString);
				System.out.println("url 필터 : " + request.getRequestURI()+"?"+queryString);

			}
		}
		
		// UID가 존재할 시 원래 수항하는 페이지로 이동
		arg2.doFilter(arg0, arg1);
	}
}
profile
시작은 미약하지만, 그 끝은 창대하리라

0개의 댓글