본문 바로가기
ICIA 수업일지

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

by 주성씨 2021. 8. 26.

https://developers.naver.com/docs/serviceapi/search/movie/movie.md#%EC%98%81%ED%99%94

 

영화 - Search API

영화 NAVER Developers - 검색 API 영화 검색 개발가이드 검색 > 영화 네이버 영화 검색 결과를 출력해주는 REST API입니다. 비로그인 오픈 API이므로 GET으로 호출할 때 HTTP Header에 애플리케이션 등록 시

developers.naver.com

 

- api : 외부에 다른 개발자가 만든 프로그램을 가져다 쓰는 방식

- 영화검색을 통해서 새로운 프로젝트를 만들어보자.

- create new main.jsp, about.jsp, mainservlet.java

- 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: 'Vitro_core';
	src:
		url('https://cdn.jsdelivr.net/gh/projectnoonnu/noonfonts_20-10-21@1.0/Vitro_core.woff')
		format('woff');
	font-weight: normal;
	font-style: normal;
}

body {
	font-family: 'Vitro_core';
	background: rgb(224, 224, 235);
}

#container {
	width: 960px;
	border: 1px solid rgb(99, 99, 156);
	margin: 0 auto;
	padding: 20px;
	background: white;
}

#header {
	padding: 20px;
	border: 1px solid rgb(99, 99, 156);
	background: rgb(99, 99, 156);
}

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

#footer {
	padding: 20px;
	border: 1px solid rgb(99, 99, 156);
	color: white;
	background: rgb(99, 99, 156);
}

#menu {
	overflow: hidden;
	border-bottom: 1px dotted black;
	background: rgb(99, 99, 156);
}

#menu h4 {
	float: left;
	width: 150px;
	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: white;
	padding: 10px;
}

a:hover {
	cursor: pointer;
	text-decoration: none;
	background: rgb(54, 57, 69);
	color: white;
	padding: 10px;
	border-radius: 10px;
}

a:VISITED {
	color: white;
}
</style>
</head>
<body>
	<div id="container">
		<div id="header">
			<h1>
				<a href="/">영화정보</a>
			</h1>
		</div>
		<div id="center">
			<div id="menu">
				<h4>
					<a href="/movie/list">영화목록</a>
				</h4>
				<h4>
					<a href="/movie/search">영화검색</a>
				</h4>
			</div>
			<div id="content">
				<jsp:include page="${page}"></jsp:include>
			</div>
		</div>
		<div id="footer">
			<h3>Copyright 2021. LCinemas. All rights reserved.</h3>
		</div>
	</div>
</body>
<script>
	var page = "${page}";

	if (page == "/movie/list.jsp") {
		$('#menu h4:nth-child(1)').css("background-color",'red');
	} else if (page == "/movie/search.jsp") {
		$('#menu h4:nth-child(2)').css("background-color",'red');
	}
</script>
</html>

 

- about.jsp

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

 

- 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 {
		RequestDispatcher dis = request.getRequestDispatcher("/main.jsp");
		request.setAttribute("page", "/about.jsp");
		dis.forward(request, response);
	}

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

}

 

- movieservlet

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(value = { "/movie/list", "/movie/search", "/movie/insert", "/movie/read", "/movie/update",
		"/movie/delete" })
public class MovieServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

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

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

}

 

- search

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<h1>영화검색</h1>

 

- list

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<h1>영화목록</h1>

 

출력물

 

- 어제 사용한 naverapi, database, library 를 복사해서 붙여넣자.

- naverapi 

package model;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;

public class NaverAPI {

	public static String search(String query, int pageNum) {
		// static 이기 때문에 productservlet에 따로 객체를 새롭게 안만들어줘도 된다.
		String clientId = "z3KOjXI9rjwIRFoYR_Hm"; // 애플리케이션 클라이언트 아이디값"
		String clientSecret = "IJNWE8ERBI"; // 애플리케이션 클라이언트 시크릿값"

		String text = null;
		try {
			text = URLEncoder.encode(query, "UTF-8");
		} catch (UnsupportedEncodingException e) {
			throw new RuntimeException("검색어 인코딩 실패", e);
		}
		int start = (pageNum-1)*5+1;
		System.out.println(start);
        // new
		String apiURL = "https://openapi.naver.com/v1/search/movie.json?query=" + text; // json
		apiURL += "&display=5&start="+start;
		
		Map<String, String> requestHeaders = new HashMap<>();
		requestHeaders.put("X-Naver-Client-Id", clientId);
		requestHeaders.put("X-Naver-Client-Secret", clientSecret);
		String responseBody = get(apiURL, requestHeaders);

		System.out.println(responseBody);
		return responseBody;
	}

	private static String get(String apiUrl, Map<String, String> requestHeaders) {
		HttpURLConnection con = connect(apiUrl);
		try {
			con.setRequestMethod("GET");
			for (Map.Entry<String, String> header : requestHeaders.entrySet()) {
				con.setRequestProperty(header.getKey(), header.getValue());
			}

			int responseCode = con.getResponseCode();
			if (responseCode == HttpURLConnection.HTTP_OK) { // 정상 호출
				return readBody(con.getInputStream());
			} else { // 에러 발생
				return readBody(con.getErrorStream());
			}
		} catch (IOException e) {
			throw new RuntimeException("API 요청과 응답 실패", e);
		} finally {
			con.disconnect();
		}
	}

	private static HttpURLConnection connect(String apiUrl) {
		try {
			URL url = new URL(apiUrl);
			return (HttpURLConnection) url.openConnection();
		} catch (MalformedURLException e) {
			throw new RuntimeException("API URL이 잘못되었습니다. : " + apiUrl, e);
		} catch (IOException e) {
			throw new RuntimeException("연결이 실패했습니다. : " + apiUrl, e);
		}
	}

	private static String readBody(InputStream body) {
		InputStreamReader streamReader = null;
		try {
			streamReader = new InputStreamReader(body,"UTF-8");
		} catch (Exception e1) {
			e1.printStackTrace();
		}

		try (BufferedReader lineReader = new BufferedReader(streamReader)) {
			StringBuilder responseBody = new StringBuilder();

			String line;
			while ((line = lineReader.readLine()) != null) {
				responseBody.append(line);
			}

			return responseBody.toString();
		} catch (IOException e) {
			throw new RuntimeException("API 응답을 읽는데 실패했습니다.", e);
		}
	}
}

 

- movieservlet

@WebServlet(value = { "/movie/list", "/movie/search", "/movie.json", "/movie/insert", "/movie/read", "/movie/update",
		"/movie/delete" })
public class MovieServlet 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");
		// 웹 출력 클래스
		PrintWriter out = response.getWriter();
		switch (request.getServletPath()) {
		case "/movie.json":
			out.println(NaverAPI.search("터미네이터", 1));
			break;
		case "/movie/search":
			RequestDispatcher dis = request.getRequestDispatcher("/main.jsp");
			request.setAttribute("page", "/movie/search.jsp");
			dis.forward(request, response);
			break;
		case "/movie/list":
			dis = request.getRequestDispatcher("/main.jsp");
			request.setAttribute("page", "/movie/list.jsp");
			dis.forward(request, response);
			break;
		}
	}

 

출력물

 

- search 에 검색을 통해서 가지고 온 데이터의 총 갯수를 alert 해보자.

- search.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<h1>영화검색</h1>

<script>
	getList();
	function getList() {
		$.ajax({
			type : 'get',
			url : '/movie.json',
			dataType : 'json',
			success : function(data) {
				alert(data.total)
			}
		})
	}
</script>

 

- 출력할 템플릿을 만들자.

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<style>
h1 {
	text-shadow: 2px 2px 2px gray;
}

.item {
	overflow: hidden;
	border: 1px solid black;
	margin-bottom: 10px;
	font-family: none;
}

img {
	float: left;
	padding: 10px;
	border: 1px solid gray;
	margin: 10px;
}

.infoTitle {
	float: left;
	margin-left: 10px;
	padding: 10px;
	font-size: 20px;
}

.info {
	float: left;
	margin-left: 10px;
	padding: 10px;
	font-size: 20px;
	width: 250px;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.info .title {
	font-weight: bold;
}

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

.item h4 {
	cursor: pointer;
	background: red;
	color: white;
	border: 1px solid red;
	padding: 10px;
	float: right;
	margin-right: 20px;
	margin-top: 180px;
	border-radius: 5px;
}
</style>
<h1>영화검색</h1>
<div id="movies"></div>
<script id="temp" type="text/x-handlebars-template">
{{#each items}}
<div class="item">
	<img src="{{image}}" width=200/>
	<div class="infoTitle">
		<div>- 영화제목 :</div>
		<div>- 출연배우 :</div>
		<div>- 영화감독 :</div>
		<div>- 제작년도 :</div>
	</div>
	<div class="info">
		<div class="title">{{title}}</div>
		<div class="actor">{{actor}}</div>
		<div class="director">{{director}}</div>
		<div class="pubDate">{{{pubDate}}}</div>
	</div>
	<h4>저장</h4>
</div>
{{/each}}
</script>
<script>
	getList();
	function getList() {
		$.ajax({
			type : 'get',
			url : '/movie.json',
			dataType : 'json',
			success : function(data) {
				var temp = Handlebars.compile($('#temp').html());
				$('#movies').html(temp(data));
			}
		})
	}
</script>

 

출력물

 

- 검색어 입력하여 검색하고 해당 검색어에 대하 검색건수 및 페이지를 더보기 버튼을 통해서 출력해보도록 하겠다.

- search

<h1>영화검색</h1>
<div id="condition">
	검색어 : <input type="text" id="query" value="아이언맨" /> 검색수 : <span
		id="total"></span>건
</div>

<div id="movies"></div>
<script id="temp" type="text/x-handlebars-template">
{{#each items}}
<div class="item">
	<img src="{{image}}" width=200/>
	<div class="infoTitle">
		<div>- 영화제목 :</div>
		<div>- 출연배우 :</div>
		<div>- 영화감독 :</div>
		<div>- 제작년도 :</div>
	</div>
	<div class="info">
		<div class="title">{{{title}}}</div>
		<div class="actor">{{actor}}</div>
		<div class="director">{{director}}</div>
		<div class="pubDate">{{{pubDate}}}</div>
	</div>
	<h4>저장</h4>
</div>
{{/each}}
</script>
<button id="more">더보기</button>
<script>
	// 페이지 전역변수 선언
	var pageNum = 1;

	getList();

	// 검색어 입력시 출력 초기화 및 페이지 1번으로
	$('#query').on('keypress', function(e) {
		if (e.keyCode == 13) {
			$('#movies').html("");
			pageNum = 1;
			getList();
		}
	})

	// 더보기 버튼 입력시
	$('#more').on('click', function() {
		pageNum++;
		getList();
	})

	function getList() {
		var query = $('#query').val();
		$.ajax({
			type : 'get',
			url : '/movie.json',
			dataType : 'json',
			data : {
				"query" : query,
				"pageNum" : pageNum
			},
			success : function(data) {
				var temp = Handlebars.compile($('#temp').html());
				$('#movies').append(temp(data));
                $('#total').html(data.total);
			}
		})
	}
</script>

 

- movieservlet

@WebServlet(value = { "/movie/list", "/movie/search", "/movie.json", "/movie/insert", "/movie/read", "/movie/update",
		"/movie/delete" })
public class MovieServlet 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");
		// 웹 출력
		PrintWriter out = response.getWriter();
		switch (request.getServletPath()) {
		case "/movie.json":
			int page = Integer.parseInt(request.getParameter("pageNum"));
			String query = request.getParameter("query");
			out.println(NaverAPI.search(query, page));
			break;

 

검색 더보기를 확인할 수 있다.

 

- 검색한 내용을 DB에 넣어보자.

- 영화 데이터를 위한 테이블을 db에 만들어보자.

- back to mysql

-- 2021.08.26
create table movie(
title nvarchar(200) primary key,
actor nvarchar(200),
director nvarchar(200),
pubDate nvarchar(20),
image nvarchar(200),
wdate datetime default now()
);
desc movie;

 

디스크립션 확인

 

- create model\ new moviedao.java & movievo.java

- movievo.java

package model;

import java.util.Date;

public class MovieVO {
	private String title;
	private String actor;
	private String director;
	private String pubDate;
	private String image;
	private Date wdate;

	public String getTitle() {
		return title;
	}

	public void setTitle(String title) {
		this.title = title;
	}

	public String getActor() {
		return actor;
	}

	public void setActor(String actor) {
		this.actor = actor;
	}

	public String getDirector() {
		return director;
	}

	public void setDirector(String director) {
		this.director = director;
	}

	public String getPubDate() {
		return pubDate;
	}

	public void setPubDate(String pubDate) {
		this.pubDate = pubDate;
	}

	public String getImage() {
		return image;
	}

	public void setImage(String image) {
		this.image = image;
	}

	public Date getWdate() {
		return wdate;
	}

	public void setWdate(Date wdate) {
		this.wdate = wdate;
	}

	@Override
	public String toString() {
		return "MovieVO [title=" + title + ", actor=" + actor + ", director=" + director + ", pubDate=" + pubDate
				+ ", image=" + image + ", wdate=" + wdate + "]";
	}

}

 

- moviedao.java

package model;

import java.sql.PreparedStatement;

public class MovieDAO {
	// 1. 영화 등록 메서드
	public int insert(MovieVO vo) {
		try {
			String sql = "insert into movie(title, actor, director, pubDate, image) values(?,?,?,?,?)";
			PreparedStatement ps = Database.CON.prepareStatement(sql);
			ps.setString(1, vo.getTitle());
			ps.setString(2, vo.getActor());
			ps.setString(3, vo.getDirector());
			ps.setString(4, vo.getPubDate());
			ps.setString(5, vo.getImage());
			ps.execute();
			// 중복확인
			return 1;
		} catch (Exception e) {
			System.out.println("insert : " + e.toString());
			// 중복확인
			return 0;
		}
	}
}

 

- 서블릿에서 insert를 실행할 수 있도록 하자.

- movieservlet

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

		request.setCharacterEncoding("UTF-8");
		PrintWriter out = response.getWriter();
		
		MovieVO vo = new MovieVO();
		vo.setTitle(request.getParameter("title"));
		vo.setActor(request.getParameter("actor"));
		vo.setDirector(request.getParameter("director"));
		vo.setTitle(request.getParameter("pubDate"));
		switch (request.getServletPath()) {
		case "/movie/insert":
			int result = dao.insert(vo);
			if(result==1){
				// 성공 이미지 다운로드
			}
			// 성공 결과 확인
			out.println(result);
			break;
		}
	}

}

 

- search.jsp

- 데이터를 받아서 ajax을 통해 서블릿으로 넘겨주도록 하자.

- 우선 데이터가 잘 넘어가는지 콘솔에 찍어보도록 하겠다.

<script>
	// 페이지 전역변수 선언
	var pageNum = 1;

	getList();

	// 저장 버튼 클릭시
	$('#movies').on('click', '.info h4', function() {
		if (!confirm("저장하시겠습니까?"))
			return;
		var title = $(this).parent().find('.title').html();
		var actor = $(this).parent().find('.actor').html();
		var director = $(this).parent().find('.director').html();
		var pubDate = $(this).parent().find('.pubDate').html();
		var image = $(this).parent().parent().find('img').attr('src');
		console.log(title, actor, director, pubDate, image);

	})

 

출력물

 

- ajax을 통해서 데이터를 post형태로 넘겨보자.

	// 저장 버튼 클릭시
	$('#movies').on('click', '.info h4', function() {
		if (!confirm("저장하시겠습니까?"))
			return;
		var title = $(this).parent().find('.title').html();
		var actor = $(this).parent().find('.actor').html();
		var director = $(this).parent().find('.director').html();
		var pubDate = $(this).parent().find('.pubDate').html();
		var image = $(this).parent().parent().find('img').attr('src');
		console.log(title, actor, director, pubDate, image);

		$.ajax({
			type : 'post',
			url : '/movie/insert',
			data : {
				'title' : title,
				'actor' : actor,
				'director' : director,
				'pubDate' : pubDate,
				'image' : image
			},
			success : function(data) {
				if (data == 0) {
					alert("저장 성공");
				} else {
					alert("저장 실패");
				}
			}
		})

	})

 

데이터가 DB에 저장됨을 확인할 수 있다.

 

- 기본키인 타이틀을 통해 중복체크를 하도록 하겠다.

- moviedao

	// 2. 제목 체크 메서드
	public int check(String title) {
		int check = 0;
		try {
			String sql = "select * from movie where title=?";
			PreparedStatement ps = Database.CON.prepareStatement(sql);
			ps.setString(1, title);
			ResultSet rs = ps.executeQuery();
			if (rs.next())
				check = 1;
		} catch (Exception e) {
			System.out.println("check : " + e.toString());
		}
		return check;
	}

 

- movieservlet.java

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

		request.setCharacterEncoding("UTF-8");
		PrintWriter out = response.getWriter();

		MovieVO vo = new MovieVO();
		vo.setTitle(request.getParameter("title"));
		vo.setActor(request.getParameter("actor"));
		vo.setDirector(request.getParameter("director"));
		vo.setPubDate(request.getParameter("pubDate"));
		
		switch (request.getServletPath()) {
		case "/movie/insert":
			
			int check = dao.check(vo.getTitle());
			
			if (check == 0) {
				String image = request.getParameter("image");
				System.out.println("image" + image);
				String file = System.currentTimeMillis() + ".jpg";
				InputStream inStr = null;
				OutputStream outStr = null;
				try {
					URL url = new URL(image);
					inStr = url.openStream();
					outStr = new FileOutputStream("c:/image/movie/" + file);
					while (true) {
						int data = inStr.read();
						if (data == -1)
							break;
						outStr.write(data);
					}
					inStr.close();
					outStr.close();
				} catch (Exception e) {
					System.out.println("insert : " + e.toString());
				} finally {
					if (inStr != null)
						inStr.close();
					if (outStr != null)
						outStr.close();
				}
				System.out.println(file);
				vo.setImage(file);
				dao.insert(vo);
			}
			// 성공 결과 확인
			out.println(check);
			break;
		}
	}

 

저장 확인

 

DB 확인

 

- 저장된 데이터를 목록으로 출력해보자.

- moviedao.java

	// 3. 영화 목록 출력
	public JSONObject list() {
		JSONObject obj = new JSONObject();
		JSONArray array = new JSONArray();
		try {
			String sql = "select count(*) from movie";
			PreparedStatement ps = Database.CON.prepareStatement(sql);
			ResultSet rs = ps.executeQuery();
			if (rs.next())
				obj.put("total", rs.getInt("count(*)"));

			sql = "select * from movie order by wdate desc";
			ps = Database.CON.prepareStatement(sql);
			rs = ps.executeQuery();
			while (rs.next()) {
				JSONObject object = new JSONObject();
				object.put("title", rs.getString("title"));
				object.put("actor", rs.getString("actor"));
				object.put("director", rs.getString("director"));
				object.put("pubDate", rs.getString("pubDate"));
				object.put("image", rs.getString("image"));
				array.add(object);
			}
			obj.put("array", array);
		} catch (Exception e) {
			System.out.println("list : " + e.toString());
		}

		return obj;
	}

 

- movieservlet.java

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

	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		// 한글 깨짐 방지 인코딩
		response.setContentType("text/html;charset=UTF-8");
		// 웹 출력
		PrintWriter out = response.getWriter();
		switch (request.getServletPath()) {
		case "/movie/list.json":
			out.println(dao.list());
			break;

 

출력물

 

- 이제 list.jsp에 목록을 출력해보자.

- search에서 템플릿이랑 CSS getList를 가지고 오겠다.

- list.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<style>
.item {
	width: 860px;
	overflow: hidden;
	border: 1px solid black;
	margin-bottom: 10px;
	font-family: none;
	overflow: hidden;
}

img {
	float: left;
	padding: 10px;
	border: 1px solid gray;
	margin: 10px;
}

.infoTitle {
	float: left;
	margin-left: 10px;
	padding: 10px;
	font-size: 20px;
}

.info {
	float: left;
	margin-left: 10px;
	padding: 10px;
	font-size: 20px;
	width: 200px;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.info .title {
	font-weight: bold;
}

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

.item h4 {
	cursor: pointer;
	background: red;
	color: white;
	border: 1px solid red;
	padding: 10px;
	float: none;
	margin-right: 20px;
	margin-top: 120px;
	border-radius: 5px;
	text-align: center;
}
</style>
<h1>영화목록</h1>
<div id="condition">
	검색어 : <input type="text" id="query" value="" />
	검색수 : <span id="total"></span>건
</div>

<div id="movies"></div>
<script id="temp" type="text/x-handlebars-template">
{{#each array}}
<div class="item">
	<img src="/image/movie/{{image}}" width=200/>
	<div class="infoTitle">
		<div>- 영화제목 :</div>
		<div>- 출연배우 :</div>
		<div>- 영화감독 :</div>
		<div>- 제작년도 :</div>
	</div>
	<div class="info">
		<div class="title">{{{title}}}</div>
		<div class="actor">{{actor}}</div>
		<div class="director">{{director}}</div>
		<div class="pubDate">{{{pubDate}}}</div>
		<h4>저장</h4>
	</div>
</div>
{{/each}}
</script>
<script>
	getList();
	function getList() {
		$.ajax({
			type : 'get',
			url : '/movie/list.json',
			dataType : 'json',
			success : function(data) {
				var temp = Handlebars.compile($('#temp').html());
				$('#movies').append(temp(data));
				$('#total').html(data.total);
			}
		})
	}
</script>

 

출력물

 

- 이미지가 없는 경우

- lis.jsp

<script id="temp" type="text/x-handlebars-template">
{{#each array}}
<div class="item">
	<img src="{{printImage image}}" width=200/>
	<div class="infoTitle">
		<div>- 영화제목 :</div>
		<div>- 출연배우 :</div>
		<div>- 영화감독 :</div>
		<div>- 제작년도 :</div>
	</div>
	<div class="info">
		<div class="title">{{{title}}}</div>
		<div class="actor">{{actor}}</div>
		<div class="director">{{director}}</div>
		<div class="pubDate">{{{pubDate}}}</div>
		<h4>저장</h4>
	</div>
</div>
{{/each}}
</script>
<script>
	Handlebars.registerHelper('printImage', function(image) {
		if (!image)
			return "http://placehold.it/200/200"
		else
			return "/image/movie/" + image;
	})
</script>

 

출력물

 

- 크롤링으로 CGV에서 데이터를 가지고 와보자.

- 크롤링을 위한 라이브러리를 확인해보자.

크롤링 라이브러리
jsoup-1.13.1.jar
0.38MB

 

위치를 확인하고 넣자.

 

- cgv.json이라는 path를 등록하자.

- movieservlet.java

http://www.cgv.co.kr/movies/

 

영화 그 이상의 감동. CGV

인질 예매율12.6% 91% 2021.08.18 개봉 예매

www.cgv.co.kr

 

크롬 기준 브라우저에서 F12를 눌러 요소를 확인할 수 잇따.

 

@WebServlet(value = { "/movie/list", "/movie/list.json", "/movie/search", "/movie.json", "/movie/insert", "/movie/read",
		"/movie/update", "/movie/delete","/cgv.json" })
public class MovieServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
	MovieDAO dao = new MovieDAO();

	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		// 한글 깨짐 방지 인코딩
		response.setContentType("text/html;charset=UTF-8");
		// 웹 출력
		PrintWriter out = response.getWriter();
		switch (request.getServletPath()) {
		case "/cgv.json":
			try {
				Document doc = Jsoup.connect("http://www.cgv.co.kr/movies/").get();
				Elements elements = doc.select(".sect-movie-chart");
				System.out.println(elements);
			} catch (Exception e) {
				System.out.println("/cgv.json : "+e.toString());
			}
			break;

 

콘솔에서 데이터를 가지고 온것을 확인할 수 있다.

 

@WebServlet(value = { "/movie/list", "/movie/list.json", "/movie/search", "/movie.json", "/movie/insert", "/movie/read",
		"/movie/update", "/movie/delete", "/cgv.json" })
public class MovieServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
	MovieDAO dao = new MovieDAO();

	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		// 한글 깨짐 방지 인코딩
		response.setContentType("text/html;charset=UTF-8");
		// 웹 출력
		PrintWriter out = response.getWriter();
		switch (request.getServletPath()) {
		case "/cgv.json":
			try {
				JSONArray mArray = new JSONArray();
				Document doc = Jsoup.connect("http://www.cgv.co.kr/movies/").get();
				Elements elements = doc.select(".sect-movie-chart ol");
				for (Element e : elements.select("li")) {
					JSONObject mObj = new JSONObject();
					String title = e.select(".title").text();
					if (!title.equals("")) {
						mObj.put("title", title);
						String image = e.select("img").attr("src");
						mObj.put("image", image);
						String pubDate = e.select(".txt-info strong").text();
						pubDate = pubDate.substring(0,10);
						mObj.put("putDate", pubDate);
						// System.out.println(title+":"+image+":"+pubDate);
						mArray.add(mObj);
					}
				}
				out.println(mArray);
			} catch (Exception e) {
				System.out.println("/cgv.json : " + e.toString());
			}
			break;

 

웹에서 위와 같이 json 으로 데이터를 가지고 온것을 확인할 수 있다.

 

		case "/movie/cgv":
			dis = request.getRequestDispatcher("/main.jsp");
			request.setAttribute("page", "/movie/cgv.jsp");
			dis.forward(request, response);
			break;
		}
	}

 

- create new cgv.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<h1>CGV 무비차트</h1>

 

- main.jsp

			<div id="menu">
				<h4>
					<a href="/movie/list">영화목록</a>
				</h4>
				<h4>
					<a href="/movie/search">영화검색</a>
				</h4>
				<h4>
					<a href="/movie/cgv">무비차트</a>
				</h4>
			</div>

 

- cgv.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<style>
#movies {
	overflow: hidden;
	margin-left: 5px;
}

img{
	border: 5px black solid;
}

.item {
	float: left;
	margin:10px;
	box-shadow : 5px 5px 5px gray;
}
.info{
	padding: 5px;
}
</style>
<h1>CGV 무비차트</h1>
<div id="movies"></div>
<script id="temp" type="text/x-handlebars-template">
{{#each .}}
<div class="item">
	<img src="{{image}}" width=190/>
	<div class="info">
		<div class="title">제목 : {{{title}}}</div>
		<div class="pubDate">개봉일 : {{{pubDate}}}</div>
	</div>
</div>
{{/each}}
</script>
<script>
	getList();
	function getList() {
		$.ajax({
			type : 'get',
			url : '/cgv.json',
			dataType : 'json',
			success : function(data) {
				var temp = Handlebars.compile($('#temp').html());
				$('#movies').html(temp(data));
			}
		})
	}
</script>

 

출력물

 

- 다음에서 날씨 데이터를 가지고 와보겠다.

https://www.daum.net/?t__nil_top=refresh 

 

Daum

나의 관심 콘텐츠를 가장 즐겁게 볼 수 있는 Daum

www.daum.net

@WebServlet(value = { "/movie/list","/daumWeather","/daumWeather.json", "/movie/cgv", "/movie/list.json", "/movie/search",
		"/movie.json", "/movie/insert", "/movie/read", "/movie/update", "/movie/delete", "/cgv.json" })
public class MovieServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
	MovieDAO dao = new MovieDAO();

	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		// 한글 깨짐 방지 인코딩
		response.setContentType("text/html;charset=UTF-8");
		// 웹 출력
		PrintWriter out = response.getWriter();
		switch (request.getServletPath()) {
		case "/daumWeather.json":
			try {
				JSONArray wArray = new JSONArray();
				Document wDoc = Jsoup.connect("https://www.daum.net/").get();
				Elements wElements = wDoc.select(".list_weather");
				for (Element e : wElements.select("li")) {
					JSONObject wObj = new JSONObject();
					String area = e.select(".txt_part").text();
					wObj.put("area", area);
					String temperature = e.select(".screen_out").text();
					wObj.put("temperature", temperature);
					// System.out.println(area + ":" + temperature);
					wArray.add(wObj);
				}
				out.println(wArray);
			} catch (Exception e) {
				System.out.println("/daumWeather.json" + e.toString());
			}
			break;

 

- main.jsp

<body>
	<div id="container">
		<div id="header">
			<h1>
				<a href="/">영화정보</a>
			</h1>
		</div>
		<div id="center">
			<div id="menu">
				<h4>
					<a href="/movie/list">영화목록</a>
				</h4>
				<h4>
					<a href="/movie/search">영화검색</a>
				</h4>
				<h4>
					<a href="/movie/cgv">무비차트</a>
				</h4>
				<h4 style="float: right; color: white;" id="weather">날씨 정보</h4>
			</div>
			<div id="content">
				<jsp:include page="${page}"></jsp:include>
			</div>
		</div>
		<div id="footer">
			<h3>Copyright 2021. LCinemas. All rights reserved.</h3>
		</div>
	</div>
</body>
<script>
	var page = "${page}";

	if (page == "/movie/list.jsp") {
		$('#menu h4:nth-child(1)').css("background-color", 'red');
	} else if (page == "/movie/search.jsp") {
		$('#menu h4:nth-child(2)').css("background-color", 'red');
	}

	var weather = [];
	getWeather();
	function getWeather() {
		$.ajax({
			type : 'get',
			url : '/daumWeather.json',
			dataType : 'json',
			success : function(data) {
				var index = 0;
				$(data).each(function() {
					weather[index] = this.area + " " + this.temperature;
					index++;
				})
			}
		})
	}
	var index = 0;
	setInterval(function() {
		$("#weather").html(weather[index & weather.length]);
		index++;
	}, 3000);
</script>

 

출력물 gif

 

- CGV 무비차트에서 데이터를 가지고와서 메인에 순위를 보여주도록 하자.

- main.jsp

<body>
	<div id="container">
		<div id="header">
			<h1>
				<a href="/">영화정보</a>
			</h1>
		</div>
		<div id="center">
			<div id="menu">
				<h4>
					<a href="/movie/list">영화목록</a>
				</h4>
				<h4>
					<a href="/movie/search">영화검색</a>
				</h4>
				<h4>
					<a href="/movie/cgv">무비차트</a>
				</h4>
				<h4 style="float: right; color: white;" id="movieChart">영화순위</h4>
				<h4 style="float: right; color: white; width: 200px" id="weather">날씨정보</h4>
			</div>
			<div id="content">
				<jsp:include page="${page}"></jsp:include>
			</div>
		</div>
		<div id="footer">
			<h3>Copyright 2021. LCinemas. All rights reserved.</h3>
		</div>
	</div>
</body>
	var movieChart = [];
	getMovieChart();
	function getMovieChart() {
		$.ajax({
			type : 'get',
			url : '/cgv.json',
			dataType : 'json',
			success : function(data) {
				var index = 0;
				$(data).each(function() {
					movieChart[index] = index + 1 + " . " + this.title;
					index++;
				})
			}
		})
	}
    
    var index = 0;
	setInterval(function() {
		$("#weather").html(weather[index & weather.length]);
		$("#movieChart").html(movieChart[index & movieChart.length]);
		index++;
	}, 3000);

 

출력물

 

ex08.zip
1.44MB