본문 바로가기
ICIA 수업일지

2021.08.23 수업일지(Servlet, Spring, Mysql)

by 주성씨 2021. 8. 23.

- 새로운 프로젝트를 만들어보자.

1. 이전에 사용했던 vo, database를 model 복사

2. model, controller src에 만듦

3. 라이브러리 복사

 

- 메인페이지가될 .jsp파일을 main이름으로 생성

- [new] main.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<script src="http://code.jquery.com/jquery-3.1.1.min.js"></script>
<script
	src="https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/3.0.1/handlebars.js"></script>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>이주성의 도서관리 시스템</title>
<style>
@font-face {
	font-family: '국립박물관문화재단클래식B';
	src:
		url('https://cdn.jsdelivr.net/gh/projectnoonnu/noonfonts_twelve@1.0/국립박물관문화재단클래식B.woff')
		format('woff');
	font-weight: normal;
	font-style: normal;
}

body {
	font-family: '국립박물관문화재단클래식B';
}

#container {
	width: 960px;
	border: 1px solid black;
	margin: 0 auto;
	padding: 20px;
}

#header {
	padding: 20px;
	border: 1px solid black;
}

#center {
	padding: 20px;
	border: 1px solid black;
	margin-top: 10px;
	margin-bottom: 10px;
}

#footer {
	padding: 20px;
	border: 1px solid black;
}

#menu {
	overflow: hidden;
	border-bottom: 1px dotted black;
}

#menu h4 {
	float: left;
	width: 100px;
	margin-left: 20px;
	margin-right: 20px;
}

h1, h3 {
	text-align: center;
}

#content {
	border: 1px solid black;
	padding: 10px;
	margin-top: 10px;
}

a {
	text-decoration: none;
	color: black;
	padding: 10px;
}

a:hover {
	cursor: pointer;
	text-decoration: none;
	background: gray;
	text-color: white;
	padding: 10px;
	border-radius: 10px;
}

a:VISITED {
	color: black;
}
</style>
</head>
<body>
	<div id="container">
		<div id="header">
			<h1>도서관리 시스템</h1>
		</div>
		<div id="center">
			<div id="menu">
				<h4>
					<a href="/book/list">도서관리</a>
				</h4>
				<h4>
					<a href="/book/search">도서검색</a>
				</h4>
			</div>
			<div id="content">내용 들어갈곳.</div>
		</div>
		<div id="footer">
			<h3>Copyright. 2021 이주성 도서관리 시스템. All right reserved.</h3>
		</div>
	</div>
</body>
</html>

 

출력물

 

- 메인 서블릿을 만들어보자.

- MVC에서 controller의 역할을 하는 서블릿을 만들어보자. src\controller\에 만든다. 서블릿은 클라이언트의 요청을 처리하고, 그 결화를 반환하는 Servlet 클래스의 구현 규칙을 지킨 자바 웹 프로그래밍 기술을 의미한다.

- [new] mainservlet.java

package controller;

import java.io.IOException;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


@WebServlet("/")
public class MainServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.setAttribute("pageName", "/about.jsp"); // new
		RequestDispatcher dis = request.getRequestDispatcher("/main.jsp"); // new
		dis.forward(request, response); // new
	}


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

	}

}

ㄴ /를 통해서 메인페이지에 진입할 수 있게 하였고, 소개란을 about.jsp로 따로 두어 pageName으로 출력할 수 있게 하였다.

 

- [new] about.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<h1>[시스템 소개]</h1>

 

- main.jsp

- jsp:include를 통해서 pageName을 출력해주도록 하겠다.

<body>
	<div id="container">
		<div id="header">
			<h1><a href="/">도서관리 시스템</a></h1>
		</div>
		<div id="center">
			<div id="menu">
				<h4>
					<a href="/book/list">도서관리</a>
				</h4>
				<h4>
					<a href="/book/search">도서검색</a>
				</h4>
			</div>
			<div id="content">
			<jsp:include page="${pageName}"></jsp:include>
			</div>
		</div>
		<div id="footer">
			<h3>Copyright. 2021 이주성 도서관리 시스템. All right reserved.</h3>
		</div>
	</div>
</body>

 

출력물

 

- 도서검색 API를 이용하기위해서 jquery, handlebar를 main에 추가하도록 하자.

- main.jsp

<script src="http://code.jquery.com/jquery-3.1.1.min.js"></script>
<script
	src="https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/3.0.1/handlebars.js"></script>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>이주성의 도서관리 시스템</title>

 

- 도서검색을 위한 servlet을 만들어보도록 하자.

- [new] bookservlet.java

package controller;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


@WebServlet(value={"/book/list","/book/search","/book/insert","/book/update","/book/delete","/book/read"})
public class BookServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
	}


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

	}

}

ㄴ value 값으로 앞으로 사용할 path들을 미리 기입해놓겠다.

 

- switch case 문으로 search, list 페이지를 메인을 통해서 진입할 수 있도록 하겠다.

	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		switch (request.getServletPath()) {
		case "/book/search":
			request.setAttribute("pageName", "/book/search.jsp");
			RequestDispatcher dis = request.getRequestDispatcher("/main.jsp");
			dis.forward(request, response);
			break;
		case "/book/list":
			request.setAttribute("pageName", "/book/list.jsp");
			dis = request.getRequestDispatcher("/main.jsp");
			dis.forward(request, response);
			break;
		}
	}

ㄴ RequestDispatcher이란 클래스는 현재 request에 담긴 정보를 저장하고 있다가 다음 페이지에서도 해당 정보를 볼 수 있게 계속 저장하는 기능이다.  forward 방식을 통해 request에 "pageName"라는 이름의 Attribute(ex. /book/search.jsp)를 저장 한 후 forward 시킨다다고 이해하면 편하다.

 

- list.jsp, search.jsp 를 만들어보자.

- [new] list.jsp 

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<h1>[도서 목록]</h1>

 

- [new] search.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<h1>[도서 검색]</h1>

 

출력물

 

- 카카오 api를 이용한 도서검색 란을 만들어보자.

- ajax을 이용해 카카오 db의 data를 불러오도록 하자.

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<h1>[도서 검색]</h1>

<div id="books"></div>

<script>
	getList();
	function getList() {
		$.ajax({
			type : 'get',
			url : 'https://dapi.kakao.com/v3/search/book?target=title',
			dataType : 'json',
			data : {
				"query" : "자바",
				"size" : 5
			},
			headers:{"Authorization":"KakaoAK 31347cda85f0d6ed06e3025a531f2aca"},
			success : function(data) {
				alert("....")
			}
		});
	}
</script>

ㄴ ajax를 통해서 데이터를 가지고 오는거니깐 get, get할 url은 위와 같이 카카오 DB에서 가지고 온다. 가지고 올때의 데이터 타입은 json이다. headers는 데이터를 가지고 오는 유저의 uid 정도라고 생각하면 되겠다. 

 

 

출력물

 

- 핸들바를 사용해서 내용을 깔끔하게 출력해보자.

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<h1>[도서 검색]</h1>

<div id="books"></div>
<script id="temp" type="text/x-handlebars-template">
	{{#each documents}}
		<div class="item">
			<div class="title">{{title}}</div>
		</div>
	{{/each}}
</script>
<script>
	getList();
	function getList() {
		$.ajax({
			type : 'get',
			url : 'https://dapi.kakao.com/v3/search/book?target=title',
			dataType : 'json',
			data : {
				"query" : "자바",
				"size" : 5
			},
			headers : {
				"Authorization" : "KakaoAK 31347cda85f0d6ed06e3025a531f2aca"
			},
			success : function(data) {
				var temp = Handlebars.compile($('#temp').html());
				$('#books').html(temp(data));
			}
		});
	};
</script>

 

 

출력물

 

- 스타일을 조정해보자.

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<style>
#books .item{
	padding: 20px;
	border: 1px solid black;
	margin-bottom: 10px;
}
.item{
	overflow: hidden;
}
div .info{
	margin-left: 20px;
	width: 650px;
}
img, div .info{
	float: left;
}
</style>
<h1>[도서 검색]</h1>
<div id="books"></div>
<script id="temp" type="text/x-handlebars-template">
	{{#each documents}}
		<div class="item">
			<img src="{{thumbnail}}"/>
			<div class="info">
				<div class="title">{{title}}</div>
				<div class="price">{{price}}</div>
				<div class="authors">{{authors}}</div>
				<hr/>
				<div class="contents">{{contents}}</div>
			</div>
		</div>
	{{/each}}
</script>

 

출력물

 

- 검색 조건을 만들어보자.

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<style>
#books .item {
	padding: 20px;
	border: 1px solid black;
	margin-bottom: 10px;
}

.item {
	overflow: hidden;
}

div .info {
	margin-left: 20px;
	width: 650px;
}

img, div .info {
	float: left;
}

img {
	box-shadow: 5px 5px 5px gray;
	border: 0.5px solid;
}
div #condition{
	margin-bottom: 10px;
}
select{
	height: 25px;
}
#query{
	height: 20px;
}
</style>
<h1>[도서 검색]</h1>
<div id="condition">
	<select id="target">
		<option value="title">제목</option>
		<option value="authors">저자</option>
		<option value="publisher">출판사</option>
	</select> <input id="query" value="자바" />
</div>
<div id="books"></div>
<script id="temp" type="text/x-handlebars-template">
	{{#each documents}}
		<div class="item">
			<img src="{{thumbnail}}"/>
			<div class="info">
				<div class="title">{{title}}</div>
				<div class="price">{{price}}</div>
				<div class="authors">{{authors}}</div>
				<div class="publisher">{{publisher}}</div>
				<hr/>
				<div class="contents">{{contents}}</div>
			</div>
		</div>
	{{/each}}
</script>
<script>
	var page = 1;
	getList();
	
	// 검색란에서 enter를 눌렀을때
	$('#query').on('keypress',function(e){
		if(e.keyCode==13){
			page=1;
			getList();
		};
	});
	
	function getList() {
		var query = $('#query').val();
		var target = $('#target').val();
		$.ajax({
			type : 'get',
			url : 'https://dapi.kakao.com/v3/search/book?target='+target,
			dataType : 'json',
			data : {
				"query" : query,
				"size" : 5,
				"page" : page
			},
			headers : {
				"Authorization" : "KakaoAK 31347cda85f0d6ed06e3025a531f2aca"
			},
			success : function(data) {
				var temp = Handlebars.compile($('#temp').html());
				$('#books').html(temp(data));
			}
		});
	};
</script>

 

출력물

 

- 더보기 버튼으로 목록을 더 출력해보자.

</script>
<hr />
<button id="more">더보기</button>
<script>
	var page = 1;
	getList();

	// 더보기 버튼을 눌렀을때
	$('#more').on('click',function(){
		page++;
		getList();
	});
	
	// 검색란에서 enter를 눌렀을때
	$('#query').on('keypress', function(e) {
		if (e.keyCode == 13) {
			$('#books').html("");
			page = 1;
			getList();
		};
	});

 

출력물

 

- 검색한 도서를 내 DB 테이블에 저장해보도록 하자.

- 도서목록을 출력해주는 메서드를 만들어주자.

- [new] bookdao.java

package model;

import java.util.*;
import java.sql.*;

public class BookDAO {
	// 1. 도서목록 출력 메서드
	public ArrayList<BookVO> list(){
		ArrayList<BookVO> array = new ArrayList<BookVO>();
		try {
			String sql = "select * from books order by code desc";
			PreparedStatement ps = Database.CON.prepareStatement(sql);
			ResultSet rs = ps.executeQuery();
			while(rs.next()){
				BookVO vo = new BookVO();
				vo.setCode(rs.getString("code"));
				vo.setTitle(rs.getString("title"));
				vo.setWriter(rs.getString("writer"));
				vo.setPrice(rs.getInt("price"));
				vo.setImage(rs.getString("image"));
				array.add(vo);
			}
		} catch (Exception e) {
			System.out.println("list : "+e.toString());
		}
		return array;
	}
}

ㄴ 도서 목록은 여러개를 가지고 와야 하니 배열에 담아서 데이터를 가지고 오도록 하겠다.

 

- 어레이리스트를 제이손으로 만들어 에이작으로 출력하도록 하자.

- bookservlet.java - 어레이리스트를 제이손으로 만들었다.

package controller;

import java.io.IOException;
import java.io.PrintWriter;
import java.text.DecimalFormat;
import java.util.ArrayList;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.json.simple.JSONArray;
import org.json.simple.JSONObject;

import model.*;

@WebServlet(value = { "/book/list", "/book/list.json", "/book/search", "/book/insert", "/book/update", "/book/delete",
		"/book/read" })
public class BookServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		response.setContentType("text/html; charset=UTF-8");
		switch (request.getServletPath()) {
		case "/book/list.json":
			BookDAO dao = new BookDAO();
			ArrayList<BookVO> array = dao.list();
			// json 변환을 위한 라이브러리가 있는지 확인하자.
			JSONArray jArray = new JSONArray();
			for (BookVO vo : array) { // array를 꺼내서 vo에 넣겠다.
				JSONObject obj = new JSONObject();
				obj.put("code", vo.getCode());
				obj.put("title", vo.getTitle());
				obj.put("writer", vo.getWriter());
				DecimalFormat df = new DecimalFormat("#,###원");
				String strPrice = df.format(vo.getPrice());
				obj.put("price", strPrice);
				obj.put("image", vo.getImage());
				jArray.add(obj);
			}
			JSONObject jObject = new JSONObject();
			jObject.put("array", jArray);
			jObject.put("total", 8);

			PrintWriter out = response.getWriter(); //
			out.print(jObject);
			break;

 

https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=hyuk9658&logNo=220636514728 

 

서블릿 개념 정리

서블릿은 Server + Applet의 합성어로 서버에서 실행되는 Applet이란 의미로 자바를 이용하여 웹에서 실...

blog.naver.com

 

출력물

 

- list.jsp - db에 있는 데이터를 불러오도록 하자.

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<style>
#books .item {
	padding: 20px;
	border: 1px solid rgb(233, 242, 251);
	background: rgb(233, 242, 251);
	margin-top: 15px;
}

.item {
	overflow: hidden;
}

div .info {
	margin-left: 20px;
	width: 650px;
}

img, div .info {
	float: left;
}

img {
	box-shadow: 5px 5px 5px gray;
	border: 0.5px solid;
}

div #condition {
	margin-bottom: 10px;
}

select {
	height: 25px;
}

#query {
	height: 20px;
}
</style>
<h1>[도서 목록]</h1>
<div id="books"></div>
<script id="temp" type="text/x-handlebars-template">
	{{#each array}}
		<div class="item">
			<img src="/image/book/{{image}}" width=150/>
			<div class="info">
				<div class="title">{{title}}</div>
				<div class="price">{{price}}</div>
				<div class="authors">{{writer}}</div>
				<div class="contents">{{contents}}</div>
			</div>
		</div>
	{{/each}}
</script>

 

출력물

 

- back to mysql

- 속성을 추가해보자.

alter table books add column contents nvarchar(1000);

 

- bookdao

- 도서등록 메서드를 만들자.

package model;

import java.util.*;
import java.sql.*;

public class BookDAO {
	// 2. 도서등록 메서드
	public void insert(BookVO vo) {
		try {
			String code = "";
			String sql = "select max(code) from books";
			PreparedStatement ps = Database.CON.prepareStatement(sql);
			ResultSet rs = ps.executeQuery();
			if (rs.next()) {
				code = rs.getString("code");
			}
			int intCode = Integer.parseInt(code) + 1;
			code = Integer.toString(intCode);

			sql = "insert into books(code, title, writer, price, image, contents) values(?,?,?,?,?,?);";
			ps = Database.CON.prepareStatement(sql);
			ps.setString(1, code);
			ps.setString(2, vo.getTitle());
			ps.setString(3, vo.getWriter());
			ps.setInt(4, vo.getPrice());
			ps.setString(5, vo.getImage());
			ps.setString(6, vo.getContents());
			ps.execute();
		} catch (Exception e) {
			System.out.println("insert : " + e.toString());
		}
	}

 

- contents 를 추가했으니 bookvo를 수정하자.

package model;

public class BookVO {
	// 1. 값을 변수로 지정하고 변수 속성은 꼭 확인하고 지정하자.
	private String code;
	private String title;
	private String writer;
	private int price;
	private String image;
	private String contents;

	// contents 추가
	public String getContents() {
		return contents;
	}

	public void setContents(String contents) {
		this.contents = contents;
	}
	// 3. 값이 잘 들어갔는지 확인하기 위해서 toString을 만들어보도록 하자.
	@Override
	public String toString() {
		return "BookVO [code=" + code + ", title=" + title + ", writer=" + writer + ", price=" + price + ", image="
				+ image + ", contents=" + contents + "]";
	}

}

 

- search.jsp

<script>
	var page = 1;
	getList();

	// 저장 버튼을 눌렀을떄 데이터를 가지고 오는지 확인하자.
	$('#books').on('click', '.item h5 a', function(e) {
		e.preventDefault();
		if (!confirm('해당 도서를 저장하시겠습니까?'))
			return;
		var item = $(this).parent().parent();
		var image = $("img").attr("src");
		var title = item.find(".title").html();
		var writer = item.find(".authors").html();
		var price = item.find(".price").html();
		var contents = item.find(".contents").html();
		$.ajax({
			type : 'post',
			url : '/book/insert',
			data : {
				"title" : title,
				"image" : image,
				"price" : price,
				"writer" : writer,
				"contents" : contents
			},
			success : function() {
				alert("상품등록 성공");
			}
		});
	});

 

콘솔에서 위와 같이 확인할 수 있다.

 

- 이제 이 데이터를 가지고 서블릿으로 간다.

- bookservlet

	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		request.setCharacterEncoding("UTF-8");
		BookVO vo = new BookVO();
		BookDAO dao = new BookDAO();
		vo.setTitle(request.getParameter("title"));
		vo.setPrice(Integer.parseInt(request.getParameter("price")));
		vo.setWriter(request.getParameter("writer"));
		vo.setContents(request.getParameter("contents"));
		switch (request.getServletPath()) {
		case "/book/insert":
			dao.insert(vo);
			break;
		}
	}

 

- bookdao에서 다음과 같이 contents 값을 array에 넣어주도록 하자.

	// 1. 도서목록 출력 메서드
	public ArrayList<BookVO> list() {
		ArrayList<BookVO> array = new ArrayList<BookVO>();
		try {
			String sql = "select * from books order by code desc limit 0 ,5;";
			PreparedStatement ps = Database.CON.prepareStatement(sql);
			ResultSet rs = ps.executeQuery();
			while (rs.next()) {
				BookVO vo = new BookVO();
				vo.setCode(rs.getString("code"));
				vo.setTitle(rs.getString("title"));
				vo.setWriter(rs.getString("writer"));
				vo.setPrice(rs.getInt("price"));
				vo.setImage(rs.getString("image"));
				vo.setContents(rs.getString("contents")); // new
				array.add(vo);
			}
		} catch (Exception e) {
			System.out.println("list : " + e.toString());
		}
		return array;
	}

 

출력물 gif

 

- 이제 이미지를 넣어보도록 하자.

- bookservlet

	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		request.setCharacterEncoding("UTF-8");
		BookVO vo = new BookVO();
		BookDAO dao = new BookDAO();
		vo.setTitle(request.getParameter("title"));
		vo.setPrice(Integer.parseInt(request.getParameter("price")));
		vo.setWriter(request.getParameter("writer"));
		vo.setContents(request.getParameter("contents"));
		switch (request.getServletPath()) {
		case "/book/insert":
			// 이미지 파일 다운로드
			String image = request.getParameter("image");
			// 현재시간 + .jpg
			String file = System.currentTimeMillis() + ".jpg";
			
			InputStream in = null;
			OutputStream out = null;

			try {
				URL url = new URL(image);
				in = url.openStream();
				out = new FileOutputStream("c:/image/book" + file);
				while (true) {
					int data = in.read();
					if (data == -1) {
						break;
					}
					out.write(data);
				}
				in.close();
				out.close();
			} catch (Exception e) {
				System.out.println("insert + "+ e.toString());
			} finally {
				if (in != null)
					in.close();
				if (out != null)
					out.close();
			}
			vo.setImage(file);
			dao.insert(vo);
			break;
		}
	}

 

출력물

 

- 이제 도서 목록에서 페이지를 만들어서 넘어가는걸 구현해보자.

- 이전 이후 버튼을 만들고 클릭 시 페이지 번호가 변경되게 해보자.

- list.jsp

</script>
<hr />
<div>
	<button id="prev">이전</button>
	<span id="page">1/3</span>
	<button id="next">이후</button>
</div>
<script>
	// 첫페이지 변수 선언
	var page = 1;
	getList();

	// 이전 이후 버튼 클릭시 처리
	// 이전
	$('#prev').on('click', function() {
		page--;
		getList();
	});

	// 이후
	$('#next').on('click', function() {
		page++;
		getList();
	});

	// 목록출력
	function getList() {
		$.ajax({
			type : 'get',
			url : '/book/list.json',
			dataType : 'json',
			data : {
				"page" : page
			},
			success : function(data) {
				var temp = Handlebars.compile($('#temp').html());
				$('#books').html(temp(data));
				$('#page').html(page);
			}
		});
	};
</script>

 

- bookservlet

	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		response.setContentType("text/html; charset=UTF-8");
		switch (request.getServletPath()) {
		case "/book/list.json":
			int page = request.getParameter("page") == null ? 1 : Integer.parseInt(request.getParameter("page"));
			BookDAO dao = new BookDAO();
			ArrayList<BookVO> array = dao.list(page);

 

- bookdao - int page 값을 받게 한다.

	// 1. 도서목록 출력 메서드
	public ArrayList<BookVO> list(int page) {
		ArrayList<BookVO> array = new ArrayList<BookVO>();
		try {
			String sql = "select * from books order by code desc limit ? ,5;";
			PreparedStatement ps = Database.CON.prepareStatement(sql);
			ps.setInt(1, (page-1)*5);

 

- 라스트 페이지 값을 구하기 위해서 토탈값을 구하는 메서드를 만들자.

- bookdao

	// 데이터 갯수
	public int total(){
		int total = 0;
		try {
			String sql = "select count(*) from books";
			PreparedStatement ps = Database.CON.prepareStatement(sql);
			ResultSet rs = ps.executeQuery();
			if(rs.next()){
				total = rs.getInt("count(*)");
			}
		} catch (Exception e) {
			System.out.println("total : "+e.toString());
		}
		return total;
	}

 

- bookservlet

		case "/book/list.json":
			BookDAO dao = new BookDAO();
			int page = request.getParameter("page") == null ? 1 : Integer.parseInt(request.getParameter("page"));
			int total = dao.total();
			int last = total%5 == 0? total/5 : total/5+1;
			
			ArrayList<BookVO> array = dao.list(page);
			// json 변환을 위한 라이브러리가 있는지 확인하자.
			JSONArray jArray = new JSONArray();
			for (BookVO vo : array) { // array를 꺼내서 vo에 넣겠다.
				JSONObject obj = new JSONObject();
				obj.put("code", vo.getCode());
				obj.put("title", vo.getTitle());
				obj.put("writer", vo.getWriter());
				DecimalFormat df = new DecimalFormat("#,###원");
				String strPrice = df.format(vo.getPrice());
				obj.put("price", strPrice);
				obj.put("image", vo.getImage());
				obj.put("contents", vo.getContents());
				jArray.add(obj);
			}
			JSONObject jObject = new JSONObject();
			jObject.put("array", jArray);
			jObject.put("total", total);
			jObject.put("last", last);

			PrintWriter out = response.getWriter();
			out.print(jObject);
			break;

 

- list.jsp

- 페이지 html에 첫페이지/라스트페이지를 입력하고, 각각의 경우에 이전 이후 버튼이 disabled하게 하자.

	// 목록출력
	function getList() {
		$.ajax({
			type : 'get',
			url : '/book/list.json',
			dataType : 'json',
			data : {
				"page" : page
			},
			success : function(data) {
				var temp = Handlebars.compile($('#temp').html());
				$('#books').html(temp(data));
				$('#page').html(page+"/"+data.last);
				
				if(page==1){
					$('#prev').attr('disabled',true)
				}else{
					$('#prev').attr('disabled',false)
				}
				
				if(page==data.last){
					$('#next').attr('disabled',true)
				}else{
					$('#next').attr('disabled',false)
				}
			}
		});
	};

출력물

 

- 삭제 버튼을 만들고 삭제 버튼을 입력할 시 팝업이 뜨게하자.

- list

			<h5><a href="/book/delete" code="{{code}}" image="{{image}}" style="background:rgb(36, 117, 194)">삭제</a><h5>
		</div>
	{{/each}}
</script>
<hr />
<div>
	<button id="prev">이전</button>
	<span id="page">1/3</span>
	<button id="next">이후</button>
</div>
<script>
	// 첫페이지 변수 선언
	var page = 1;
	getList();

	// 삭제 버튼을 누를 경우
	$('#books').on('click', '.item h5 a', function(e) {
		e.preventDefault();
		var code = $(this).attr("code");
		var image = $(this).attr("image");
		if(!confirm(code+" 을(를) 삭제하시겠습니까?")) return;
		
	});

 

- 삭제 메서드를 만들자.

- bookdao

	// 4. 도서 삭제 메서드
	public void delete(String code){
		try {
			String sql = "delete from books where code=?";
			PreparedStatement ps = Database.CON.prepareStatement(sql);
			ps.setString(1, code);
			ps.execute();
		} catch (Exception e) {
			System.out.println("delete + "+e.toString());
		}
	}

 

- bookservlet

public class BookServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
	BookDAO dao = new BookDAO();

	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		response.setContentType("text/html; charset=UTF-8");
		switch (request.getServletPath()) {
		case "/book/delete":
			String code = request.getParameter("code");
			String image = request.getParameter("image");
			// 이미지 데이터 삭제
			dao.delete(code);
			// 이미지 파일 삭제
			File file = new File("c:/image/book/"+image);
			file.delete();
			break;

 

- list.jsp

	// 삭제 버튼을 누를 경우
	$('#books').on('click', '.item h5 a', function(e) {
		e.preventDefault();
		var code = $(this).attr("code");
		var image = $(this).attr("image");
		if (!confirm(code + " 을(를) 삭제하시겠습니까?"))
			return;
		$.ajax({
			type : 'get',
			url : "/book/delete",
			data : {
				"code" : code,
				"image" : image
			},
			success : function() {
				alert("도서삭제 성공");
				getList();
			}
		})
	});

 

삭제하여 위와 같이 초기값만 나오도록 하였다.

 

- 이제 도서 정보 읽기 메서드를 만들어보자.

- bookdao - vo에 sql로부터 가져온 데이터를 담는다.

	// 5. 도서 정보 읽기 메서드
	// 목록중 하나만 출력할 경우 BookVO로
	public BookVO read(String code) {
		BookVO vo = new BookVO();
		try {
			String sql = "select * from books where code=?";
			PreparedStatement ps = Database.CON.prepareStatement(sql);
			ps.setString(1, code);
			ResultSet rs = ps.executeQuery();
			if (rs.next()) {
				vo.setCode(rs.getString("code"));
				vo.setTitle(rs.getString("title"));
				vo.setWriter(rs.getString("writer"));
				vo.setPrice(rs.getInt("price"));
				vo.setImage(rs.getString("image"));
				vo.setContents(rs.getString("contents"));
			}
		} catch (Exception e) {
			System.out.println("read : " + e.toString());
		}
		return vo;
	}

 

- 이 메서드를 서블릿에서 호출하자.

- bookservlet

		case "/book/read":
			String code = request.getParameter("code");
			request.setAttribute("vo", dao.read(code));
			request.setAttribute("pageName", "/book/read.jsp");
			RequestDispatcher dis = request.getRequestDispatcher("/main.jsp");
			dis.forward(request, response);
			break;

 

- list - 이미지를 클릭할 경우 /book/read로 연결되게 한다.

<script id="temp" type="text/x-handlebars-template">
	{{#each array}}
		<div class="item">
			<img src="/image/book/{{image}}" width=150 onClick="location.href='/book/read?code={{code}}'"/>
			<div class="info">
				<div class="title">{{title}}</div>
				<div class="price">{{price}}</div>
				<div class="authors">{{writer}}</div>
				<div class="contents">{{contents}}</div>
			</div>
			<h5><a href="/book/delete" code="{{code}}" image="{{image}}" style="background:rgb(36, 117, 194)">삭제</a><h5>
		</div>
	{{/each}}
</script>

 

- new read.jsp - vo에 담아온 정보를 출력한다.

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<style>
.item {
	overflow: hidden;
	margin: 0px auto;
}

.item img {
	float: left;
	border: 1px solid gray;
	box-shadow:5px 5px 5px gray;
}

.item .info {
	float: left;
	width: 500px;
	margin-left: 20px;
}

input[type=text] {
	width: 100%;
	margin-bottom: 10px;
}
</style>
<h1>[도서 정보]</h1>
<form name="frm">
	<div class="item">
		<img src="/image/book/${vo.image}" width=200 />
		<div class="info">
			도서 코드 <input type="text" name="code" value="${vo.code}" />
			<hr />
			도서 제목<input type="text" name="title" value="${vo.title}" />
			<hr />
			도서 저자<input type="text" name="writer" value="${vo.writer}" />
			<hr />
			도서 가격<input type="text" name="price" value="${vo.price}" />
			<hr />
		</div>
		<textarea cols="72" rows="10" style="margin-left:20px">${vo.contents}</textarea>
	</div>
	<hr />
	<div style="text-align: center">
	<input type="submit" value="정보수정"/>
	<input type="reset" value="수정취소"/>
	</div>
</form>

 

출력물

 

- 도서정보 수정하는 메서드를 만들어보자.

- bookdao

	// 6. 도서 수정 메서드
	public void update(BookVO vo){
		try {
			String sql = "update books set title=?, writer=?, price=?, contents=? where code=?";
			PreparedStatement ps = Database.CON.prepareStatement(sql);
			ps.setString(1, vo.getTitle());
			ps.setString(2, vo.getWriter());
			ps.setInt(3, vo.getPrice());
			ps.setString(4, vo.getContents());
			ps.setString(5, vo.getCode());
			ps.execute();
		} catch (Exception e) {
			System.out.println("update : "+e.toString());
		}
	}

 

- bookservlet

	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		request.setCharacterEncoding("UTF-8");
		
		BookVO vo = new BookVO();
		vo.setTitle(request.getParameter("title"));
		vo.setPrice(Integer.parseInt(request.getParameter("price")));
		vo.setWriter(request.getParameter("writer"));
		vo.setContents(request.getParameter("contents"));
		
		switch (request.getServletPath()) {
		case "/book/update":
			vo.setCode(request.getParameter("code")); // new
			dao.update(vo);
			response.sendRedirect("/book/list");
			break;

 

- 이제 read page에서 submit을 눌렀을때 적용되게 하자.

- read.jsp

	<div style="text-align: center">
		<input type="submit" value="정보수정" /> <input type="reset" value="수정취소" />
	</div>
</form>
<script>
	$(frm).on('submit',function(e){
		e.preventDefault();
		if(!confirm("수정하시겠습니까?"))return;
		frm.action="/book/update";
		frm.method="post";
		frm.submit();
	})
</script>

 

출력물