본문 바로가기
[ JAVA ]/JAVA Spring

[ Spring ] 상품 등록/목록 페이지 구현

by 환이s 2023. 4. 13.


프로젝트 구조

 

 

이전 포스팅에서 관리자 목록 페이지를 생성했습니다.

오늘은 상품 등록/목록 기능 구현을 해보겠습니다.

 

프로젝트 흐름은 Controller  = > Service => DAO => View 단 순으로 진행합니다.


admin_menu.jsp

 

이전 포스팅에서 생성했던 관리자 메뉴 페이지에 폼 생성해서 Controller에 요청을 보냅니다.

 

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
        <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
        <c:set var="path" value="${pageContext.request.contextPath }"/>   

<div style="text-align: center;">
	<a href="${path}/admin/list.do">상품 목록</a> |  <!-- 기능 추가  -->
	<c:if test="${sessionScope.admin_userid != null }">
	<a href="${path}/admin/write.do">상품등록</a> |  
    <!-- 관리자 아이디 확인 시 표출 / 기능 추가 -->
	</c:if>
	<a href="${path}/pdf/list.do">PDF</a> |
	<a href="${path }/chart/chart1.do">구글 차트(json)</a> |
	<a href="${path }/chart/chart2.do">구글 차트(db)</a> |
	<a href="${path }/jchart/chart1.do">JFreeChart(png)</a> |
	<a href="${path }/jchart/chart2.do">JFreeChart(pdf)</a> |
	
	
	<div style="text-align: right;">
	<c:choose>
	<c:when test="${sessionScope.admin_userid == null }">
	<!-- 로그인하지 않은 상태 -->
	<a href="${path}/member/login.do">일반 로그인</a> |
	<a href="${path}/admin/login.do">관리자 로그인</a> |
	</c:when>
	<c:otherwise>
	<!-- 로그인한 상태 -->
	${sessionScope.admin_name }님이 로그인중입니다.
	<a href="${path}/admin/logout.do">로그아웃</a> |
	</c:otherwise>
	</c:choose>
	</div>
</div>
<hr>

Controller

 

상품 등록 기능은 Service 에 요청을 보내는 것보단 등록할 수 있는 폼으로 리턴을 해주고, 목록 페이지는 이전에 생성했던 Product Service에 listProduct()를 호출합니다.

 

상품 목록 기능은 ModelAndView 타입으로 요청을 보내는데 , ModelAndView데이터와 이동하고자 하는 View Page를 같이 저장하는 생성자 입니다.

 

 

package com.example.spring.controller.admin;

import javax.inject.Inject;
import javax.servlet.http.HttpSession;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

import com.example.spring.model.member.dto.MemberDTO;
import com.example.spring.service.admin.AdminService;
import com.example.spring.service.shop.ProductService;

@Controller
@RequestMapping("admin/*") //공통 url mapping
public class AdminController {
	@Inject
	AdminService adminService;
	
	@Inject
	ProductService productService;
	
	@RequestMapping("login.do")//세부 url
	public String login() {
		return "admin/login";
	}
	
	@RequestMapping("login_check.do")
	public ModelAndView login_check(MemberDTO dto, HttpSession session, 
			ModelAndView mav) {
		String name=adminService.loginCheck(dto);//로그인 체크
		if(name != null) {//로그인 성공
			//관리자용 세션변수
			session.setAttribute("admin_userid", dto.getUserid());
			session.setAttribute("admin_name", name);
			//일반 사용자용 세션변수
			session.setAttribute("userid", dto.getUserid());
			session.setAttribute("name", name);
			mav.setViewName("admin/admin");
		}else {
			mav.setViewName("admin/login");
			mav.addObject("message", "error");
		}
		return mav;
	}
	
	@RequestMapping("logout.do")
	public String logout(HttpSession session) {
		session.invalidate();//세션 초기화
		//관리자 로그인 페이지로 이동
		return "redirect:/admin/login.do";
	}
	
	// 상품 등록 폼으로 이동
	@RequestMapping("write.do")
	public String write() {
		return "admin/admin_product_write";
	}
	// 상품 목록 페이지 Service 단에 요청
	@RequestMapping("list.do")
	public ModelAndView list(ModelAndView mav) {
		mav.setViewName("/admin/admin_product_list");
		mav.addObject("list", productService.listProduct());
		return mav;
	}

}

 

먼저 목록 페이지 요청 처리 합니다.

 


ProductService 

 

 Service단은 DAO와 연결해 줍니다. 

 

import java.util.List;

import javax.inject.Inject;

import org.springframework.stereotype.Service;

import com.example.spring.model.shop.dao.ProductDAO;
import com.example.spring.model.shop.dto.ProductDTO;

@Service
public class ProductServiceImpl implements ProductService {
	
	@Inject
	ProductDAO productDao;

	@Override
	public List<ProductDTO> listProduct() {
		
		return productDao.listProduct();
	}

ProductDAO

 

상품 목록은 한 가지 데이터를 가져오는 게 아닌,

전체 데이터를 가져와야 하기 때문에 selectOne()이 아니라 selectLIst()mapper 파일에 요청을 보냅니다.

 

import java.util.List;

import javax.inject.Inject;

import org.apache.ibatis.session.SqlSession;
import org.springframework.stereotype.Repository;

import com.example.spring.model.shop.dto.ProductDTO;

@Repository
public class ProductDAOImpl implements ProductDAO {
	
	@Inject
	SqlSession sqlSession;
	
	
	
	@Override
	public List<ProductDTO> listProduct() {
		
		return sqlSession.selectList("product.product_list");
	}

productMapper.xml

 

DAO에서 요청을 select문으로 요청을 보냈으니, mapper 에서도 동일한 SQL문으로 코드 작업을 하는데,

여기서 주의할 점은 select문은 resultType을 꼭 설정을 해줘야 합니다.

 

상품 목록의 타입은 DTO 타입으로 요청을 보냈기 때문에 DTO 경로를 타입으로 설정해 줍니다.

 

<!-- 다른 mapper와 중복되지 않도록 네임스페이스 기재 -->
<mapper namespace="product">
	<select id="product_list" resultType="com.example.spring.model.shop.dto.ProductDTO">
	select * from product
	order by product_name 
	</select>

 

mapper 작업이 끝났다면 Controller 에서 View Page 설정한 admin_product_list 페이지를 생성합니다.

 


admin_product_list

 

상품 목록 페이지는 유저 폼과는 다르게 관리자 ID 값이 들어오면 편집 기능이 할 수 있게 만들어 줍니다.

 

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<%@ include file="../include/header.jsp" %>
</head>
<body>
<%@ include file="../include/admin_menu.jsp" %>
<h2>상품목록</h2>
<table border="1" style="width: 100%;">
  <tr>
    <th>상품코드</th>
    <th>&nbsp;</th>
    <th>상품명</th>
    <th>가격</th>
  </tr>
<c:forEach var="row" items="${list}">  
  <tr>
    <td>${row.product_id}</td>
    <td><img src="${path}/images/${row.picture_url}" 
    width="100px" height="100px"></td>
    <td><a href="${path}/shop/product/detail/${row.product_id}">${row.product_name}</a>
    <!-- 관리자에게만 편집 버튼 표시 -->
    <c:if test="${sessionScope.admin_userid != null }"> <br>
     <a href="${path}/shop/product/edit/${row.product_id}">[편집]</a>
    </c:if>
    </td>
    <td><fmt:formatNumber value="${row.price}" pattern="#,###" /></td>
  </tr>
</c:forEach>  
</table>
</body>
</html>

 product_list.jsp (Form)

 

 

목록 페이지에 데이터가 정상적으로 출력되는 걸 확인했습니다.

다음으로 상품 등록 기능 구현을 하는데, Controller 에서 view 단 페이지를 리턴 시켰습니다.

그럼 상품 등록 페이지를 생성합니다.


admin_product_write

 

상품 등록 페이지에서는 간단한 안전성 검사 처리를 하고 Controller에 요청을 보냅니다.

 

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<%@ include file="../include/header.jsp" %>
<script type="text/javascript">
function product_write() {
	var product_name=$("#product_name").val();
	var price=$("#price").val();
	var description=$("#description").val();
	if(product_name==""){//빈값이면
		alert("상품이름을 입력하세요");
		$("#product_name").focus();
		return;
	}
	if(price==""){//빈값이면
		alert("가격을 입력하세요");
		$("#price").focus();
		return;
	}
	if(description==""){//빈값이면
		alert("상품설명을 입력하세요");
		$("#description").focus();
		return;
	}
	document.form1.action="${path}/shop/product/insert.do"; <!-- Controller에 보냄 -->
	document.form1.submit();
}
</script>
</head>
<body>
<%@ include file="../include/admin_menu.jsp" %>
<h2>상품 등록</h2>
<form name="form1" method="post" enctype="multipart/form-data">
<table>
 <tr>
  <td>상품명</td>
  <td> <input name="product_name" id="product_name"> </td>
 </tr>
 <tr>
  <td>가격</td>
  <td> <input name="price" id="price"> </td>
 </tr>
 <tr>
  <td>상품설명 </td>
  <td>
   <textarea rows="5" cols="60" name="description" id="description"></textarea>
  </td> 
 </tr>
 <tr>
  <td>상품이미지 </td>
  <td> <input type="file" name="file1" id="file1"> </td>
 </tr>
 <tr>
  <td colspan="2" align="center"> 
   <input type="button" value="등록" onclick="product_write()">
   <input type="button" value="목록" onclick="location.href='${path}/admin/list.do'">
  </td>
 </tr>
</table>
</form>

</body>
</html>

Controller

 

상품 등록 페이지에서 상품 이미지를 첨부하려면 File 객체를 사용해야 합니다.

첨부 파일이 유/무 처리 해주고 디렉터리 설정도 해줍니다. 

 

@RequestMapping("insert.do")
	public String insert(@ModelAttribute ProductDTO dto) {
		String filename="-"; //not null로 했을때 "-"으로 처리 되게함.
		//첨부 파일이 있으면
		if(!dto.getFile1().isEmpty()) {
			//첨부 파일의 이름
			filename=dto.getFile1().getOriginalFilename();
			try {
				//개발디렉토리, 배포디렉토리
				//디렉토리 구분자 : 윈도우즈 \, 유닉스(리눅스) /
				// " "안에다 \를 쓰면 특수무자로 알아듣기 때문에 \를 하나 더 써야함.
				String path="C:\\work\\.metadata\\.plugins\\org.eclipse.wst.server.core"
						+ "\\tmp0\\wtpwebapps\\spring02\\WEB-INF\\views\\images";
				//디렉토리가 존재하지 않으면 생성
				new File(path).mkdir();
				//임시 디렉토리에 저장된 첨부파일을 이동
				dto.getFile1().transferTo(new File(path+filename));
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		dto.setPicture_url(filename);
		productService.insertProduct(dto);
		// 목록으로 이동
		return "redirect:/shop/product/list.do";
	}

ProductService

 

	@Override
	public void insertProduct(ProductDTO dto) {
			productDao.insertProduct(dto);

	}

ProductDAO

 

	@Override
	public void insertProduct(ProductDTO dto) {
		sqlSession.insert("product.insert", dto);

	}

productMapper

상품을 등록할 때 상품 번호는 시퀀스로 설정해주고, 해당 데이터들은 함수로 연결합니다.

 

	<!-- 상품 등록 -->
	<insert id="insert">
	insert into product values
	(seq_product.nextval,#{product_name},#{price},#{description},#{picture_url})
	</insert>

 

코드 작업은 끝났습니다.

데이터가 정상적으로 등록되는지 확인합니다.


출력

 

< 상품 등록 >

 

 

< 목록 페이지 >

 


마치며

 

오늘은 상품 목록/등록 기능을 구현했습니다.

다음 포스팅에서 뵙겠습니다.

728x90