💡 핵심 요약 (TL;DR)
Servlet일반상품3 : 상품 상세페이지, c:forTokens의 동작 원리를 이해하고 실제 프로젝트에 적용하기 위한 실무 가이드다.
* 변수를 굳이 사용하지않는다면 한 줄코딩하는 것이 좋다.
GoodsFrontController.java의 doProcess()의 주소비교 후 처리부분에 코드 추가
1 2 3 4 5 6 7 8
| }else if(command.equals("/GoodsDetail.go")){ System.out.println("C: /GoodsList.go 호출"); action = new GoodsDetailAction(); try { forward = action.execute(request, response); } catch (Exception e) { e.printStackTrace(); } }
|
GoodsDetailAction.java 생성
- GoodsDAO객체 생성 후 getGoodsDetail()생성시 아래 코드를 한줄로 나타낼 수 있다.
- 변수를 굳이 사용하지않는다면 한 줄코딩하는 것이 좋다.
1 2 3 4 5 6
| GoodsDTO gdto = gdao.getGoodsDetail(gno); request.setAttribute("gdto", gdto);
request.setAttribute("gdto", gdao.getGoodsDetail(gno));
|
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
| public class GoodsDetailAction implements Action {
@Override public ActionForward execute(HttpServletRequest request, HttpServletResponse response) throws Exception { System.out.println("M : GoodsDetailAction의 execute() 호출"); request.setCharacterEncoding("UTF-8"); int gno = Integer.parseInt(request.getParameter("gno")); GoodsDAO gdao = new GoodsDAO(); GoodsDTO gdto = gdao.getGoodsDetail(gno); request.setAttribute("gdto", gdto); ActionForward forward = new ActionForward(); forward.setPath("./goods/goods_detail.jsp"); forward.setRedirect(false); return forward; } }
|
AdminGoodsDAO.java 생성 후 getGoodsDetail()메서드 코드 추가
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
| public GoodsDTO getGoodsDetail(int gno) { GoodsDTO gdto = null; try { getCon(); sql = "select * from itwill_goods where gno=?"; pstmt = con.prepareStatement(sql); pstmt.setInt(1, gno); rs = pstmt.executeQuery(); if(rs.next()){ gdto = new GoodsDTO(); gdto.setGno(rs.getInt("gno")); gdto.setCategory(rs.getString("category")); gdto.setName(rs.getString("name")); gdto.setPrice(rs.getInt("price")); gdto.setColor(rs.getString("color"));
gdto.setAmount(rs.getInt("amount")); gdto.setSize(rs.getString("size")); gdto.setContent(rs.getString("content")); gdto.setImage(rs.getString("image")); gdto.setBest(rs.getInt("best"));
gdto.setDate(rs.getDate("date")); } System.out.println("상품 상세정보 저장 완료"); } catch (Exception e) { e.printStackTrace(); } finally { closeDB(); } return gdto; }
|
goods_detail.jsp 생성
- DB의 정보를 request에 저장했고 그걸 불러와서 select항목에 넣을 수 있다. 이때 두가지 방법이 있다.
- <c:forEach>와 <c:forTokens>의 차이점은 <c:forTokens>의 경우 문자열을 분리자를 사용해서 분리해서 출력가능
1 2 3 4 5 6 7 8
| <c:forTokens var="name" items="고양이,강아지,소" delims=","> <p><c:out value="${name}"/></p> </c:forTokens>
//출력결과 고양이 강아지 소
|
첫번째 방법 : forTokens +스크립틀릿사용
1 2 3 4 5 6 7 8 9 10 11 12
| <select> <option value="">선택하세요</option> <c:forTokens var="size" items=""<%=gdto.getSize() %>" delims = ","> <option value="${gdto.size}">${size}</option> </c:forTokens> </select>
//출력값 S M L XL
|
두번째 방법 : forTokens + EL태그사용
1 2 3 4 5 6 7 8 9 10 11 12
| <select> <option value="">선택하세요</option> <c:forTokens var="color" items="${gdto.color}" delims = ","> <option value="${gdto.color}">${color}</option> </c:forTokens> </select> <br>
//출력값 white black yellow
|
javascript 코드 한줄로 불러오기
- a태그를 이용하면 href로 항상 페이지이동이 된다. 이를 막기 위해서는 2가지 방법이 있다.
- e.preventDefault();
javascript:isBasket();
1 2 3 4 5
| //원치않는 href="#"가 진행되어 페이지이동이 일어난다(여기선 새로고침) <a href="" onclick="isBasket();"> [장바구니 담기] </a>
//이렇게부르면 페이지이동없이 자바스크립트를 실행할 수 있다 <a href="javascript:isBasket();"> [장바구니 담기] </a>
|
구매수량이 재고보다 많은 경우 제어
- 자바표현식 : DB정보를 꺼내오기 불가능. 페이지 구성상 제일 마지막에 호출되므로 자바표현식으로 사용불가능
- EL표현식 : DB정보를 꺼내오기 가능.
- 자바스크립트태그안에서는 EL표현식을 문자형태(‘’)로 사용하는 것이 일반적.
- 문자형태로 쓰지않아도 객체로 처리되기때문에 동일하게 처리되나 문법상 문자형태로 (‘’)써줘야 함.
1 2 3 4 5 6 7 8 9 10 11 12 13
| // 구매 수량 var buyCnt = document.goodsform.amount.value;
// 남은 수량 (DTO정보) var DBCnt = <%=gdto.getAmount()%> //에러 var DBCnt = ${gdto.amount}; //사용가능 var DBCnt = '${gdto.amount}'; //문자형태도 사용가능
if(buyCnt > DBCnt){ alert("구매 수량을 조절하시오"); document.goodsform.amount.focus(); return; }
|
전체코드
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
| <% // GoodsDetailAction 에서 저장한 상품 정보를 받아오기 GoodsDTO gdto = (GoodsDTO) request.getAttribute("gdto"); %>
<form action="" method="post" name="goodsform"> <input type="hidden" name="name" value="<%=gdto.getName()%>"> <input type="hidden" name="price" value="${gdto.price }"> <table border="1"> <tr> <td> <img src="./upload/<%=gdto.getImage().split(",")[0]%>" width="300" height="300"> </td> <td> 상품명 : ${gdto.name} <br> 판매가격 : <%=gdto.getPrice() %>원<br> 구매수량 : <input type="text" name="amount">개<br> 남은수량 : ${gdto.amount}개<br> 크기 : <select name="size"> <option value="">선택하세요</option> <c:forTokens var="size" items="<%=gdto.getSize() %>" delims = ","> <option>${size}</option> </c:forTokens> </select> <br> 색상 : <select name="color"> <option value="">선택하세요</option> <c:forTokens var="color" items="${gdto.color}" delims = ","> <option>${color}</option> </c:forTokens> </select> <br> <input type="button" class="btn" value="[장바구니 담기]" onclick="javascript:isBasket();" > <input type="button" class="btn" value="[바로 구매하기]" onclick="javascript:isBasket();"> </td> </tr> <tr> <td colspan="2"> <h2>상세페이지</h2> <img src="./upload/<%=gdto.getImage().split(",")[0]%>" width="400" height="600"> </td> </tr> </table> </form>
<script type="text/javascript">
function isBasket() { if(document.goodsform.size.value == ""){ alert("사이즈를 선택하세요"); document.goodsform.size.focus(); return false; } if(document.goodsform.color.value == ""){ alert("색상을 선택하세요"); document.goodsform.color.focus(); return; } if(document.goodsform.amount.value == ""){ alert("수량을 입력하세요"); document.goodsform.amount.focus(); return; }else if(document.goodsform.amount.value > ${gdto.amount}){ alert("수량을 남은 수량 ${gdto.amount}개 이하로 입력하세요"); document.goodsform.amount.focus(); return; } let result = confirm("장바구니로 이동하시겠습니까?"); if(result){ document.goodsform.action = "./BasketAdd.ba?gno=${gdto.gno}"; document.goodsform.submit(); }else{ return; } } </script>
|
#TILITWILL(JAVA)