상품관리 프로젝트 코드 작성하기
상품관리 프로젝트 페이지 구성
쇼핑몰 페이지
자바파일
Controller
HomeController
: home.jsp를 실행하기 위해 경유하는 컨트롤러 / 시간 정보 담아서 home.jsp 실행
MemberController
: 로그인, 로그인 체크, 로그아웃,
UploadController
: 업로드폼으로 포워딩, 폼데이터 업로드, 업로드 함수
CartController
: cart테이블 저장, cart 리스트 반환, 품목 삭제, 전체 삭제, 업데이트??<<
ProductController
: 상품 목록, 상품 상세보기, 상품 등록 페이지로 포워딩, 등록시 상품목록페이지로 포워
AdminController
: 관리자 로그인창으로 포워딩, 로그인 체크,
관리자 로그아웃처리하고 관리자로그인페이지로 포워딩
Model
MemberDAO + Impl
MemberDTO
: userid / passwd / name / email / join_date
CartDAO +Impl
CartDTO
: cart_id / userid / name / product_id / product_name / price / money / amount
ProductDAO + Impl
ProductDTO
: product_id / product_name / price / description / picture_url / file1
Service
MemberService + Impl
CartService + Impl
ProductService + Impl
AdminService + Impl
설정파일
Mapper ( namespace로 구분 ) ★★★
memberMapper.xml
: 로그인 체크 쿼리
adminMapper.xml
: 관리자 로그인 체크 쿼리
cartMapper.xml
: 장바구니 담기, 장바구니 리스트, 개별상품 삭제, 전체 삭제 쿼리
productMapper.xml
: 상품 리스트, 상품 상세, 상품 추가 쿼리
기본 설정 파일
web.xml
: root-context.xml, servlet-context.xml 로딩
root-context.xml
: mybatis 객체 빈으로 등록시 Mappers.xml 스캔
servlet-context.xml
: include나 image폴더 리소스 매핑 설정 / 업로드 경로 리소스 빈으로 등록 /
파일 업로드에 필요한 클래스 빈으로 등록 / 컴포넌트 스캔 / 뷰로 포워딩시 pre,suffix 설정
pom.xml
//mybatis mapper 코드는 어디에?<<
views 파일 ( .jsp )
include 파일 : header / menu / admin_menu / style.css
memberLogin / cart_list / product_detail / product_list / product_write / uploadForm / uploadResult
admin / adminLogin
상품관리 예제 코드 작성 순서
7강) 상품관리 프로젝트 코드 작성 -1
1. jsp페이지 및 리소스 파일 넣고 servlet-context에 등록, url 매핑 : include / images ...
2. pom에 파일업로드, 썸네일 라이브러리 등록
3. 등록한 라이브러리에서 사용할 클래스를 servlet-context에 빈으로 등록
4. UploadController.java
5. 파일 업로드 폼.jsp
6. 업로드 결과.jsp
-----------------------------------------------------------------------------------------------------
8강 ) 상품관리 프로젝트 코드 작성 -2
7. 사용자 페이지
: productDTO , DAO > Mapper(sample매퍼 사용) > Service > Controller 작성
/ 상품 목록jsp
-----------------------------------------------------------------------------------------------------
9강) 상품관리 프로젝트 코드 작성 -3
8. 로그인 페이지, 로그아웃
: Member DTO , DAO > Mapper(sample매퍼 사용) > Service > Controller 작성
9. 장바구니 (cart 테이블 )
: Cart DTO , DAO > Mapper(sample매퍼 사용) > Service > Controller 작성
-----------------------------------------------------------------------------------------------------
10강) 상품관리 프로젝트 코드 작성 -4
10. 관리자 로그인, 상품 등록, 수정, 삭제 (admin테이블 )
: Admin DTO , DAO > Mapper(sample매퍼 사용) > Service > Controller 작성
관리자 로그인 페이지, 관리자 메뉴 페이지.jsp
코드 작성 전 설정해야 부분
sample이나 spring01에서 프로젝트에서 파일 복사해올때 수정해야할 부분
pom.xml reference부터만 복사해오기
web.xml 한글 인코딩 처리
servelt-context 컴포넌트 스캔 패키지 spring02로 수정
mapper 패키지의 log4j.xml 애플리케이션 로거 컨트롤러경로에서 프로젝트 이름 spring02로 수정
root-context.xml 에서 datasource bean부분
id / password 수정
"jdbc:log4jdbc:oracle:thin@localhost:1521/xe" // :xe 가 낮은버전에선 될수도있음
home.jsp 한글깨짐 처리해주는 코드 추가
root-context.xml 에 mybatis mapper interface bean을 자동으로 검색하여 생성해주는 코드 추가
<mybatis-spring:xcan base-package="com.example.spring02.model.memo">
( 프로젝트 서버로 실행할때 프로젝트 하나씩만 등록해놓는게 좋다. )
memo 테이블 만들기
1. 메인 페이지인 home.jsp와 include될 jsp파일 일부 작성
header.jsp
1 2 3 4 5 6 7 8 9 10 11 12 13 | <%@ 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"%> <!-- path 변수 선언, request객체가 가진 쿼리 문자열 반환된 값 저장--> <c:set var="path" value="${pageContext.request.contextPath}" /> <!--자바스크립트 라이브러리인 jquery는 소스로 등록해놔야 사용 가능 --> <script src="http://code.jquery.com/jquery-3.3.1.js"></script> <!-- link : 외부 문서와 연결해주는 태그, 주로 css파일이나 폰트 관련 코드 연결해줌 --> <link rel="stylesheet" href="${path}/include/style.css" /> | cs |
pageContext.request.contextPath : EL문에서 getContextPath() (현재 프로젝트 path 리턴하는 함수) 대신 사용
menu.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 | <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <!-- path value = ${pageContext.request.contextPath} header.jsp에서 코어태그로 변수 path 선언--> <a href="${path}">Home</a> <!-- 이전에 만들어뒀던 한줄메모장 --> <a href="${path}/memo/list.do">한줄메모장</a> <a href="${path }/upload/uploadForm">업로드 테스트</a> <a href="${path }/shop/product/list.do">상품 목록</a> <!-- admin_userid는 admin/login_check.do에서 넘어온 session에 저장된 정보--> <c:if test="${sessionScope.admin_userid == 'admin'} "> <a href="${path }/shop/product/write.do">상품등록</a> </c:if> <a href="${path/shop/cart/list.do}">장바구니</a> <div style="text-align : right;"> <c:choose> <!-- 넘어온 session 데이터가 없어도(선언된 적 없는 변수여도) dot써서 비교 가능한가봄 --> <c:when test="${sessionScope.userid == null }"> <a href="${path}/member/login.do">로그인</a> <a href="${path}/admin/login.do">관리자 로그인</a> </c:when> <c:otherwise> ${sessionScope.name}님이 로그인중입니다. <a href="${path}/member/logout.do">로그아웃</a> </c:otherwise> </c:choose> </div> <!--수평선 --> <hr> | cs |
home.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 | <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <%@ page session="false" %> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Home</title> <!-- jsp:액션태그 아니고 지시자 include --> <%@include file="include/header.jsp" %> </head> <body> <%@include file="include/menu.jsp" %> <c:if test ="${sessionScope.userid != null }"> <h2> ${sessionScope.name}(${sessionScope.userid}) 님의 방문을 환영합니다. </h2> </c:if> <!-- HomeController.java에서 Model에 담겨 넘어오는 serverTime --> <P> The time on the server is ${serverTime}. </P> <!-- 배포 디렉토리(실제 경로) 확인 ★★★--> <!--application (javax.servlet.ServletContext ) : 웹 어플리케이션 Context의 정보를 저장하고 있는 jsp내장객체 --> <%=application.getRealPath("/") %> </body> </html> | cs |
<%=application.getRealPath("/") %>
현재 프로젝트의 H/W 상의 실제 경로를 출력한다.
E:\SpringWorkspace\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\spring02\
2. pom에 파일업로드, 썸네일 라이브러리 등록
1 2 3 4 5 6 | <!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload --> <dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.4</version> </dependency> | cs |
1 2 3 4 5 6 7 | <!-- https://mvnrepository.com/artifact/org.imgscalr/imgscalr-lib --> <dependency> <groupId>org.imgscalr</groupId> <artifactId>imgscalr-lib</artifactId> <version>4.2</version> </dependency> | cs |
3. servlet-context에 리소스 매핑 설정 / 파일업로드에 필요한 클래스를 빈으로 등록 ★★★
servlet-context 리소스 매핑 부분에
include될 jsp파일과 images 리소스 매핑 (스프링에서 읽어들이도록)
1 2 3 4 | <resources location="/WEB-INF/views/include/" mapping="/include/**" /> <resources location="/WEB-INF/views/images/" mapping="/images/**" /> | cs |
파일 업로드 관련 설정
파일 업로드 시 필요한 스프링 프레임워크 내장 클래스를 빈으로 등록
1 2 3 4 5 6 7 8 | <beans:bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <beans:property name="maxUploadSize" value="10485760" /> </beans:bean> <!-- 웹 상이 아닌 하드웨어상 디렉토리 설정 시 필요--> <beans:bean id="uploadPath" class="java.lang.String"> <beans:constructor-arg value="d:/upload" /> </beans:bean> | cs |
org.springframework.web.multipart.commons.CommonsMultipartResolver
스프링프레임워크 파일업로드 관련 내장 객체, 스프링 내장객체여도 빈으로 등록을 해야한다.
4 ~ 6. 파일업로드에 필요한 페이지 작성
파일 업로드 관련 설정을 끝냈으니 업로드 관련 페이지 작성
menu.jsp의 업로드 테스트와 연결 //POST방식 명시하지 않았으므로 GET방식으로 넘어감.
1 | <a href="${path }/upload/uploadForm">업로드 테스트</a> | cs |
UploadController.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 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 | package com.example.spring02test.controller.upload; import java.io.File; import java.util.UUID; import javax.annotation.Resource; import org.slf4j.Logger; // 하단의 로깅툴 설명 참고 import org.slf4j.LoggerFactory; import org.springframework.stereotype.Controller; import org.springframework.util.FileCopyUtils; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.multipart.MultipartFile; import org.springframework.web.servlet.ModelAndView; @Controller public class UploadController { //logger는 상수(전역변수)로 설정 private static final Logger logger = LoggerFactory.getLogger(UploadController.class); //servlet-context에 리소스로 등록한 uploadPath //매핑 등록한 리소스 주입받을때 쓰는 @Resource 어노테이션 @Resource(name="uploadPath") //아래 파일 업로드하는 메서드에서 File 객체인 target 경로 설정시 사용됨 String uploadPath; //다른이름으로 변수 선언해도 된다. //POST 방식이라고 명시하지 않으면 폼데이터는 GET방식으로 넘어온다. //업로드 폼으로 포워딩해주는 메서드 @RequestMapping(value="/upload/uploadForm", method = RequestMethod.GET) public void uploadFrom() { //GET방식으로 넘어올 땐 이 메서드 실행 //리턴값 없으므로 RequestMapping에 매핑된 url.jsp로 포워딩 //upload/uploadForm.jsp로 포워딩 }//menu.jsp에서 '업로드 테스트' 누르면 이 메서드 실행됨.(GET 방식) //POST 방식이라고 명시하지 않으면 폼데이터는 GET방식으로 넘어온다. //파일 올릴때 post방식 명시하여 이 메서드 실행 @RequestMapping(value="/upload/uploadForm", method = RequestMethod.POST) public ModelAndView uploadFrom( MultipartFile file, ModelAndView mav)throws Exception { //파일을 올리면 MultipartFile 객체에 담긴다. logger.info("파일 이름 : " + file.getOriginalFilename()); logger.info("파일 크기 : " + file.getSize()); //Content Type : 파일 종류?? logger.info("컨텐트 타입 : " + file.getContentType()); String savedName = file.getOriginalFileName(); savedName = uploadFile(savedName, file.getBytes()); //uploadFile()는 파일 이름 적절하게 바꿔서 저장하고 이름만 리턴해주는 메서드 mav.setViewName("upload/uploadResult"); mav.addObject("savedName", savedName); //uploadResult페이지에는 업로드된 파일 이름만 포워딩해주면 된다. return mav; //uploadResult.jsp로 포워딩 } //파일 이름이 중복되지 않도록 처리 //파일 원래 이름과 내용 매개값으로 받아옴 private String uploadFile(String originalName, byte[] fileData) throws Exception { //uuid 생성 (Universal Unique Identifier, 범용 고유 식별자) //java.util.UUID UUID uid = UUID.randomUUID();//클래스멤버 //저장된 파일 이름 : uuid + _ + //uuid타입이므로 toString() 처리해줘야함 String savedName = uid.toString() + "_" + originalName; //java.io의 File 클래스 객체 생성하여 //매개값으로 업로드 경로와 저장할 이름 넣기 File target = new File(uploadPath, savedName); //★★★ //임시 디렉토리에 저장된 업로드된 파일을 지정된 디렉토리로 복사 //FileCopyUtils.copy(바이트 배열, 파일 객체) //target은 uploadPath설정, 이름 설정 완료된 객체 //fileData는 파일 내용 //임시디렉토리가 어디...??아무튼 uploadPath에 파일 복사해주는 과정 FileCopyUtils.copy(fileData, target); return savedName; } } | cs |
파일 종류? : 파일 어플리케이션 이름, 확장자 같은 파일 종류 정보인듯
로깅툴 ('spring 3강 로깅, 데이터베이스(Oracle) 연결 테스트' 에 정리한 내용 )
1) 로깅툴을 사용하는 이유
- System.out.println()은 IO리소스를 많이 사용하여 시스템이 느려질 수 있음
- 로그를 파일로 저장하여 분석할 필요가 있음
2) 로깅툴의 종류
- commons-logging : 스프링3에서 사용하던 로깅툴
- log4j : 효율적인 메모리 관리로 그동안 많이 사용되었음
- logback : log4j보다 성능이 우수하여 최근에 많이 사용되고 있음
SLF4J : logback 사용을 위한 인터페이스
SLF4J 설정 방법 //sample 프로젝트에 이미 설정돼있음
1. pom.xml 의 slf4j-version을 1.7.25로 설정
2. pom.xml 에 라이브러리 추가
3. src/main/resouces에 있는 logback.xml 파일 작성
4. 로그를 수집할 클래스에 변수 선언
5. 로그를 수집할 method에서 로그 수집 명령어 호출
uploadResult.jsp는 uploadForm.jsp의 iframe으로 들어가도록 함
아이프레임이란 내부 프레임(inline frame)이라는 의미로 하나의 HTML문서내에서 다른 HTML문서를 보여주고자 할때 사용합니다.
일반적인 프레임(frame)과 비교해보면 아이프레임은 <frameset> 태그 사이에 올 필요가 없으며, 독립적으로 마치 <img> 태그를 사용하듯 문서 내의
원하는 위치에 삽입할 수 있습니다.
아이프레임에서 사용할 수 있는 속성도 <img> 태그과 유사합니다.
uploadForm.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 | <%@ 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" %> <style> /* uploadResult.jsp 표시할 부분 iframe으로 설정 */ iframe { width : 400px; height : 200px; border : 1px; border-style : solid; } </style> </head> <body> <%@ include file="../include/menu.jsp" %> <!--폼데이터 POST방식으로 보내기/ enctype="multipart/form-data" ★★★ target="iframe1"설정 해놓으면 데이터 처리 결과가 아래의 iframe1으로 간다. uploadFile 메서드는 업로드된 파일 이름만 리턴한다--> <form id="form1" action="${path}upload/uploadForm" method="post" enctype = "multipart/form-data" target="iframe1"> <!-- input type=file의 name값은 upload/uploadForm으로 url매핑된 메서드의 MultipartFile 매개값과 이름이 같아야함★★★ --> <input type ="file" name ="file"> <input type ="submit" value="업로드"> </form> <iframe name="iframe1"></iframe> </body> </html> | cs |
UploadController.java
uploadResult.jsp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | <%@ 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> 파일이 업로드 되었습니다. 파일명 : ${savedName} </body> </html> | cs |
form 태그의 enctype //인코딩 타입
파일을 업로드 할때 <form>태그에서 ENCTYPE="multipart/form-data"라는 애트리뷰트를 반드시 써야 한다.
그렇게 하지 않으면 웹 서버로 데이터를 넘길때 파일의 경로명만 전송되고 파일 내용이 전송되지 않기 때문이다.
그리고 이때 METHOD 애트리뷰트에는 'POST' 값을 지정해야 한다.
** <form>태그의 속성인 method, action, enctype 등은 입력받은 데이터를 어떻게 처리할 것인지 세부적으로 설정하는 데 사용된다.
method는 전송 방식,
action은 전송 목적지,
enctype은 전송되는 데이터 형식을 설정한다.
** enctype
enctype 속성은 다음 세가지의 값으로 지정될 수 있다.
1. application/www-form-urlencoded
디폴트값이다. enctype을 따로 설정하지 않으면 이 값이 설정된다. 폼데이터는 서버로 전송되기 전에 URL-Encode 된다.
2. multipart/form-data
파일이나 이미지를 서버로 전송할 경우 이 방식을 사용한다.
3. text/plain
이 형식은 인코딩을 하지 않은 문자 상태로 전송한다.
출처: https://tibang.tistory.com/entry/form태그의-enctype-속성 [T없이맑은날]
'Spring > study' 카테고리의 다른 글
상품관리 프로젝트 코드 작성 -3 (0) | 2019.06.18 |
---|---|
상품관리 프로젝트 코드 작성 -2 (0) | 2019.06.14 |
spring 7강 상품테이블 만들기, File Upload 테스트 (0) | 2019.06.11 |
spring 6강 Oracle과 mybatis 연동 실습(자바 코드에 SQL 명령어를 함께 작성하는 방식) (0) | 2019.06.06 |
스프링 한글 처리를 위한 인코딩 필터 (0) | 2019.06.05 |