본문 바로가기
카테고리 없음

상품관리 프로젝트 코드 작성 -4

by avvin 2019. 6. 23.

 상품관리 프로젝트 코드 작성 -4


상품관리 예제 코드 작성 순서 

 

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 DAO > Mapper(sample매퍼 사용) > Service > Controller 작성

    관리자 페이지, 관리자 로그인 페이지, 관리자 메뉴 페이지.jsp


    ProductController에 만들어둔 insert.do /  url맵핑된 메서드 작성




관리자 로그인


상품관리_관리자.sql

1
2
3
4
5
6
7
8
9
10
11
12
13
14
create table admin(
userid varchar2(50) not null,
passwd varchar2(50) not null,
name varchar2(50) not null,
email varchar2(100),
join_date date default sysdate,
primary key(userid)
);
 
insert into admin(userid, passwd, name) values ('admin''1234''관리자');
 
select * from admin;
 
commit;


admin 테이블을 생성하는데 MemberDTO와 같은 구성이므로 데이터 맵핑 타입은 MemberDTO로 한다.


private String userid;

private String passwd;

private String name;

private String email;

private Date join_date;



AdminDAO.java

1
2
3
4
5
6
7
8
9
10
package com.example.spring02test.model.admin;
 
import com.example.spring02test.model.member.DTO.MemberDTO;
 
public interface AdminDAO {
 
    //MemberDAO와 다를게 없음, 매퍼에서 접근하는 테이블명만 다르다.
    public String login_check(MemberDTO dto);
}
 
cs



AdminDAOImpl.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package com.example.spring02test.model.admin;
 
import javax.inject.Inject;
 
import org.apache.ibatis.session.SqlSession;
 
import com.example.spring02test.model.member.DTO.MemberDTO;
 @Repository
public class AdminDAOImpl implements AdminDAO {
 
    @Inject
    SqlSession session;
    
    @Override
    public String login_check(MemberDTO dto) {
        
        return session.selectOne("admin.login_check", dto);
    }
 
}
 
cs



AdminService.java

1
2
3
4
5
6
7
8
9
10
11
12
13
package com.example.spring02test.service.admin;
 
import com.example.spring02test.model.member.DTO.MemberDTO;
 
public interface AdminService {
    
    //Member 로그인 데이터 처리할 때는 서비스에서 세션 객체 데이터 처리하던데 
    //Admin 로그인할때 세션객체 처리는 컨트롤러에서 다 하는듯함 (왜 방식을 통일하지 않은건지...)
    //logout도 db에 접속할 필요 없이 세션만 초기화해주면 되는거라 
    //세션객체 데이터 처리를 컨트롤러에서 하는거면 로그아웃 메서드도 컨트롤러에만 있으면 된다.
    public String login_check(MemberDTO dto);
    
}
cs




AdminServiceImpl.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package com.example.spring02test.service.admin;
 
import javax.inject.Inject;
 
import org.springframework.stereotype.Service;
 
import com.example.spring02test.model.admin.AdminDAO;
import com.example.spring02test.model.member.DTO.MemberDTO;
 
@Service
public class AdminServiceImpl implements AdminService {
 
    @Inject
    AdminDAO adminDao;
    
    @Override
    public String login_check(MemberDTO dto) {
        return adminDao.login_check(dto);
    }
}





AdminController.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
package com.example.spring02test.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.spring02test.model.member.DTO.MemberDTO;
import com.example.spring02test.service.admin.AdminService;
 
@Controller
@RequestMapping("/admin/*")
public class AdminController {
 
    @Inject
    AdminService adminService;
    
    //로그인창으로 넘겨주는 메서드
    @RequestMapping("login.do")
    public String login() {
        return "admin/login";
    }
    
    
    //로그인 시도 시 실행
    @RequestMapping("login_check.do")
    public ModelAndView login_check(
            MemberDTO dto, HttpSession session, ModelAndView mav) {
        
        String name = adminService.login_check(dto);
        
        if(name != null) { //로그인 성공시
            
            //로그인 성공시에 세션에 로그인 정보를 담아야한다.
            //기껏 세션 객체 파라미터 자리에 위치시켜놓고 안쓰면 안된다.
            //관리자 계정의 아이디, 이름 저장
            session.setAttribute("admin_userid"dto.getUserid());
            session.setAttribute("admmin_name"dto.getName());
            
            mav.setViewName("admin/admin");
            mav.addObject("message""success");
            
            return mav;
        } 
    
        mav.setViewName("admin/login");
        mav.addObject("message""error");
    //error와 success로 로그인 성공여부 알아내어 c:if 사용할 예정
        
        return mav;
    }
    
    //관리자 로그아웃 처리
    @RequestMapping("logout.do")
    public String logout(HttpSession session) {
        
        session.invalidate();//세션 무효화
        
        return "redirect:/admin/login.do"
    }
    
}






admin.jsp (관리자 메뉴 페이지)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<%@ 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" %>
 
<c:if test="${message =='success' }">
 
<h2> ${sessionScope.admin_name }
     ${sessionScope.admin_user_id }님 환영합니다. </h2>
 
</c:if>
</body>
</html>r

c



자바 코드인 session.getAttribute("id"); 대신 EL문에서 ${sessionScope.id } 로 표현


admin/login.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
<%@ 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>
$(function(){
    $("#btnLogin").click(function(){
        var userid = $("#userid").val();
        var passwd = $("#passwd").val();
    if(userid==""){
        alert("아이디를 입력하세요");
        $("#userid").focus();
        return;
    }
    if(passwd==""){
        alert("비밀번호를 입력하세요");
        $("#passwd").focus();
        return;
    }
        //form에 action이 설정돼있지 않고, submit도 없다.
        //button은 폼데이터를 다른 페이지로 넘기는 기능이 없으므로 
        //자바스크립트 함수를 이용해 넘기는데, 
        //이 때, 자바스크립트에서 html의 기능을 구현해주기도하는
        //document 객체를 사용한다. 
        document.form1.action="${path}/admin/login_check.do"
        document.form1.submit();
    });
    
});
 
</script>
</head>
<body>
<%@ include file="../include/menu.jsp" %>
<h2>관리자 로그인</h2>
<form name="form1" method="post">
<table border="1" method="post">
 
<tr>
    <td>아이디 </td>
    <!-- type안쓰면 기본값은 type="text"-->
    <td> <input id="userid" name="userid"> </td>
</tr>
<tr>
    <td>
        <input type="password" id="passwd" name="passwd">
    </td>
</tr>
<tr>
    <td colspan="2" align="center">
        <button type="button" id="btnLogin" > 로그인 </button>
    
        <c:if test="${param.message == 'nologin'}">
            <div style="color:red">
                로그인 하세요.
            </div>
        </c:if>
        
        <c:if test="${message=='error'}">
            <div style="color:red">
                아이디와 비밀번호를 확인해주세요.
            </div>
        </c:if>
        
        <c:if test="${message=='logout'}">
            <div style="color:red">
                로그아웃 되었습니다.
            </div>
        </c:if>
    </td>
</tr>
</table>
</form>
</body>
</html>




- 표현식으로 attribute / parameter 등을 JSP파일에서 출력할 용도로 사용하는 언어

attribute $[ atribute 이름 ]으로 출력 

파라미터는 ${param.이름} 또는 ${ paramValue.이름[인덱스] }의 형태로 출력




include/admin_menu.jsp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<a href="${path}/shop/product/list.do">상품목록</a>
<a href="${path}/shop/product/write.do">상품등록</a>
<c:choose>
    <c:when test="${sessionScope.admin_userid == null }">
        <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>
<hr>







상품 등록 / 수정 / 삭제하기



배포디렉토리 확인하기(getRealPath()는 현재 프로젝트 위치를 반환하므로 뒤에 파일 경로도 써줘야한다.)
1
2
3
4
5
<!-- 개발디렉토리에 있는 데이터를 톰캣이 배포디렉토리에 카피한다. -->
<!-- 배포 디렉토리(실제 경로) 확인 ★★★-->
<!--application (javax.servlet.ServletContext )
    : 웹 어플리케이션 Context의 정보를 저장하고 있는 객체   -->
<%=application.getRealPath("/"%>
cs




product_list.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
<%@ 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>
$(function(){
    $("#btnAdd").click(function(){
        loation.href="${path}/shop/product/write.do";    
    });
}); /* Add버튼을 누르면 write.do 실행하는 함수 */
 
</script>
</head>
<body>
<%@ include file="../include/menu.jsp" %>
<h2>상품 목록</h2>
<button type="button" id="btnAdd"> 상품 등록 </button>
<table border="1" width="500px">
    <tr>
        <th> 상품ID</th>
        <th>&nbsp;</th>
        <th>상품명</th>
        <th>가격</th>
    </tr>
 
<!-- list(ProductDTO)의 원소 변수 row 선언-->
<c:forEach var="row" items="${list}">
    <tr align="center">
        <td>${row.product_id}</td>
        <td>
            <img src="${path}/images/${row.picture_url}" 
            width="100" height="100">
        </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>
cs




MultipartFile 인터페이스에서 많이 쓰이는 메소드들

 메  소  드내    용 
 String getName() 파라미터 이름 
 String getOriginalFilename() 파일 이름 
 boolean isEmpty() 파일이 존재하지 않으면 true 반환 
 long getSize() 파일 크기 
 byte[] getBytes() throws IOException 파일 데이터 
 InputStream getInputStream() throws IOException  파일 데이터를 읽어오는 InputStream을 얻어온다
 사용이 끝난 후에는 알아서 잘 종료 해줄 것
 void transferTo(File file) throws IOException 파일 데이터를 지정한 file로 저장

출처: https://ggoreb.tistory.com/73 [나는 초보다]




관리자 메뉴 [상품등록]


ProductController.java : write.do 
1
2
3
4
    @RequestMapping("write.do")
    public String write() {
        return "shop/product_write";
    }//데이터처리 없이 글쓰기 페이지로 포워딩
cs


웹에디터(Web Editor)는 인터넷 홈페이지를 제작할 수 있게 해주는 홈페이지 전문 저작 도구이다. 
홈페이지나 인터넷에서 쓰이는 HTML(Hyper Text Markup Language) 양식의 문서를 만들려면 HTML 태그를 이용해야 한다. 
여러가지 명령어로 문자는 물론 그림, 동영상과 소리, 홈페이지나 웹사이트 연결까지 가능한 HTML 문서를 만들게 해주는 프로그램이 바로 웹에디터다.

[네이버 지식백과] 웹에디터 [Web Editer] (매일경제, 매경닷컴)


product_write.jsp

ckeditor사용하는데 ckeditor에 대한 내용 인강에 X...

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
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
    <!-- views/shop/product_write.jsp -->
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<%@ include file="../include/header.jsp" %>
<!-- ckeditor 사용을 위해 js 파일 연결 -->
<script src="${path}/ckeditor/ckeditor.js"></script>
</head>
<body>
<%@ include file="../include/admin_menu.jsp" %>
<script>
function product_write(){
    // 태그를 name으로 조회할 경우
    //var product_name=document.form1.product_name.value;
    // 태그를 id로 조회할 경우
    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";
    //폼 데이터를 서버에 전송
    document.form1.submit();
}
</script>
 
 
<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>
<script>
//id가 description인 태그에 ckeditor를 적용시킴
//CKEDITOR.replace("description"); //이미지 업로드 안됨
CKEDITOR.replace("description",{
    filebrowserUploadUrl : "${path}/imageUpload.do"
});
</script>            
        </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="javascript:product_write()">
            <input type="button" value="목록"
onclick="location.href='${path}/shop/product/list.do'">
        </td>
    </tr>
</table>    
</form>
 
</body>
</html>
 
cs



ProductController.java : insert.do
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
    //상품 등록
    @RequestMapping("insert.do")
    public String insertProduct(ProductDTO dto) {        
    
        //새로운 첨부파일이 있으면 
        //경로 변수에 배포디렉토리를 등록하고
        //배포 디렉토리 확인 : 앞부분은 <%=application.getRealPath("/") %>
        //프로젝트 단위 이하 파일 경로는 같다
        //File객체로 배포디렉토리가 존재하지 않을 시 디렉토리 생성하는 함수 호출
        //임시 디렉토리에 저장된 첨부파일을 이동???
        //
        //인강에 자세한 내용은 X
        
        String filename="";
        //file1은 dto에 만들어둔 파일을 다루는 객체 필드
        //이 객체가 비어있지 않다면 
        //== 파일객체(임시디렉토리)에 저장된 첨부파일을 배포디렉토리로 이동?
        if(!dto.getFile1().isEmpty()) {
            //첨부 파일의 이름
            filename=dto.getFile1().getOriginalFilename();
            //파일, 디렉토리 다룰땐 예외처리 필수
            try {
                String path="D:\\work\\.metadata\\.plugins\\"
                + "org.eclipse.wst.server.core\\tmp1\\wtpwebapps\\"
                + "spring02\\WEB-INF\\views\\images\\";
                
                //디렉토리가 존재하지 않으면 생성
                new File(path).mkdir();
                 //파일객체에 저장된 (임시 디렉토리에 저장된) 첨부파일을 이동
                //디렉토리를 생성했으니 new File(경로 + 파일이름)으로 파일을 생성하고
                // (MultipartFile)file객체의 
                //transferTo(데이터 붙여넣기 될 파일)메서드를 사용하여 파일 복사
                dto.getFile1().transferTo(new File(path+filename));
                
            } catch (Exception e) {
                e.printStackTrace();
            }    
        } 
        //picture_url에는 파일 이름이 들어간다.
        dto.setPicture_url(filename);//String타입
        //여기까지 updateProduct와 똑같다.
        //updatProduct는 상품 정보 수정시 새로 첨부된 파일이 없으면
        //else문을 통해 기존에 있던 파일을 file 객체에 저장한다.
        //insertProduct이므로 file 객체가 비어있으면 아무 처리도 하지 않는다.
        
        productService.insertProduct(dto);
    
        return "redirect:/shop/product/list.do";
    }
    
cs





ProductController.java : edit.do 
1
2
3
4
5
6
7
8
9
10
11
    // 상품 디테일 정보 불러와서 수정
    @RequestMapping("edit/{product_id}")
    public ModelAndView edit(
            @PathVariable("product_id"int product_id, ModelAndView mav) {
        
        mav.setViewName("shop/product_edit");
        
        mav.addObject("dto", productService.detailProduct(product_id));
        
        return mav;
    }
cs



ProductController.java : update.do
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
    //상품 정보 수정
    @RequestMapping("update.do")
    public String updateProduct(ProductDTO dto) {
        //새로운 첨부파일이 있으면 
        //경로 변수에 배포디렉토리를 등록하고
        //배포 디렉토리 확인 : 앞부분은 <%=application.getRealPath("/") %>
        //프로젝트 단위 이하 파일 경로는 같다
        //File객체로 배포디렉토리가 존재하지 않을 시 디렉토리 생성하는 함수 호출
        //임시 디렉토리에 저장된 첨부파일을 이동???
        //
        //인강에 자세한 내용은 X
        
        String filename="";
        //file1은 dto에 만들어둔 파일을 다루는 객체 필드
        //이 객체가 비어있지 않다면 
        //== 파일객체(임시디렉토리)에 저장된 첨부파일을 배포디렉토리로 이동?
        if(!dto.getFile1().isEmpty()) {
            //첨부 파일의 이름
            filename=dto.getFile1().getOriginalFilename();
            //파일, 디렉토리 다룰땐 예외처리 필수
            try {
                String path="D:\\work\\.metadata\\.plugins\\"
                + "org.eclipse.wst.server.core\\tmp1\\wtpwebapps\\"
                + "spring02\\WEB-INF\\views\\images\\";
                
                //디렉토리가 존재하지 않으면 생성
                new File(path).mkdir();
                 //파일객체에 저장된 (임시 디렉토리에 저장된) 첨부파일을 이동
                //디렉토리를 생성했으니 new File(경로 + 파일이름)으로 파일을 생성하고
                // (MultipartFile)file객체의 
                //transferTo(데이터 붙여넣기 될 파일)메서드를 사용하여 파일 복사
                dto.getFile1().transferTo(new File(path+filename));
                
            } catch (Exception e) {
                e.printStackTrace();
            }
            //picture_url에는 파일 이름이 들어간다.
            dto.setPicture_url(filename);//String타입
            
        } else { //(상품)"새로운" 첨부파일이 없을때
            //기존에 첨부한 파일 정보를 가져와서
            ProductDTO dto2 = productService.detailProduct(dto.getProduct_id());
            //저장
            dto.setPicture_url(dto2.getPicture_url());
        }
    
        productService.updateProduct(dto);
        return "redirect:/shop/product/list.do";
    }
cs



ProductController.java : delete.do
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
    //상품 삭제
    //@RequestParam은 폼의 개별값, 
    //@ModelAtrribute는 폼의 전체 데이터(dto) 받아올 때 사용
    @RequestMapping("delete.do")
    public String delete(@RequestParam int product_id) {
        //첨부파일 삭제
        String filename = productService.fileInfo(product_id);
        System.out.println("첨부파일 이름 : " +filename);
        if(filename != null && !filename.equals("")) {
            String path = "D:\\work\\.metadata\\.plugins\\org.eclipse.wst.server.core"
                    + "\\tmp1\\wtpwebapps\\spring02\\WEB-INF\\views\\images\\"//상품이미지 디렉토리
            
            File f = new File(path+filename);
            System.out.println("파일존재여부 :" + f.exists());
            if(f.exists()) {
                f.delete();
                System.out.println("삭제되었습니다.");
            }
        }
        
        //레코드 삭제
        productService.deletePrduct(product_id);
        //화면 이동
        return "redirect:/shop/product/list.do";
    }