hyeonga_code
reProject_09_사용자 상품 리스트 페이지 구현 본문
reProject_08_회원 정보 찾기 기능 구현(아이디 찾기, 비밀번호 찾기)
2023.12.23 - [Project] - reProject_07_로그인 기능 구현 2023.12.21 - 2023.12.22 기존에 작업했던 form action 방식이 아닌 ajax로 처리 1.client_findInfo.jsp 수정 : 태그 수정 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 2
hyeonga493.tistory.com
2023-12-22
-- 회원 기능을 완벽하게 구현하지 않았으나 다음주 금요일까지 팀원들과 하기로 한 스터디때문에 상품 리스트, 상품 상세 페이지 기능부터 구현
-- 기존의 프로젝트에서는 패키지를 크게 product, admin, client로 나누어 작업했는데 product에 admin과 client의 내용이 같이 들어가 불편함이 있었으므로 product를 둘로 나누어 작업하려고 함
-- 기존 프로젝트에서 작업한 페이징 처리를 수정해서 사용
1. client_productList.jsp 파일 작성
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
|
<%@ 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>WEATHERWEAR</title>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="resources/client/client_js/client_productList.js"></script>
<link rel="stylesheet" href="/w2/resources/client/client_css/client_base_style.css">
<link rel="stylesheet" href="/w2/resources/client/client_css/client_productList_style.css">
</head>
<body>
<div class="container">
<%@ include file="/WEB-INF/views/client/base/client_header.jspf" %>
<div class="body">
<div class="productList">
<div class="Title">
<h2>${ param.gubun }</h2>
</div>
<div class="orderby">
<select class="select" id="ordertype" onchange="orderBy()">
<option ${ pararm.ordertype == 'proRegDate' ? 'selected' : '' || param.ordertype == null ? 'selected' : ''} value="proRegDate">최신순</option>
<option ${ param.ordertype == 'proCnt' ? 'selected' : '' } value="proCnt">판매순</option>
<option ${ param.ordertype == 'proPriceH' ? 'selected' : '' } value="proPriceH">높은 가격순</option>
<option ${ param.ordertype == 'proPriceL' ? 'selected' : '' } value="proPriceL">낮은 가격순</option>
</select>
</div>
<div class="clear_con"></div>
<div class="product">
<c:forEach var="product" items="${ productList }">
<ul class="product_list">
<li>
<a href="clientProductInfo.do?proId=${ product.proId }">
<img src="${ product.imageDir }${ product.imageName }" class="productList_img">
</a>
</li>
<li class="name">
<a href="clientProductInfo.do?proId=${ product.proId }">
${ product.proName }
</a>
</li>
<li class="price">₩ <fmt:formatNumber value="${ product.proPrice }" pattern="###,###" />
</ul>
</c:forEach>
</div>
<div class="clear_con"></div>
<!-- 페이징 처리 -->
<div class="paging">
<div class="prev_btn">
<ul class="paging_ul">
<c:if test="${ paging.prev }">
<li class="paging_li">
<a href="productList.do?page=${startPage -1}&gubun=${ param.gubun }&ordertype=${param.ordertype}">처음페이지로</a>
</li>
</c:if>
<c:if test="${ paging.currentPage>1 }">
<li class="paging_li">
<a href="productList.do?page=${ paging.currentPage -1}&gubun=${ param.gubun }&ordertype=${param.ordertype}">이전</a>
</li>
</c:if>
</ul>
</div>
<div class="page_btn">
<ul class="paging_ul">
<c:forEach var="pageNum" begin="${paging.startPage}" end="${paging.endPage}">
<li class="paging_li">
<a href="productList.do?page=${ pageNum }&gubun=${ param.gubun }&ordertype=${param.ordertype}"
style="${(pageNum == paging.currentPage) ? 'color:red; font-style:italic;' : 'color:dimgrey;'}">${ pageNum }</a>
</li>
</c:forEach>
</ul>
</div>
<div class="next_btn">
<ul class="paging_ul">
<c:if test="${ paging.currentPage < paging.endPage }">
<li class="paging_li">
<a href="productList.do?page=${ paging.currentPage + 1 }&gubun=${ param.gubun }&ordertype=${param.ordertype}">다음</a>
</li>
</c:if>
<!-- 다음 버튼 -->
<c:if test="${ paging.next }">
<li class="paging_li">
<a href="productList.do?page=${ paging.endPage +1 }&gubun=${ param.gubun }&ordertype=${param.ordertype}">마지막페이지로</a>
</li>
</c:if>
</ul>
</div>
</div>
</div>
</div>
<%@ include file="/WEB-INF/views/client/base/client_footer.jspf" %>
</div>
</body>
</html>
|
2. ClientGetController.java 수정
@Autowired
private ClientProductService productService;
/** 상품 리스트 페이지 */
@RequestMapping("clientProductList.do")
public String clientProductList(@RequestParam(value = "page", required = false)Integer page,
@RequestParam(value="ordertype", required=false) String ordertype,
@RequestParam(value="gubun", required=false)String gubun, Model model) {
System.out.println("1. [ Client Get Controller ] productList");
HashMap<String, Object> check = new HashMap<String, Object>();
if(page == null || page == 0) {
check.put("page", 1);
} else {
check.put("page", (int)page);
}
check.put("table", "product");
check.put("ordertype", (String)ordertype);
check.put("gubun", (String)gubun);
List<HashMap<String, Object>> productList = productService.clientProductList(check, model);
model.addAttribute("productList", productList);
return "client_productList";
}
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
|
package com.w2.client.controller;
import java.util.HashMap;
import java.util.List;
import javax.servlet.http.HttpSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import com.w2.client.ClientService;
import com.w2.client.ClientVO;
import com.w2.client.product.ClientProductService;
@Controller
public class ClientGetController {
@Autowired
private ClientService clientService;
@Autowired
private ClientProductService productService;
/** 사용자 메인페이지 */
@RequestMapping("clientMain.do")
public String main() {
return "client_main";
}
/** 상품 리스트 페이지 */
@RequestMapping("clientProductList.do")
public String clientProductList(@RequestParam(value = "page", required = false)Integer page,
@RequestParam(value="ordertype", required=false) String ordertype,
@RequestParam(value="gubun", required=false)String gubun, Model model) {
System.out.println("1. [ Client Get Controller ] productList");
HashMap<String, Object> check = new HashMap<String, Object>();
if(page == null || page == 0) {
check.put("page", 1);
} else {
check.put("page", (int)page);
}
check.put("table", "product");
check.put("ordertype", (String)ordertype);
check.put("gubun", (String)gubun);
List<HashMap<String, Object>> productList = productService.clientProductList(check, model);
model.addAttribute("productList", productList);
return "client_productList";
}
/** 사용자 로그인 페이지 */
@RequestMapping("clientLogin.do")
public String login() {
return "client_login";
}
/** 로그아웃 요청 */
@RequestMapping("clientLogout.do")
public String logout(HttpSession session) {
if(session != null) {
session.invalidate();
}
return "redirect:/clientMain.do";
}
/** 사용자 정보 찾기 페이지 */
@RequestMapping("clientFindInfo.do")
public String findInfo() {
return "client_findInfo";
}
/** 회원가입 페이지 */
@RequestMapping("clientSignup.do")
public String signup() {
return "client_signup";
}
/** 커뮤니티 페이지 */
@RequestMapping("clientCommunity.do")
public String community() {
return "client_community";
}
/** 마이페이지 */
@RequestMapping("clientMypage.do")
public String mypage(HttpSession session, ClientVO client, Model model) {
System.out.println("1. [ Client Get Controller ] myPage ");
HashMap<String, Object> myinfo = clientService.clientSetMypage((String)session.getAttribute("session"));
model.addAttribute("myinfo", myinfo);
return "client_mypage";
}
}
|
3. Paging.java 클래스 생성
-- paging 처리는 공통으로 사용되는 기능이므로 com.w2.util 패키지에 생성
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
|
package com.w2.util;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
@Getter
@Setter
@ToString
public class Paging {
private static final int VIEW_POST_NUM = 20; // 한 페이지당 보여 줄 게시글의 수
private static final int VIEW_PAGE_NUM = 5; // 한 페이지당 보여줄 페이지의 수
private Integer totalPosts; // 총 게시글의 수
private Integer totalPage; //게시판의 전체 페이지 수
private Integer currentPage; // 현재 페이지 번호
private Integer startPage; // 현재 페이지의 시작 번호
private Integer endPage; // 현재 페이지의 끝 번호
private boolean prev; // 이전 버튼 활성화 여부
private boolean next; // 다음 버튼 활성화 여부
public Paging(Integer totalPosts, Integer currentPage, Object object) {
if( currentPage != null) {
this.currentPage = currentPage;
} else {
this.currentPage = 1;
}
this.totalPosts = totalPosts;
System.err.println("3. [ Paging ] totalPosts : " + totalPosts);
// 생성자에서 메소드를 호출하여 페이지 번호를 부여하는 기능을 추가합니다.
pagingMaker();
}
// 페이지 번호를 만들어주는 메소드
public void pagingMaker() {
// 한 페이지당 보여줄 글의 개수로 총 페이지를 나누어 총 페이지 수를 지정합니다.
totalPage = (totalPosts-1) / VIEW_POST_NUM + 1;
System.err.println("4. [ Paging ] totalPage : " + totalPage);
if(currentPage < 1 || currentPage > totalPage) {
currentPage = 1;
}
endPage = ((currentPage - 1) / VIEW_PAGE_NUM + 1) * VIEW_PAGE_NUM;
if(endPage >= totalPage) {
endPage = totalPage;
}
startPage = ((currentPage-1) / VIEW_PAGE_NUM) * VIEW_PAGE_NUM + 1;
// 시작 페이지가 1과 같으면 이전 버튼을 비활성화하고 다르면 이전버튼을 활성화합니다.
prev = (startPage == 1) ? false : true;
// 끝 페이지가 총 페이지 수와 같다면 다음 버튼을 비활성화 하고 다르다면 다음 버튼을 활성화합니다.
next = (endPage == totalPage) ? false : true;
}
}
|
cs |
-- com.w2.client.product 패키지 생성
4. ProductService.java 인터페이스 작성
1
2
3
4
5
6
7
8
9
10
11
12
13
|
package com.w2.client.product;
import java.util.HashMap;
import java.util.List;
import org.springframework.ui.Model;
public interface ClientProductService {
// 상품 목록
List<HashMap<String, Object>> clientProductList(HashMap<String, Object> check, Model model);
}
|
-- com.w2.client.product.impl 패키지 생성
5. ProductServiceImpl.java 클래스 작성
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
|
package com.w2.client.product.impl;
import java.util.HashMap;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.ui.Model;
import com.w2.client.product.ClientProductDAO;
import com.w2.client.product.ClientProductService;
import com.w2.util.Paging;
@Service("productService")
public class ClientProductServiceImpl implements ClientProductService {
@Autowired
public ClientProductDAO productdao;
// 상품 목록
@Override
public List<HashMap<String, Object>> clientProductList(HashMap<String, Object> check, Model model) {
System.out.println("2. [ Impl ] productList");
int currentPage;
if(check.get("page") == null || (int)check.get("page") == 0) {
currentPage = 1;
} else {
currentPage = (int)check.get("page");
}
int totalCount = productdao.searchCount(check);
Paging paging = new Paging(totalCount, currentPage, check);
int postStart = (paging.getCurrentPage()-1) * 20;
int postEnd = paging.getCurrentPage() * 20;
check.put("startPage", paging.getStartPage());
check.put("endPage", paging.getEndPage());
check.put("postStart", postStart);
check.put("postEnd", postEnd);
model.addAttribute("paging", paging);
return productdao.clientProductList(check);
}
}
|
6. ProductDAO.java 클래스 작성
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
|
package com.w2.client.product;
import java.util.HashMap;
import java.util.List;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
@Repository
public class ClientProductDAO {
@Autowired
private SqlSessionTemplate sqlSessionTemplate;
// 상품 리스트 조회
public List<HashMap<String, Object>> clientProductList(HashMap<String, Object> check) {
System.out.println("3. [ Product DAO ] productList");
return sqlSessionTemplate.selectList("ProductDAO.clientProductList", check);
}
// 상품 개수 확인
public int searchCount(HashMap<String, Object> check) {
System.out.println("3. [ Product DAO ] searchCount");
return sqlSessionTemplate.selectOne("ProductDAO.searchCount", check);
}
}
|
7. client-product-mapping.xml 파일 작성
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
|
<?xml version="1.0" encoding="UTF-8"?>
<!-- MyBatis 다운 파일 PDF 에서 붙여넣은 내용입니다. -->
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="ProductDAO">
<!-- 사용 가능
<sql id="미리 지정가능">지정하고 싶은 값 입력 가능</sql>
<include refid="미리 지정가능"/>
-->
<!-- 상품 리스트 -->
<select id="clientProductList" resultType="HashMap" parameterType="HashMap">
SELECT pro.proId, pro.proName, pri.proPrice, img.imageName, img.imageDir
FROM product pro
LEFT JOIN product_price pri ON pro.proId = pri.proId
LEFT JOIN product_image img ON pro.proId = img.ImageBy AND img.ImageStatus='대표'
WHERE pro.proSell = 'Y'
<choose>
<when test="gubun == 'outer'">
AND pro.proCate LIKE "11%"
</when>
<when test="gubun == 'top'">
AND pro.proCate LIKE "12%"
</when>
<when test="gubun == 'pants'">
AND pro.proCate LIKE "13%"
</when>
<when test="gubun == 'skirts'">
AND pro.proCate LIKE "14%"
</when>
<when test="gubun == 'dress'">
AND pro.proCate LIKE "15%"
</when>
</choose>
ORDER BY
<choose>
<when test="ordertype == 'proRegDate'">
pro.proRegDate DESC
</when>
<when test="ordertype == 'proCnt'">
pro.proCnt DESC
</when>
<when test="ordertype == 'proPriceH'">
pri.proPrice DESC
</when>
<when test="ordertype == 'proPriceL'">
pri.proPrice ASC
</when>
<when test="ordertype == 'proSell'">
pro.proSell ASC
</when>
<otherwise>
pro.proName ASC
</otherwise>
</choose>
<choose>
<when test="postStart == 1">
LIMIT 0,20
</when>
<otherwise>
LIMIT #{ postStart }, 20
</otherwise>
</choose>
</select>
<!-- 상품 개수 조회 -->
<select id="searchCount" resultType="int">
SELECT COUNT(*)
FROM product
JOIN product_image ON product.proId = product_image.imageBy AND product_image.imageStatus="대표"
<choose>
<when test="gubun == 'outer'">
WHERE proCate LIKE "11%"
</when>
<when test="gubun == 'top'">
WHERE proCate LIKE "12%"
</when>
<when test="gubun == 'pants'">
WHERE proCate LIKE "13%"
</when>
<when test="gubun == 'skirts'">
WHERE proCate LIKE "14%"
</when>
<when test="gubun == 'dress'">
WHERE proCate LIKE "15%"
</when>
</choose>
</select>
</mapper>
|
8. client_header.jspf 파일 수정
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
32
33
34
35
36
37
38
|
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<header class="header clear">
<img src='/w2/resources/client/client_image/logo_pull.png' class="header_img" onclick="location.href='clientMain.do'">
<!-- 익명의 사용자 -->
<c:if test="${ session == null }">
<nav class="user_menu">
<ul>
<li><a href="clientLogin.do">LOGIN</a></li>
<li><a href="clientSignup.do">JOIN</a></li>
<li><a href="#">CART</a></li>
</ul>
</nav>
</c:if>
<!-- 로그인한 사용자 -->
<c:if test="${ session != null }">
<nav class="user_menu">
<ul>
<li><a href="#">CART</a></li>
<li><a href="clientMypage.do">MYPAGE</a></li>
<li><a href="clientLogout.do">LOGOUT</a></li>
</ul>
</nav>
</c:if>
<div class="clear_con"></div>
<nav class="main_menu">
<ul>
<li><a class="main_menu_a" href="clientProductList.do?gubun=all"><strong class="all">ALL</strong></a></li>
<li><a class="main_menu_a" href="clientProductList.do?gubun=outer"><strong class="outer">OUTER</strong></a></li>
<li><a class="main_menu_a" href="clientProductList.do?gubun=top"><strong class="top">TOP</strong></a></li>
<li><a class="main_menu_a" href="clientProductList.do?gubun=pants"><strong class="pants">PANTS</strong></a></li>
<li><a class="main_menu_a" href="clientProductList.do?gubun=skirts"><strong class="skirts">SKIRTS</strong></a></li>
<li><a class="main_menu_a" href="clientProductList.do?gubun=dress"><strong class="dress">DRESS</strong></a></li>
<li><a class="main_menu_a" href="clientCommunity.do"><strong>COMMUNITY</strong></a></li>
</ul>
</nav>
</header>
|
9. client_productList_style.css 파일 수정
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
|
@charset "UTF-8";
.productList > .Title > h2 {
text-transform: uppercase;
}
.productList {
display: flex;
flex-direction: column;
padding-left: 1%;
}
.product {
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: flex-start;
padding-left: 2%;
}
.product_list {
max-width: 100%;
max-height: 100%;
list-style-type: none;
display: flex;
flex-direction: column;
padding-left: 10px;
padding-right: 10px;
}
.productList_img {
width: 200px;
height: 200px;
min-width: 80px;
min-height: 80px;
max-width: 100%;
min-height: 100%;
}
.name > a {
text-decoration: none;
color: black;
}
.name {
width: 200px;
text-align: left;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
max-width: 100%
}
.paging {
width: 100%;
display: flex;
justify-content: center;
padding-left: 0px;
}
.prev_btn {
width: 15%;
display: flex;
padding-left: 0px;
}
.page_btn {
min-width: 30%;
display: flex;
padding-left: 0px;
}
.next_btn {
width: 15%;
display: flex;
padding-left: 0px;
}
.paging_ul {
width: 100%;
list-style-type: none;
display: flex;
justify-content: space-evenly;
padding-left: 0px;
}
.paging_li > a {
text-decoration: none;
color: dimgrey;
}
.paging_li > a:hover {
font-weight: bold;
}
|
10. client_productList.js 파일 작성
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
$(document).ready(function(){
const params = new URLSearchParams(location.search);
let gubun = "." + params.get('gubun') + "";
document.querySelector(gubun).style.color="red";
})
function orderBy(){
var value = document.getElementById("ordertype").value;
const params = new URLSearchParams(location.search);
let gubun = params.get('gubun');
window.location.replace("productList.do?gubun=" + gubun + "&ordertype=" + value);
}
|
>>> 실행
-- 상품 정보는 유니클로상품을 json파일로 읽어와 처
>> 정렬기능 구현 됨
>> 페이징 기능 구현 됨
-- 1페이지인 경우 '처음 페이지로', '이전' 버튼 보이지 않음
-- 마우스 올리는 경우 커서 생성되며 색상 변경됨
reProject_10_사용자 상품 상세 페이지 구현
reProject_09_사용자 상품 리스트 페이지 구현 2023.12.23 - [Project] - reProject_08_회원 정보 찾기 기능 구현(아이디 찾기, 비밀번호 찾기) 2023-12-22 -- 회원 기능을 완벽하게 구현하지 않았으나 다음주 금요
hyeonga493.tistory.com
'Project_WEATHERWEAR' 카테고리의 다른 글
reProject_00_작업 일지 (0) | 2023.12.27 |
---|---|
reProject_10_사용자 상품 상세 페이지 구현 (1) | 2023.12.23 |
reProject_08_회원 정보 찾기 기능 구현(아이디 찾기, 비밀번호 찾기) (0) | 2023.12.23 |
reProject_07_로그인 기능 구현 (0) | 2023.12.23 |
reProject_06_회원 가입 기능 구현 (0) | 2023.12.23 |