@WebServlet(urlPatterns = {"/item/write.do"})
public class ItemWriteController extends HttpServlet {
private static final long serialVersionUID = 1L;
public ItemWriteController() {
super();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.getRequestDispatcher("/WEB-INF/item_write.jsp").forward(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
}
ItemWriteController.java를 생성하고
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta http-equiv='X-UA-Compatible' content='IE=edge' />
<meta name='viewport' content='width=device-width, initial-scale=1' />
<title>물품등록</title>
<link rel="stylesheet" href="${pageContext.request.contextPath}/resources/css/bootstrap.min.css" />
<!-- Include stylesheet -->
<link href="https://cdn.quilljs.com/1.3.6/quill.snow.css" rel="stylesheet">
</head>
<body>
<div class="container">
<div style="width:1500px; margin:0 auto; padding: 50px; border:1px solid #efefef;">
<h3>물품등록</h3>
<hr />
<!-- <form action="${pageContext.request.contextPath}/item/write.do" method="post"> -->
<form id="form" action="write.do" method="post">
<div class="row">
<div class="col-sm">
<div class="form-floating mb-2">
<input type="text" name="name" id="title" class="form-control" autofocus required />
<label for="title" class="form-label">물품명</label>
</div>
<div style="margin-bottom:5px;">
<!-- Create the editor container -->
<div id="editor" style="height:300px;">
<p>물품설명</p>
</div>
</div>
<textarea id="content" name="content" style="display:block"></textarea>
<div class="form-floating mb-2">
<input type="text" name="price" id="price" class="form-control" required />
<label for="price" class="form-label">가격</label>
</div>
<div class="form-floating mb-2">
<input type="text" name="quantity" id="quantity" class="form-control" required />
<label for="quantity" class="form-label">수량</label>
</div>
<div>
<input type="submit" value="등록" class="btn btn-primary" onclick="insertItem()"/>
</div>
</div>
</div>
</form>
</div>
</div>
<!-- Include the Quill library -->
<script src="https://cdn.quilljs.com/1.3.6/quill.js"></script>
<!-- Initialize Quill editor -->
<script>
const toolbarOptions = [
['bold', 'italic', 'underline', 'strike'], // toggled buttons
['blockquote', 'code-block'],
[{ 'header': 1 }, { 'header': 2 }], // custom button values
[{ 'list': 'ordered'}, { 'list': 'bullet' }],
[{ 'script': 'sub'}, { 'script': 'super' }], // superscript/subscript
[{ 'indent': '-1'}, { 'indent': '+1' }], // outdent/indent
[{ 'direction': 'rtl' }], // text direction
[{ 'size': ['small', false, 'large', 'huge'] }], // custom dropdown
[{ 'header': [1, 2, 3, 4, 5, 6, false] }],
[{ 'color': [] }, { 'background': [] }], // dropdown with defaults from theme
[{ 'font': [] }],
[{ 'align': [] }],
['clean'] // remove formatting button
];
// 위쪽에 있는 태그 중에서 id가 editor인 것을 찾아서 toolbar는 toolbarOptions의 값으로 대체하고 테마를 snow로 해서 변경
const quill = new Quill('#editor', {
modules: {
toolbar: toolbarOptions
},
theme: 'snow'
});
function insertItem(){
// 물품명 유효성 검사
const name = document.getElementById("name");
if(name.value.length <= 0) {
alert('물품명을 입력하세요.');
name.focus();
return false;
}
// 가격 유효성 검사
const price = document.getElementById("price");
if(name.value.length <= 0) {
alert('가격을 입력하세요.');
name.focus();
return false;
}
// 수량 유효성 검사
const quantity = document.getElementById("quantity");
if(name.value.length <= 0) {
alert('수량을 입력하세요.');
name.focus();
return false;
}
// div 태그의 내용을 textarea로 복사
const divContent = quill.root.innerHTML;
document.getElementById("content").value = divContent;
// form 태그 전송
document.getElementById("form").submit();
}
</script>
</body>
</html>
item_write.jsp를 생성한다.
코드에 작성한 것처럼 유효성 검사 또한 포함하였다.
물품명, 가격, 수량 순으로 입력되지 않은 칸이 있으면 알림창이 뜬다.
@Insert({
" INSERT INTO item (name, content, price, quantity) ",
" VALUES(#{obj.name}, #{obj.content}, #{obj.price}, #{obj.quantity}) "
})
public int insertItemOne(@Param("obj") Item obj);
Mapper를 생성하고
@WebServlet(urlPatterns = {"/item/write.do"})
public class ItemWriteController extends HttpServlet {
private static final long serialVersionUID = 1L;
public ItemWriteController() {
super();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.getRequestDispatcher("/WEB-INF/item_write.jsp").forward(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Item item = new Item();
item.setName(request.getParameter("name"));
item.setContent(request.getParameter("content"));
item.setPrice(Long.parseLong(request.getParameter("price")));
item.setQuantity(Long.parseLong(request.getParameter("quantity")));
System.out.println(item.toString()); // 전달받은 값 확인용
//mapper를 통해 데이터 추가
int ret = MybatisContext.getSqlSession().getMapper(ItemMapper.class).insertItemOne(item);
if( ret == 1 ) {
// 절대 경로를 이용한 페이지 이동
response.sendRedirect(request.getContextPath() +"/item" + "/select.do");
}
else {
// 상대 경로를 이용한 페이지 이동
response.sendRedirect("write.do");
}
}
}
itemWriteController.java에 추가한다.
위처럼 입력하고 등록을 눌러보면
select.do를 아직 생성하지 않았으니 404에러가 뜨고
콘솔에는 등록한 값이 나온다.
하지만 유효성검사를 하기 때문에 굳이 하지 않아도 된다.
이제 select.do를 생성하여 404에러를 없애보자.
// #{ } => 값을 표현할때
// ${ } => 컬럼명, 테이블명 등.
@Select({
" SELECT i.* FROM item i WHERE ${column} LIKE '%' || #{text} || '%' ORDER BY no DESC "
})
public List<Item> selectItemList(@Param("column") String column,
@Param("text")String text);
@Insert({
" INSERT INTO item(name, content, price, quantity) ",
" VALUES(#{obj.name}, #{obj.content}, #{obj.price}, #{obj.quantity}) "
})
public int insertItemOne(@Param("obj")Item obj);
지난번에 만든 Mapper를 가져와 생성하고
@WebServlet(urlPatterns = {"/item/select.do"})
public class ItemSelectController extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
List<Item> list = MyBatisContext.getSqlSession()
.getMapper(ItemMapper.class).selectItemList("name", "");
request.setAttribute("list", list);
request.getRequestDispatcher("/WEB-INF/item_select.jsp").forward(request, response);
}
}
BoardSelectCOntroller.java를 토대로 ItemSelectController.java를 생성한다.
<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">
<a href="write.do" class="btn btn-primary">물품등록</a>
<div style="width:500px; margin-top:10px;">
<form class="row g-2">
<div class="col-auto">
<input type="text" name="text" class="form-control" placeholder="검색어" style="width:300px;"/>
</div>
<div class="col-auto">
<input type="submit" class="btn btn-primary" value="검색" />
</div>
</form>
</div>
<table class="table table-sm table-hover">
<thead>
<tr>
<th scope="col">번호</th>
<th scope="col">물품명</th>
<th scope="col">가격</th>
<th scope="col">수량</th>
<th scope="col">날짜</th>
</tr>
</thead>
<tbody>
<c:forEach var="obj" items="${list}">
<tr>
<td scope="row">${obj.no}</td>
<td>${obj.name}</td>
<td>${obj.price}</td>
<td>${obj.quantity}</td>
<td>${obj.regdate}</td>
</tr>
</c:forEach>
</tbody>
</table>
</div>
<script src="${pageContext.request.contextPath}/resources/js/jquery-3.6.4.min.js"></script>
<script src="${pageContext.request.contextPath}/resources/js/jquery.twbsPagination.min.js"></script>
<script>
</script>
</body>
item_select.jsp또한 board_select.jsp를 복사하고 수정하여 생성한다.
이렇게 작성했던 item들의 목록들이 나온다면 성공.
<thead>
<tr>
<th scope="col">번호</th>
<th scope="col">물품명</th>
<th scope="col">가격</th>
<th scope="col">수량</th>
<th scope="col">날짜</th>
<th scope="col">이미지</th>
</tr>
</thead>
<tbody>
<c:forEach var="obj" items="${list}">
<tr>
<td scope="row">${obj.no}</td>
<td>${obj.name}</td>
<td>${obj.price}</td>
<td>${obj.quantity}</td>
<td>${obj.regdate}</td>
<td><a href="imagewrite.do?ino=${obj.no}" button class="btn btn-primary">이미지 등록</button></td>
</tr>
</c:forEach>
</tbody>
item_select.jsp를 위처럼 수정해준다.
이렇게 이미지 등록 버튼이 생성된다.
@WebServlet(urlPatterns = {"/item/imagewrite.do"})
public class ItemImageWriteController extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String ino = request.getParameter("ino");
request.setAttribute("ino", ino);
request.getRequestDispatcher("/WEB-INF/item_image_write.jsp").forward(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
}
ItemImageWriteController.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 lang="ko">
<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:800px; margin:0 auto; padding: 50px; border:1px solid #efefef;">
<h3>물품이미지등록</h3>
<hr />
<form id="form" action="${pageContext.request.contextPath}/item/imagewrite.do" method="post">
<div class="row">
<div class="col-sm">
<div class="form-floating mb-2">
<input type="text" name="ino" id="ino"
style="background-color:#efefef;"
value="${ino}" class="form-control" readonly />
<label for="ino" class="form-label">물품번호</label>
</div>
<div class="form-floating mb-2">
<img src="" style="width:100px;height:100px">
<input type="file" name="file" id="file" class="form-control" />
</div>
<div>
<input type="button" value="등록" class="btn btn-primary"
onclick="insertImageItem()"/>
<a href="select.do" class="btn btn-success">목록으로</a>
</div>
</div>
</div>
</form>
</div>
</div>
<script>
function insertImageItem() {
}
</script>
</body>
</html>
item_image_write.jsp를 생성한다.
이미지 등록 버튼을 누르면
물품 번호가 나오며 이미지를 등록하는 창으로 이동하게 된다.
파일 선택을 누르면 이렇게 사진을 선택할 수 있는 창이 나오게 된다.
또한 목록으로 버튼을 누르면 다시 목록으로 가게 된다.
<div class="form-floating mb-2">
<img src="${pageContext.request.contextPath}/resources/images/default.png"
id="img" style="width:100px;height:100px">
<input type="file" name="file" id="file" class="form-control" onchange="imageChange(this)"/>
</div>
...
<script>
function imageChange(e){
const img = document.getElementById("img");
console.log(e.files);
if(e.files.length > 0){ // 첨부
// 파일을 첨부하면 크롬에서 blob:http://1.237....
img.src = URL.createObjectURL( e.files[0] ); // 가상의 url정보를 생성해서 추함.
}
else { // 취소
img.src = "${pageContext.request.contextPath}/resources/images/default.png";
}
}
function insertImageItem() {
}
</script>
item_image_write.jsp를 위처럼 수정, 추가해준다.
파일을 선택하면 해당하는 이미지가 보인다.
<div class="form-floating mb-2">
<img src="${pageContext.request.contextPath}/resources/images/default.png"
id="img" style="width:100px;height:100px; cursor:pointer;"
onclick="clickImage()">
<input type="file" name="file" id="file" class="form-control"
style="display:none"
onchange="imageChange(this)" />
</div>
...
<script>
function clickImage () {
document.getElementById("file").click();
}
item_image_write.jsp를 위처럼 수정, 추가한다.
파일추가 버튼이 사라졌다. 사진 파일을 누르면
이렇게 사진을 추가할 수 있다.
사진을 추가한 모습.
사진을 누르고 확인이 아닌 취소 버튼을 눌렀을 때의 모습.
@Insert({
" INSERT INTO itemimage(filename, filesize, filetype, filedata, itemno) ",
" VALUES(#{obj.filename}, #{obj.filesize}, #{obj.filetype}, #{obj.filedata}, #{obj.itemno}) "
})
public int insertItemImageOne(@Param("obj") ItemImage obj);
mapper를 추가하고
@WebServlet(urlPatterns = {"/item/imagewrite.do"})
@MultipartConfig()
public class ItemImageWriteController extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String ino = request.getParameter("ino");
request.setAttribute("ino", ino);
request.getRequestDispatcher("/WEB-INF/item_image_write.jsp").forward(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Long ino = Long.parseLong( request.getParameter("ino"));
Part file = request.getPart("file");
ItemImage obj = new ItemImage();
obj.setItemno(ino);
obj.setFilename(file.getSubmittedFileName());
obj.setFilesize(file.getSize());
obj.setFiletype(file.getContentType());
obj.setFiledata(file.getInputStream().readAllBytes());
System.out.println(obj);
// mapper로 추가 후
int ret = MybatisContext.getSqlSession().getMapper(ItemImageMapper.class).insertItemImageOne(obj);
if( ret == 1 ) {
// 절대 경로를 이용한 페이지 이동
response.sendRedirect(request.getContextPath() +"/item" + "/imagewrite.do?ino="+ino);
}
else {
// 상대 경로를 이용한 페이지 이동
response.sendRedirect("imagewrite.do");
}
}
}
ItemImageWriteController.java를 수정한다.
<body>
<div class="container">
<div style="width:800px; margin:0 auto; padding: 50px; border:1px solid #efefef;">
<h3>물품 이미지 등록</h3>
<hr />
<form id="form" action="${pageContext.request.contextPath}/item/imagewrite.do" method="post"
enctype="multipart/form-data">
...
function insertImageItem() {
// 유효성 검사한 후
const file = document.getElementById("file");
if (file.value.length <= 0) {
alert('파일첨부');
}
// form 태그 전송
document.getElementById("form").submit();
}
</script>
</body>
item_image_write.jsp를 위처럼 수정, 추가한다.
페페사진을 등록해보자.
등록을 누르니 페페 사진이 사라졌다. 제대로 등록이 되었는지 H2에서 확인해보자.
REGDATE를 보면 현재 날짜와 시간인 2023-04-10 14:08 을 볼 수 있다.
제대로 등록이 되었다는 뜻!
...
<form id="form1" action="imagewritebatch.do?ino=${ino}" method="post"
enctype="multipart/form-data">
<c:forEach var="idx" begin="1" end="3" step="1">
<img src="${pageContext.request.contextPath}/resources/images/default.png"
class="imgs"
style="width:50px;height:50px; cursor:pointer;"/>
<input type="file" name="file[]" onchange="imageChangeBatch(this, '${idx-1}')"/>
<br />
</c:forEach>
<input type="button" value="일괄등록" onclick="insertIamgeBatch()" class="btn btn-primary" />
<a href="select.do" class="btn btn-success">목록으로</a>
</form>
</div>
</div>
<script>
// document.getElementById("아이디"); id가 일치하는 1개 찾기
// document.getElementsByName("name값"); name값이 일치하는 n개 찾기
// document.getElementsByClassName("class값"); class값이 일치하는 n개 찾기
// document.getElementsByTagName("img"); 태그가 img인 n개 찾기
const imgs = document.getElementsByClassName("imgs"); //<img src class="imgs" />
const files = document.getElementsByName("file[]"); //<input type="file" name="file[]" />
function imageChangeBatch(e, idx){ //첨부한파일정보, type=file의 위치(0부터)
if(e.files.length > 0) {
imgs[ Number(idx) ].src=URL.createObjectURL( e.files[0] );// 가상의 url정보를 생성해서 추가함.
}
else{
imgs[ Number(idx) ].src="${pageContext.request.contextPath}/resources/images/default.png";
}
}
function insertIamgeBatch() {
var chk = 0;
for(let i=0; i<files.length; i++) { //files전체 반복
if(files[i].value.length <= 0){ // 첨부하지 않은 것을 발견하면
alert('이미지 첨부하세요.'); // 알림창 표시
chk = 1;
break; //반복문 종료
}
}
if(chk === 0){ // if문을 한번도 수행하지 않았다면 form 전송
document.getElementById("form1").submit();
}
}
function insertImageItem() {
// 유효성 검사 한 후
const file = document.getElementById("file");
if(file.value.length <= 0){
alert('파일첨부 하세요');
}
// form태그 전송
document.getElementById("form").submit();
}
</script>
</body>
</html>
item_image_write.jsp를 위처럼 추가한다.
3개를 한 번에 등록할 수 있게 되었다.
이미지를 선택하지 않고 일괄등록을 누르면 이미지를 첨부하라는 알림이 뜬다.
이렇게 3개를 한 번에 추가할 수 있다.
일괄등록을 누른 모습이다.
imagewritebatch.do를 생성하지 않았으니 404 오류가 나온다.
@WebServlet(urlPatterns = {"/item/imagewritebatch.do"})
@MultipartConfig()
public class ItemImageWriteBatchController extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String ino = request.getParameter("ino");
request.setAttribute("ino", ino);
request.getRequestDispatcher("/WEB-INF/item_image_write.jsp").forward(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Long ino = Long.parseLong( request.getParameter("ino"));
Collection<Part> file = request.getParts();
for(Part filePart : file) {
// name값이 files인것만 필터
if(filePart.getName().equals("file[]")) {
ItemImage obj = new ItemImage();
obj.setItemno(ino);
obj.setFilename(filePart.getSubmittedFileName());
obj.setFiletype(filePart.getContentType());
obj.setFilesize(filePart.getSize());
obj.setFiledata(filePart.getInputStream().readAllBytes());
// 여기서 mapper로 insest수행
// insert all 한 번에 추가하기
MybatisContext.getSqlSession().getMapper(ItemImageMapper.class)
.insertItemImageOne(obj);
}
}
response.sendRedirect(request.getContextPath() +"/item" + "/imagewrite.do?ino="+ino);
}
}
예전에 만든 BoardImageInsertBatchServlet을 참조하여 ItemImageWriteBatchController.java를 만들었다.
jsp에서 파일명을 files[]로 했기 때문에 if(filePart.getName().equals("file[]"))로 받아야 한다.
이렇게 우는 페페를 등록하면
사진 3개가 동시에 들어간 것을 확인할 수 있다.