JSP 강의 Day09

주세환·2023년 4월 11일
0

JSP

목록 보기
9/16

물품등록

등록된 이미지 출력

// 이미지 1개 가져가기
@Select({
	" SELECT i.* FROM itemimage i WHERE NO = #{no} "
})
public ItemImage selectItemImageOne(@Param("no") long no); //이미지번호

// 물품번호를 이용해서 관련된 전체 이미지 번호 반환
@Select({
	" SELECT i.NO FROM itemimage i WHERE ITEMNO = #{itemno} ORDER BY no DESC "
})
public List<Long> selectItemImageNo (@Param("itemno") long itemno);

우선 mapper를 생성한다.

@WebServlet(urlPatterns = "/item/image")
public class ItemImageServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
		ItemImageMapper mapper = MybatisContext.getSqlSession().getMapper(ItemImageMapper.class);
		
		long no = Long.parseLong(request.getParameter("no"));
		//no를 전달하여 mapper에서 ItemImage정보 1개 가져옴.
		ItemImage obj = mapper.selectItemImageOne(no);
		
		response.setContentType(obj.getFiletype()); // 이건 이미지다. html 아니다.
		response.setStatus(200); // 200은 정상적인 처리결과다.
		response.getOutputStream().write(obj.getFiledata()); // 이게 실제 정보다.
		
	}
}

저번에 만든 ItemImageServlet.java를 가져온다.

이제 postman을 열어보자.

ItemImageServlet에 정의해둔 주소인 /item/image에 no까지 입력하면 해당하는 사진이 보이게 된다.

이때 no는 데이터베이스에서 보고 확인해야 한다.


protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
	
	ItemImageMapper mapper = MybatisContext.getSqlSession().getMapper(ItemImageMapper.class);
	
	long no = Long.parseLong(request.getParameter("no"));
	//no를 전달하여 mapper에서 ItemImage정보 1개 가져옴.
	ItemImage obj = mapper.selectItemImageOne(no);
	
	response.setContentType(obj.getFiletype()); // 이건 이미지다. html 아니다.
	response.setStatus(200); // 200은 정상적인 처리결과다.
	response.getOutputStream().write(obj.getFiledata()); // 이게 실제 정보다.
	
}

Servlet을 위처럼 수정하고

 </form>
           
           <hr />
           <c:forEach var="no" items="${imageNo}">]
           	<img src="${pageContext.request.contextPath}/item/image?no=${no}"
           		style="width:100px;height:100px" />
           	<button>수정</button>	
           	<button>삭제</button>
           	<br />	
           </c:forEach>
           
	</div>
</div>

<script>

item_image_write.jsp를 위처럼 수정하면

이렇게 등록되어있는 사진들과 수정, 삭제 버튼이 추가된다.


삭제기능

<button onclick="itemImageDelete('${no}}', '${ino}')">삭제</button>

...

<script>

function itemImageDelete(no, ino) { // 삭제할이미지번호, 물품번호
	const ret = confirm('삭제할까요?');
	if(ret === true) {
		//<form action="imagedelete.do" method="post" style="display:none;">
		var form = document.createElement("form");
		form.setAttribute("action", "imagedelete.do");
		form.setAttribute("method", "post");
		form.style.display="none";

		//<input type="hidden" name="imageno" value="삭제할번호" />
		var input = document.createElement("input");
		input.setAttribute("type", "hidden")
		input.setAttribute("name", "imageno");
		input.setAttribute("value", Number(no)); // typescript
		
		//<input type="hidden" name="ino" value="삭제할번호" />
		var input1 = document.createElement("input");
		input1.setAttribute("type", "hidden")
		input1.setAttribute("name", "ino");
		input1.setAttribute("value", Number(ino));
		
		// form태그에 추가
		form.appendChild(input);
		form.appendChild(input1);
		// body에 추가
		document.body.appendChild(form);
		// form전송
		form.submit();
	}
}

item_image_write.jsp의 버튼을 수정하고 script에 삭제기능을 추가하였다.

삭제를 누르면 알림창이 뜨고

확인을 누르니 imagedelete.do로 이동한다.

@WebServlet(urlPatterns = {"/item/imagedelete.do"})
@MultipartConfig()
public class ItemImageDeleteController extends HttpServlet {
	private static final long serialVersionUID = 1L;


	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		Long ino = Long.parseLong( request.getParameter("ino"));
		Long imageNo = Long.parseLong( request.getParameter("imageno"));
		
		// mapper를 이용해서 삭제
		
		int ret = MybatisContext.getSqlSession().getMapper(ItemImageMapper.class).deleteItemImageOne(imageNo);
		if( ret == 1 ) {
			// 절대 경로를 이용한 페이지 이동
			response.sendRedirect(request.getContextPath() +"/item" + "/imagewrite.do?ino="+ino);
		}
		else {
			// 상대 경로를 이용한 페이지 이동
			response.sendRedirect("imagewrite.do?ino="+ino);

		}
	}
}

ItemImageDeleteController.java를 생성하자.

삭제를 눌렀더니

이렇게 오류가 떴다. 문제를 찾아보자.

<button onclick="itemImageDelete('${no}', '${ino}')">삭제</button>

에서 ${no}}로 되어있었다.

삭제를 누르면

정상적으로 삭제되고 주소도 그대로 돌아온다.


수정기능

	<!-- 이미지 수정 모달창 -->
	<!-- Modal -->
	<div class="modal fade" id="exampleModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
	  <div class="modal-dialog">
	    <div class="modal-content">
	      <div class="modal-header">
	        <h5 class="modal-title fs-5" id="exampleModalLabel">Modal title</h5>
	        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
	      </div>
	      <div class="modal-body">
	        ...
	      </div>
	      <div class="modal-footer">
	        <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
	        <button type="button" class="btn btn-primary">Save changes</button>
	      </div>
	    </div>
	  </div>
	</div>
	
	<script src="${pageContext.request.contextPath}/resources/js/jquery-3.6.4.min.js"></script>
	<script src="${pageContext.request.contextPath}/resources/js/bootstrap.min.js"></script>
	<script>
	
		function itemUpdateModal() {
			const modal = new bootstrap.Modal(document.getElementById("exampleModal"),{});
			modal.show();
		}

이미지 수정 모달, jQuery, bootstrap, 함수를 추가한다.

수정버튼을 누른 상태이다.

이제 모달창을 입맛대로 바꿔볼 차례이다.

<div class="modal fade" id="exampleModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
	  <div class="modal-dialog">
	    <div class="modal-content">
	      <div class="modal-header">
	        <h5 class="modal-title fs-5" id="exampleModalLabel">이미지 수정</h5>
	        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
	      </div>
	      <div class="modal-body">
	        이미지 번호 : <input type="text" readonly />
	        현재 이미지 : <img src="" style="width:100px;height:100px" />
	        변경 이미지 : <input type="file" />
	      </div>
	      <div class="modal-footer">
	        <button type="button" class="btn btn-primary">저장</button>
	        <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">취소</button>
	      </div>
	    </div>
	  </div>
	</div>

이렇게 바꾸었다.

이제 필요한 값들을 추가하자.

<c:forEach var="no" items="${imageNo}">
            	${no} => 
            	<img src="${pageContext.request.contextPath}/item/image?no=${no}"
            		style="width:100px;height:100px" />
            	<button onclick="itemUpdateModal()">수정</button>	
            	<button onclick="itemImageDelete('${no}', '${ino}')">삭제</button>
            	<br />	
            </c:forEach>

위 항목을 추가하면

각 사진에 해당하는 번호가 추가된다.

Modal -->
<div class="modal fade" id="exampleModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
  <form action="imageupdate.do" method="post" enctype="multipart/form-data">
  <div class="modal-dialog">
    <div class="modal-content">
    
		<div class="modal-header">
		  <h5 class="modal-title fs-5" id="exampleModalLabel">이미지 수정</h5>
		  <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
		</div>
		
		<div class="modal-body">
		  이미지 번호 : <input type="text" id="modal_image_no" readonly /><br />
		  현재 이미지 : <img src="" style="width:100px;height:100px" id="modal_image_src" /><br />
		  변경 이미지 : <input type="file" id="modal_image_file" /><br />
		</div>
		
		<div class="modal-footer">
		  <button type="button" class="btn btn-primary">저장</button>
		  <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">취소</button>
		</div>
    </div>
  </div>
  </form>
</div>
...

function itemUpdateModal(no, ino) {
	const imageNo = document.getElementById("modal_image_no");
	const imageSrc = document.getElementById("modal_image_src");
	const imageFile = document.getElementById("modal_image_file");
	
	imageNo.value = no;
	imageSrc.src = '${pageContext.request.contextPath}/item/image?no=' + no;

위처럼 수정한다.

수정버튼을 누르면 이미지 번호, 현재 이미지, 변경 이미지가 출력된다.

하지만 이미지 변경은 되지 않는다.


<div class="modal-body">
  이미지 번호 : <input type="text" name="imageno" id="modal_image_no" readonly /><br />
  현재 이미지 : <img src="" style="width:100px;height:100px" id="modal_image_src" /><br />
  <input type="hidden" name="ino" value="${ino}" />
  변경 이미지 : <input type="file" name="file" id="modal_image_file" /><br />
</div>

<div class="modal-footer">
  <input type="submit" class="btn btn-primary" value="이미지변경" />

item_image_jsp를 이렇게 변경하면

파일을 선택하고 이미지변경을 누르면

imageupdate.do로 넘어가게 된다.


@WebServlet(urlPatterns = {"/item/imageupdate.do"})
@MultipartConfig()
public class ItemImageUpdateController extends HttpServlet {
	private static final long serialVersionUID = 1L;

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		Long ino = Long.parseLong( request.getParameter("ino") ); // 물품 번호
		Long imageNo = Long.parseLong( request.getParameter("imageno") ); // 이미지 번호
		Part file = request.getPart("file"); // 첨부한 파일
		
		if(file.getSize() > 0) { // 첨부가 되었다면 수정하기
			// mapper를 이용하여 수정
			ItemImage obj = new ItemImage();
			obj.setNo( imageNo );
			obj.setItemno( ino );
			obj.setFilename( file.getSubmittedFileName() );
			obj.setFiletype( file.getContentType() );
			obj.setFilesize( file.getSize() );
			obj.setFiledata( file.getInputStream().readAllBytes() );
			int ret = MybatisContext.getSqlSession().getMapper(ItemImageMapper.class).updateItemImageOne(obj);
		
			System.out.println(imageNo);
			System.out.println(ino);
			// 적절한 페이지로 이동
			if( ret == 1 ) { // 변경 완료
				request.setAttribute("message", "변경 완료");
				request.setAttribute("url", "imagewrite.do?ino="+ino);
				request.getRequestDispatcher("/WEB-INF/alert.jsp").forward(request, response);
			}
			else {// 변경 완료 안됨
				request.setAttribute("message", "변경 실패");
				request.setAttribute("url", "imagewrite.do?ino="+ino);
				request.getRequestDispatcher("/WEB-INF/alert.jsp").forward(request, response);
			}
		}
		else { // 변경사항 없습니다.
			request.setAttribute("message", "변경 사항 없음");
			request.setAttribute("url", "imagewrite.do?ino="+ino);
			request.getRequestDispatcher("/WEB-INF/alert.jsp").forward(request, response);
		}
	}	
}

ItemImageUpdateController.java를 생성하고

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>    
<!DOCTYPE html>
<html>
<head>
	<script>
		alert('${message}'); // 알림을 표시
		window.location.href='${url}'; // 주소창을 바꾸고 enter키
	</script>
</head>
</html>

message와 url을 연결할 alert.jsp를 생성한다.

이제 실험해보자.

화난 페페를 넣고 이미지 변경을 눌러보면

변경이 완료되었다.

파일을 선택하지 않고 변경을 누르면

변경 사항이 없다고 뜬다.


회원가입

고객 회원가입

회원가입 창

@WebServlet(urlPatterns = {"/customer/join.do"})
public class CustomerJoinController extends HttpServlet {
	private static final long serialVersionUID = 1L;

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.getRequestDispatcher("/WEB-INF/customer/customer_join.jsp").forward(request, response);
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
	}
}

CustomerJoinController를 생성하고

<head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>고객용 회원가입</title>
    <link rel="stylesheet" href="${pageContext.request.contextPath}/resources/css/bootstrap.min.css" />
</head>

<body>
	<div class="container">
        <div style="width:600px; margin:0 auto; padding: 50px; border:1px solid #efefef;">
        	<h3>회원가입</h3>
            <div class="row">
                <div class="col-sm">
	                <div class="form-floating mb-2">
	                    <input type="text" id="id" class="form-control" />
	                    <label for="id" class="form-label">아이디</label>
	                </div>
	                <div class="form-floating mb-2">
	                    <input type="password" id="pw" class="form-control" />
	                    <label for="pw" class="form-label">암호</label>
	                </div>
	                <div class="form-floating mb-2">
	                    <input type="password" id="pw1" class="form-control" />
	                    <label for="pw1" class="form-label">암호 확인</label>
	                </div>
	                <div class="form-floating mb-2">
	                    <input type="text" id="name" class="form-control" />
	                    <label for="name" class="form-label">이름</label>
	                </div>
	                <div class="form-floating mb-2">
	                    <input type="number" id="age" class="form-control" />
	                    <label for="age" class="form-label">나이</label>
	                </div>
	                <div>
                    	<input type="submit" value="회원가입" class="btn btn-primary" />
                    </div>
                </div>
            </div>
		</div>            
	</div>
	
	<script>
	
	</script>
</body>

customer_join.jsp를 생성하면

고객용 회원가입창이 생성된다.

아이디 중복확인

// 아이디 중복확인
@Select({
	" SELECT COUNT(*) cnt FROM member m WHERE ID=#{id} "
})
public int selectMemberIDCheck(@Param("id") String id);

Mapper를 생성한다.

// 127.0.0.1:8080/web03/api/member/idcheck.json?id=중복확인 아이디
@WebServlet(urlPatterns = {"/api/member/idcheck.json"})
public class RestMemberIDCheckController extends HttpServlet {
	private static final long serialVersionUID = 1L;
	private Gson gson = new Gson(); // 라이브러리를 이용한 객체 생성
    
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// 전달받는 문자로 된 페이지 정보
		String id = request.getParameter("id");
		
		// 아이디 전달 => 존재하면 1 없으면 0 반환
		int ret = MybatisContext.getSqlSession().getMapper(MemberMapper.class).selectMemberIDCheck(id);
		
		
		response.setContentType("application/json");
		Map<String, Object> map = new HashMap<>();
		map.put("ret", ret);
		String jsonString = gson.toJson(map);

		PrintWriter out = response.getWriter();
		out.print(jsonString);
		out.flush();
	}
}

RestMemberIDCheckController.java를 생성한다.


postman에서 확인해보자.

존재하는 아이디면 1이 나오고

존재하지 않는 아이디면 0이 나온다.

이제 추가해보자.

<div class="form-floating mb-2">
    <input type="text" id="id" class="form-control" onkeyup="ajaxIDCheck(this)"/>
    <label for="id"id="lbl_check" class="form-label">아이디</label>
</div>

...

<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/1.3.5/axios.min.js"></script>
<script>
async function ajaxIDCheck(e){
		console.log(e.value);
		if(e.value.length>0){
			// rest api 호출
			const url = '${pageContext.request.contextPath}/api/member/idcheck.json?id=' + e.value;
			const headers={"Content-Type":"application/json"};
			const {data} = await axios.get(url, {headers});
			// 결과값 받기
			console.log(data);
			if(data.ret === 1){
				// 사용불가
				document.getElementById("lbl_check").innerText = '사용불가';
			}
			else if(data.ret === 0){
				// 사용가능
				document.getElementById("lbl_check").innerText = '사용가능';
			}
		}
		else{
			document.getElementById("lbl_check").innerText = '아이디';
		}
}
</script>

customer_join.jsp의 아이디 창에 id, onkeyup을 추가하고 script, function을 작성한다

  • onkeyup : 키보드를 뗐을 때.

아이디창에 입력해보자.

asdf를 순서대로 입력하였더니 a, as, asd, asdf 키보드를 뗄 때마다 콘솔에 출력이 되는 모습을 볼 수 있다.

아이디가 중복되지 않으니 사용가능 글자가 적혀있다.

이미 존재하는 아이디인 1을 입력하자 사용불가로 변하게 된다.

0개의 댓글