- SpringμΌλ‘ ν¬ν κΈ°λ₯ ꡬννκΈ°
1. ν¬ν κΈ°λ₯μ νμν DB ν μ΄λΈ μμ±
POLL ν μ΄λΈ : ν¬ν κΈμ λν λ²νΈ(PK)μ μμ±μ, μμ±μ λͺ©, ν¬ν μμ λ μ§, λλλ λ μ§, ν¬ν νλͺ© κ°μ, μ΄ ν¬νμ, κΈ μμ± μκ°μ λ΄κ³ μλ€.
POLLSUB ν μ΄λΈ : POLL ν μ΄λΈμ POLLID(ν¬νκΈ λ²νΈ)λ₯Ό λ°μμ ν¬ν νλͺ©λ€ κ°κ°μ μ΄λ¦κ³Ό ν¬ν μλ₯Ό λ΄μλλ€.
VOTER ν μ΄λΈ : IDκ° ν¬ννμ λ μ΄λ€ ν¬νκΈμ μ΄λ€ νλͺ©μ ν¬ννλμ§μ ν¬νν μκ°μ λ΄μλλ€.
2. MyBatisλ₯Ό νμ©ν 쿼리문 μμ±
Poll.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="Poll">
<!-- λͺ¨λ ν¬ν λͺ©λ‘ -->
<select id="getPollAllList" resultType="bit.com.a.poll.PollDto">
SELECT POLLID, ID, QUESTION, SDATE, EDATE, ITEMCOUNT, POLLTOTAL, REGDATE
FROM POLL
ORDER BY SDATE DESC
</select>
<!-- ν¬νλ₯Ό νλμ§ μ¬λΆ νμΈ (1μ΄λ©΄ ν¬νν κ²)-->
<select id="isVote" parameterType="bit.com.a.poll.Voter" resultType="int">
SELECT NVL(COUNT(*), 0)
FROM VOTER
WHERE POLLID=#{pollId} AND ID=#{id}
</select>
<!-- ν¬ν λ§λ€κΈ° -->
<insert id="makePoll" parameterType="bit.com.a.poll.PollDto">
INSERT INTO POLL(POLLID, ID, QUESTION, SDATE, EDATE, ITEMCOUNT, POLLTOTAL, REGDATE)
VALUES(POLL_SEQ.NEXTVAL, #{id}, #{question}, #{sDate}, #{eDate}, #{itemCount}, 0, SYSDATE)
</insert>
<!-- ν¬ν νλͺ©λ€ -->
<insert id="makePollSub" parameterType="bit.com.a.poll.PollSubDto">
INSERT INTO POLLSUB(POLLSUBID, POLLID, ANSWER, ACOUNT)
VALUES(POLLSUB_SEQ.NEXTVAL, (SELECT NVL(MAX(POLLID),0) FROM POLL), #{answer}, 0)
</insert>
<!-- ν¬ν μ 보 μ·¨λ -->
<select id="getPoll" parameterType="bit.com.a.poll.PollDto" resultType="bit.com.a.poll.PollDto">
SELECT POLLID, ID, QUESTION, SDATE, EDATE, ITEMCOUNT, POLLTOTAL, REGDATE
FROM POLL
WHERE POLLID=#{pollId}
</select>
<!-- ν¬ν νλͺ©λ€ -->
<select id="getPollSubList" parameterType="bit.com.a.poll.PollDto" resultType="bit.com.a.poll.PollSubDto">
SELECT POLLSUBID, POLLID, ANSWER, ACOUNT
FROM POLLSUB
WHERE POLLID=#{pollId}
</select>
<!-- ν¬ννμ λ -->
<!-- λκ°? -->
<insert id="pollingVoter" parameterType="bit.com.a.poll.Voter">
INSERT INTO VOTER(VOTERID, POLLID, POLLSUBID, ID, REGDATE)
VALUES(VOTER_SEQ.NEXTVAL, #{pollId}, #{pollSubId}, #{id}, SYSDATE)
</insert>
<!-- μ΄λ ν¬νμ -->
<update id="pollingPoll" parameterType="bit.com.a.poll.Voter">
UPDATE POLL
SET POLLTOTAL=POLLTOTAL+1
WHERE POLLID=#{pollId}
</update>
<!-- μ΄λ νλͺ©μ -->
<update id="pollingSub" parameterType="bit.com.a.poll.Voter">
UPDATE POLLSUB
SET ACOUNT=ACOUNT+1
WHERE POLLSUBID=#{pollSubId} AND POLLID=#{pollId}
</update>
</mapper>
3. ServiceImplμμ νΈλμμ μ²λ¦¬
PollServiceImpl.java
package bit.com.a.poll;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class PollServiceImpl implements PollService {
@Autowired
PollDao dao;
@Override
public List<PollDto> getPollAllList(String id) {
//λͺ¨λ ν¬ν λͺ©λ‘μ κ°μ§κ³ μ¨λ€.
List<PollDto> list = dao.getPollAllList();
//ν¬ν μ°Έμ¬νλμ§ νμΈ ν λκ²¨μ€ λͺ©λ‘ (νλ²λ§ μ°Έμ¬ κ°λ₯ν΄μΌ νλ―λ‘)
List<PollDto> pList = new ArrayList<PollDto>();
/* Voter ν
μ΄λΈμ κΈ°λ‘μ΄ μλ€λ©΄ ν΄λΉ ν¬νμ μ°Έμ¬ν κ² */
for (PollDto poll : list) {
int pollId = poll.getPollId(); // ν¬νκΈ λ²νΈλ₯Ό κΊΌλΈλ€.
//ν¬ννμ : 1, ν¬νμνμ : 2
int count = dao.isVote(new Voter(pollId, 0, id));
if (count == 1) {
poll.setVote(true);
} else {
poll.setVote(false);
}
pList.add(poll);
}
return pList;
}
@Override
public void makePoll(PollBean pBean) {
// ν¬ν μ£Όμ
PollDto poll = new PollDto(pBean.getId(), pBean.getQuestion(), pBean.getsDate(), pBean.geteDate(), pBean.getItemCount(), 0);
dao.makePoll(poll);
//ν¬ν νλͺ©λ€
String answer[] = pBean.getPollNum();
for (int i = 0; i < pBean.getItemCount(); i++) {
PollSubDto pollSub = new PollSubDto();
pollSub.setAnswer(answer[i]);
dao.makePollSub(pollSub);
}
}
@Override
public PollDto getPoll(PollDto poll) {
return dao.getPoll(poll);
}
@Override
public List<PollSubDto> getPollSubList(PollDto poll) {
return dao.getPollSubList(poll);
}
@Override
public void polling(Voter voter) {
dao.pollingVoter(voter);
dao.pollingPoll(voter);
dao.pollingSub(voter);
}
}
4. Controller μμ±
PollController.java
package bit.com.a.poll;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import bit.com.a.dto.MemberDto;
@Controller
public class PollController {
@Autowired
PollService service;
@RequestMapping(value = "pollList.do", method = { RequestMethod.GET, RequestMethod.POST })
public String pollList(Model model, HttpServletRequest req) {
model.addAttribute("doc_title", "ν¬ν λͺ©λ‘");
String id = ((MemberDto)req.getSession().getAttribute("login")).getId();
List<PollDto> list = service.getPollAllList(id);
model.addAttribute("pLists", list);
return "pollList.tiles";
}
@RequestMapping(value = "pollMake.do", method = { RequestMethod.GET, RequestMethod.POST })
public String pollMake(Model model) {
model.addAttribute("doc_title", "ν¬ν λ§λ€κΈ°");
return "pollMake.tiles";
}
@RequestMapping(value = "pollMakeAf.do", method = { RequestMethod.GET, RequestMethod.POST })
public String pollMakeAf(PollBean pBean) {
service.makePoll(pBean);
return "redirect:/pollList.do";
}
@RequestMapping(value = "pollDetail.do", method = { RequestMethod.GET, RequestMethod.POST })
public String pollDetail(PollDto poll, Model model) {
model.addAttribute("doc_title", "ν¬ν λ΄μ©");
PollDto dto = service.getPoll(poll);
List<PollSubDto> list = service.getPollSubList(poll);
model.addAttribute("poll", dto);
model.addAttribute("pollSubList", list);
return "pollDetail.tiles";
}
@RequestMapping(value = "polling.do", method = { RequestMethod.GET, RequestMethod.POST })
public String polling(Voter voter) {
service.polling(voter);
return "redirect:/pollList.do";
}
@RequestMapping(value = "pollResult.do", method = { RequestMethod.GET, RequestMethod.POST })
public String pollResult(PollDto poll, Model model) {
model.addAttribute("doc_title", "ν¬ν κ²°κ³Ό");
//PollTotal
PollDto dto = service.getPoll(poll);
//ν¬ν νλͺ©λ€
List<PollSubDto> list = service.getPollSubList(poll);
model.addAttribute("poll", dto);
model.addAttribute("pollSubList", list);
return "pollResult.tiles";
}
}
5. λ·°λ¨ μμ±
pollList.jsp (리μ€νΈ νμ΄μ§)

<%@page import="util.PollUtil"%>
<%@page import="bit.com.a.dto.MemberDto"%>
<%@page import="bit.com.a.poll.PollDto"%>
<%@page import="java.util.List"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%
List<PollDto> pLists = (List<PollDto>)request.getAttribute("pLists");
MemberDto mem = (MemberDto)session.getAttribute("login");
%>
<!-- κ΄λ¦¬μ -->
<%
if(mem.getAuth() == 1) {
%>
<table class="list_table" style="width: 95%;">
<col width="50"><col width="50"><col width="300"><col width="100">
<col width="100"><col width="50"><col width="50"><col width="100">
<tr>
<th>λ²νΈ</th>
<th>μμ΄λ</th>
<th>ν¬νμ λͺ©</th>
<th>μμμΌ</th>
<th>μ’
λ£μΌ</th>
<th>보기 κ°μ</th>
<th>ν¬ννμ</th>
<th>λ±λ‘μΌ</th>
</tr>
<%
for(int i = 0; i < pLists.size(); i++) {
PollDto poll = pLists.get(i);
%>
<tr bgcolor="#aabbcc">
<td><%=i+1 %></td>
<td><%=poll.getId() %></td>
<td><%=poll.getQuestion() %></td>
<td><%=poll.getsDate() %></td>
<td><%=poll.geteDate() %></td>
<td><%=poll.getItemCount() %></td>
<td><%=poll.getPollTotal() %></td>
<td><%=poll.getRegDate() %></td>
</tr>
<%
}
%>
</table>
<!-- μ¬μ©μ -->
<%
} else {
%>
<table class="list_table" style="width: 95%;">
<col width="50"><col width="50"><col width="300"><col width="100"><col width="100">
<col width="100"><col width="50"><col width="50"><col width="100">
<tr>
<th>λ²νΈ</th>
<th>μμ΄λ</th>
<th>ν¬νμ λͺ©</th>
<th>κ²°κ³Ό</th>
<th>μμμΌ</th>
<th>μ’
λ£μΌ</th>
<th>보기 κ°μ</th>
<th>ν¬ννμ</th>
<th>λ±λ‘μΌ</th>
</tr>
<%
for(int i = 0; i < pLists.size(); i++) {
PollDto poll = pLists.get(i);
%>
<tr bgcolor="#aabbcc">
<td><%=i+1 %></td>
<td><%=poll.getId() %></td>
<% // ν¬ν μ£Όμ
boolean isS = poll.isVote();
//ν¬ννμ κΈ°κ°λ§λ£
if(isS || PollUtil.isEnd(poll.geteDate())) {
%>
<td>[λ§κ°]<%=poll.getQuestion() %></td>
<%
} else { // ν¬νλ₯Ό μνμΌλ©°, κΈ°κ°μ΄ μμ§ λ§λ£λμ§ μμ
%>
<td>
<a href="pollDetail.do?pollId=<%=poll.getPollId() %>"><%=poll.getQuestion() %></a>
</td>
<%
}
%>
<td>
<%
if(isS || PollUtil.isEnd(poll.geteDate())) {
%>
<a href="pollResult.do?pollId=<%=poll.getPollId() %>">κ²°κ³Ό</a>
<%
} else {
%>
<img alt="" src="image/pen.gif">
<%
}
%>
</td>
<td><%=poll.getsDate() %></td>
<td><%=poll.geteDate() %></td>
<td><%=poll.getItemCount() %></td>
<td><%=poll.getPollTotal() %></td>
<td><%=poll.getRegDate() %></td>
</tr>
<%
}
%>
</table>
<%
}
%>
<%
if(mem.getAuth() == 1) {
%>
<a href="pollMake.do">ν¬ν λ§λ€κΈ°</a>
<%
}
%>
pollMake.jsp (ν¬νκΈ μμ± νμ΄μ§)

<%@page import="java.util.Calendar"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
Calendar cal = Calendar.getInstance();
int tYear = cal.get(Calendar.YEAR);
int tMonth = cal.get(Calendar.MONTH)+1;
int tDay = cal.get(Calendar.DATE);
%>
<form action="pollMakeAf.do" method="post">
<table class="list_table" style="width: 85%">
<colgroup>
<col width="200px"><col width="200px">
</colgroup>
<tr>
<th>μμ΄λ</th>
<td style="text-align: left;">
${login.id}<input type="hidden" name="id" value="${login.id }">
</td>
</tr>
<tr>
<th>ν¬νκΈ°ν</th>
<td style="text-align: left;">
<select name="sYear">
<%
for(int i = tYear; i < tYear + 6; i++) {
%>
<option <%=(tYear+"").equals(i+"")?"selected='selected'":"" %> value="<%=i %>"><%=i %></option>
<%
}
%>
</select>λ
<select name="sMonth">
<%
for(int i = 1; i <= 12; i++) {
%>
<option <%=(tMonth+"").equals(i+"")?"selected='selected'":"" %> value="<%=i %>"><%=i %></option>
<%
}
%>
</select>μ
<select name="sDay">
<%
for(int i = 1; i <= cal.getActualMaximum(Calendar.DAY_OF_MONTH); i++) {
%>
<option <%=(tDay+"").equals(i+"")?"selected='selected'":"" %> value="<%=i %>"><%=i %></option>
<%
}
%>
</select>μΌ
~
<select name="eYear">
<%
for(int i = tYear; i < tYear + 6; i++) {
%>
<option <%=(tYear+"").equals(i+"")?"selected='selected'":"" %> value="<%=i %>"><%=i %></option>
<%
}
%>
</select>λ
<select name="eMonth">
<%
for(int i = 1; i <= 12; i++) {
%>
<option <%=(tMonth+"").equals(i+"")?"selected='selected'":"" %> value="<%=i %>"><%=i %></option>
<%
}
%>
</select>μ
<select name="eDay">
<%
for(int i = 1; i <= cal.getActualMaximum(Calendar.DAY_OF_MONTH); i++) {
%>
<option <%=(tDay+"").equals(i+"")?"selected='selected'":"" %> value="<%=i %>"><%=i %></option>
<%
}
%>
</select>μΌ
</td>
</tr>
<tr>
<th>ν¬νλ΄μ©</th>
<td style="text-align: left;">
<textarea rows="10" cols="50" name="question"></textarea>
</td>
</tr>
<tr>
<th>ν¬ν λ¬Ένμ</th>
<td style="text-align: left;">
<select name="itemCount" onchange="pollChange(this)">
<%
for(int i = 2; i <= 20; i++) {
%>
<option <%= (4+"").equals(i+"")? "selected='selected'":"" %> value="<%=i %>" ><%=i %></option>
<%
}
%>
</select>
</td>
</tr>
<tr>
<th>ν¬ν μμΈ λ¬Έν</th>
<td style="text-align: left;">
<%
for(int i = 1; i <=20; i++) {
%>
<div id='poll<%=i %>'>
<%=(i+"") %>λ²:<input type="text" name="poll<%=i %>" size="60">
</div>
<%
}
%>
</td>
</tr>
<tr>
<td colspan="2">
<input type="submit" value="ν¬νλ§λ€κΈ°">
</td>
</tr>
</table>
</form>
<script>
$(document).ready(function() {
/* νλͺ©λ€ μ΄κΈ°ν */
for(i = 5; i <= 20; i++) {
$('#poll'+i).hide();
}
});
function pollChange(sel) {
let val = sel.options[sel.selectedIndex].value; // selected μ ννκ° λ°ν
console.log(val);
for(i = 1; i <= 20; i++) {
$('#poll'+i).val("");
$('#poll'+i).hide();
}
//μ€μ κ°λ§νΌ 보μ¬μ€λ€.
for(i = 1; i <= val; i++) {
$('#poll'+i).show();
}
}
</script>
pollDetail.jsp (ν¬νκΈ μμΈ νμ΄μ§)

<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<form action="polling.do" method="post">
<table class="list_table" style="width: 95%">
<colgroup>
<col width="200px">
<col width="500px">
</colgroup>
<tr>
<th>ν¬νλ²νΈ</th>
<td style="text-align: left;">
<input type="text" name="pollId" value="${poll.pollId }" size="50" readonly="readonly">
</td>
</tr>
<tr>
<th>μμ΄λ</th>
<td style="text-align: left;">
<input type="text" name="id" value="${login.id}" size="50" readonly="readonly">
</td>
</tr>
<tr>
<th>ν¬νκΈ°ν</th>
<td style="text-align: left;">
${poll.sDate} ~ ${poll.eDate}
</td>
</tr>
<tr>
<th>ν¬νλ΄μ©</th>
<td style="text-align: left;">
<textarea rows="10" cols="50" name="question" readonly="readonly">${poll.question}</textarea>
</td>
</tr>
<tr>
<th>보기 κ°μ</th>
<td style="text-align: left;">
${poll.itemCount }
</td>
</tr>
<tr>
<th>보기</th>
<td style="text-align: left;">
<c:forEach items="${pollSubList }" var="pSub" varStatus="i">
${i.count }λ²
<input type="radio" name="pollSubId" ${i.count==1?"checked='checked'":"" } value="${pSub.pollSubId }">
<input type="text" name="answer" size="60" value="${pSub.answer }" readonly="readonly">
<br>
</c:forEach>
</td>
</tr>
<tr align="center">
<td colspan="2">
<input type="submit" value="ν¬ννκΈ°">
</td>
</tr>
</table>
</form>
pollResult.jsp (ν¬ν κ²°κ³Ό νμ΄μ§)
β» νμ΄μ°¨νΈ (www.highcharts.com/) νμ΄ κ·Έλν μ¬μ©
DBλ₯Ό JSON νμμΌλ‘ λ§λ€μ΄ JSμ μ½μ
<%@page import="bit.com.a.poll.PollSubDto"%>
<%@page import="java.util.List"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!-- https://codepen.io/pen/ 'νμ΄μ°¨νΈ' -->
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/modules/exporting.js"></script>
<script src="https://code.highcharts.com/modules/export-data.js"></script>
<script src="https://code.highcharts.com/modules/accessibility.js"></script>
<%
List<PollSubDto> list = (List<PollSubDto>)request.getAttribute("pollSubList");
String jsonData = "[";
for(PollSubDto p : list) {
jsonData += "{name:'" +p.getAnswer()+ "', y:" +p.getaCount()+ "}, ";
}
jsonData = jsonData.substring(0, jsonData.length()-1);
jsonData += "]";
System.out.println(jsonData);
request.setAttribute("jsonData", jsonData);
%>
<table class="list_table" style="width: 95%">
<colgroup>
<col width="200px"><col width="500px">
</colgroup>
<tr>
<th>ν¬νλ²νΈ</th>
<td style="text-align: left;">
<input type="text" value="${poll.pollId }" size="50" readonly="readonly">
</td>
</tr>
<tr>
<th>μμ΄λ</th>
<td style="text-align: left;">
<input type="text" value="${login.id }" size="50" readonly="readonly">
</td>
</tr>
<tr>
<th>ν¬νκΈ°ν</th>
<td style="text-align: left;">
${poll.sDate } ~ ${poll.eDate }
</td>
</tr>
<tr>
<th>ν¬νλ΄μ©</th>
<td style="text-align: left;">
<textarea rows="10" cols="50" readonly="readonly">${poll.question }</textarea>
</td>
</tr>
<tr>
<th>ν¬νκ²°κ³Ό</th>
<td>
<figure class="highcharts-figure">
<div id="container"></div>
</figure>
</td>
</tr>
</table>
<script type="text/javascript">
Highcharts.chart('container', {
chart: {
plotBackgroundColor: null,
plotBorderWidth: null,
plotShadow: false,
type: 'pie'
},
title: {
text: 'ν¬ν κ²°κ³Ό'
},
tooltip: {
pointFormat: '{series.name}: <b>{point.percentage:.1f}%</b>'
},
accessibility: {
point: {
valueSuffix: '%'
}
},
plotOptions: {
pie: {
allowPointSelect: true,
cursor: 'pointer',
dataLabels: {
enabled: true,
format: '<b>{point.name}</b>: {point.percentage:.1f} %'
}
}
},
series: [{
name: 'ν¬νμ¨',
colorByPoint: true,
data: <%=jsonData %>
}]
});
</script>
- Crawling (ν¬λ‘€λ§)
- μΉνμ΄μ§λ₯Ό κ·Έλλ‘ κ°μ Έμ νμν λ°μ΄ν°λ₯Ό μΆμΆν΄ λ΄λ νμ
Jsoupμ νμ©ν ν¬λ‘€λ§
- κΈ°λ³Έ μΈν
1. mvn λ νμ§ν 리μμ jsoup κ²μ
2. Jsoup Java HTML Parserμμ jarνμΌ λ€μ΄λ‘λ
3. lib ν΄λμ μ½μ
- μ¬μ© μμ
CGV 곡μμ¬μ΄νΈμμ μνμ λͺ©, μλ§€μ¨ κ°μ Έμ€κΈ°
Document doc = Jsoup.connect("http://www.cgv.co.kr/movies/").get();
1. μν μ λͺ© κ°μ Έμ€κΈ°
/*
<div class="box-contents">
<a href="/movies/detail-view/?midx=84514">
<strong class="title">λ΄μΌμ κΈ°μ΅</strong>
*/
Elements titles = doc.select("div.box-contents strong.title");
for (int i = 0; i < 7; i++) {
Element title = titles.get(i);
String t = title.text();
System.out.println(t);
}
2. μλ§€μ¨ κ°μ Έμ€κΈ°
/* μλ§€μ¨ */
/*
<div class="score">
<strong class="percent">μλ§€μ¨<span>7.8%</span></strong>
<!-- 2020.05.07 κ°λ΄μ ν리μκ·Έ λ
ΈμΆ, κ°λ΄ν 골λ μκ·Έμ§μ λ
ΈμΆλ³κ²½ (μ μ© λ²μ1~ 3μ)-->
<div class='egg-gage small'>
<span class='egg great'></span>
<span class='percent'>86%</span>
*/
Elements percents = doc.select("div.score strong.percent span");
for (int i = 0; i < 7; i++) {
Element percent = percents.get(i);
String p = percent.text();
System.out.println(p);
}
MovieChart.java
package movie;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
public class MovieChart {
public static List<MovieVo> getCGVData() throws IOException {
/* CGV μ¬μ΄νΈ */
Document doc = Jsoup.connect("http://www.cgv.co.kr/movies/").get();
/* μνμ λͺ© */
/*
<div class="box-contents">
<a href="/movies/detail-view/?midx=84514">
<strong class="title">λ΄μΌμ κΈ°μ΅</strong>
*/
Elements titles = doc.select("div.box-contents strong.title");
/* μλ§€μ¨ */
/*
<div class="score">
<strong class="percent">μλ§€μ¨<span>7.8%</span></strong>
<!-- 2020.05.07 κ°λ΄μ ν리μκ·Έ λ
ΈμΆ, κ°λ΄ν 골λ μκ·Έμ§μ λ
ΈμΆλ³κ²½ (μ μ© λ²μ1~ 3μ)-->
<div class='egg-gage small'>
<span class='egg great'></span>
<span class='percent'>86%</span>
*/
Elements percents = doc.select("div.score strong.percent span");
List<MovieVo> list = new ArrayList<MovieVo>();
for (int i = 0; i < 7; i++) {
Element title = titles.get(i);
String t = title.text();
Element percent = percents.get(i);
String p = percent.text();
// System.out.println(t);
// System.out.println(p);
MovieVo vo = new MovieVo();
double pv = Double.parseDouble(p.replace("%", ""));
vo.setTitle(t);
vo.setPercent(pv);
list.add(vo);
}
return list;
}
}
JUM μ€μκ° κ²μμ΄ ν¬λ‘€λ§
/* JUM μ€μκ° κ²μμ΄ */
Document doc = Jsoup.connect("https://zum.com/").get();
Elements searchs = doc.select("div.issue_keyword_total span.d_keyword");
System.out.println("μ€ μ€μκ° κ²μμ΄");
for (int i = 0; i < 20; i+=2) {
Element search = searchs.get(i);
String s = search.text();
System.out.println((i/2)+1 +" "+s);
}
- 컀μ€ν μ΄λ Έν μ΄μ μ νμ©ν AOP ꡬν
ν μλ‘ aopλ₯Ό νμ©νμ¬ login session μ΄ μλμ§λ₯Ό κ²μ¬ν λ, λͺ¨λ 컨νΈλ‘€λ¬ λ©μλμ μ μ©νκ² λλ©΄ λ‘κ·ΈμΈλ§μ λμ§ μλ λΆμμ¬κ° μκΈ΄λ€. μ΄λ κ² aopλ₯Ό μ μ©νκ³ μΆμ§ μμ λ©μλκ° μλ€λ©΄ 컀μ€ν μ΄λ Έν μ΄μ μ νμ©νλ©΄ λλ€.
1. μ΄λ Έν μ΄μ μμ±
μμμ μ΄λ¦μΌλ‘ 컀μ€ν μ΄λ Έν μ΄μ μ μμ±νλ€.
NoLogging.java
package bit.com.a.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface NoLogging {
}
2. AOP ν¬μΈνΈμ»·μ μ΄λ Έν μ΄μ 쑰건 μΆκ°
bit.com.a.controller νμμ μλ λ©μλμ΄λ©΄μ NoLogging μ΄λ Έν μ΄μ μ΄ λΆμ§ μμ κ²λ§ AOPκ° μ€νλκ² μ‘°κ±΄μ 건λ€.
LogAOP.java
@Around("within(bit.com.a.controller.*)" +
"&& !@annotation(bit.com.a.annotation.NoLogging)")
3. AOPκ° λ°λλμ§ μμ λ©μλ μμ @μ΄λ Έν μ΄μ μΆκ°
μ¬κΈ°μ NoLoggingμ΄λΌλ μ΄λ¦μ μ΄λ Έν μ΄μ μ λ§λ€μλ€. μ΄λ Έν μ΄μ μ μΆκ°νλ©΄ ν΄λΉ λ©μλλ AOPκ° λ°λλμ§ μλλ€.
@NoLogging
@RequestMapping(value = "login.do", method = RequestMethod.GET)
public String login() {
return "login.tiles";
}
- Web Socket (μΉ μμΌ)
- λ νλ‘κ·Έλ¨κ°μ λ©μμ§λ₯Ό κ΅ννκΈ° μν ν΅μ λ°©λ² μ€ νλ
νΉμ§
1. μꡬμ μλ°©ν₯ ν΅μ
ν΄λΌμ΄μΈνΈμ μλ²κ° μλ‘ μν λ λ°μ΄ν°λ₯Ό μ£Όκ³ λ°μ μ μμΌλ©° μ°κ²°μ΄ λμ΄μ§μ§ μκ³ μ§μλλ€.
2. μ€μκ° λ€νΈμνΉ
λΉ λ₯΄κ² λ°μ΄ν°λ₯Ό κ΅ννλ μ€μκ° μ²λ¦¬κ° νμν λ μ¬μ©λλ€.
ꡬν λ°©λ²
1. pom.xmlμ dependency μΆκ°
<!-- μΉ μμΌ -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-websocket</artifactId>
<version>5.3.3</version>
</dependency>
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.json</artifactId>
<version>1.0.4</version>
</dependency>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20190722</version>
</dependency>
<dependency>
<groupId>com.googlecode.json-simple</groupId>
<artifactId>json-simple</artifactId>
<version>1.1.1</version>
</dependency>
2. spring ν΄λ μ websocket-context.xml μμ±
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:websocket="http://www.springframework.org/schema/websocket"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/websocket http://www.springframework.org/schema/websocket/spring-websocket-4.3.xsd">
<websocket:handlers>
<websocket:mapping handler="myHandler" path="/echo.do"/>
<websocket:handshake-interceptors>
<bean class="org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor"/>
</websocket:handshake-interceptors>
</websocket:handlers>
<bean id="myHandler" class="bit.com.a.websocket.WebSocket"/>
</beans>
3. web-xml μμ
<async-supported>true</async-supported> νκ·Έλ μΆκ°
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/spring/servlet-context.xml
/WEB-INF/spring/aop-context.xml
/WEB-INF/spring/file-context.xml
/WEB-INF/spring/websocket-context.xml <!-- μ¬κΈ°μΆκ° -->
</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
<async-supported>true</async-supported> <!-- μ¬κΈ°μΆκ° -->
</servlet>
4. WebSocket.java μμ±
- TextWebSocketHandlerλ₯Ό μμ
- 체ν¬λ κ²λ€ Override ν΄μ€λ€.
package bit.com.a.websocket;
import java.util.Date;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;
public class WebSocket extends TextWebSocketHandler{
private Map<String, WebSocketSession> userMap = new ConcurrentHashMap<String, WebSocketSession>();
public WebSocket() {
System.out.println("EchoHandler μμ±λ¨" + new Date());
}
/* ν΄λΌμ΄μΈνΈμ μ μμ΄ μ±κ³΅νμ λ νΈμΆ */
@Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
System.out.println("μ°κ²°λ¨" + session.getId() + " " + new Date());
userMap.put(session.getId(), session);
}
/* ν΄λΌμ΄μΈνΈμ μ μμ΄ λκ²Όμ λ */
@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
System.out.println("μ°κ²° μ’
λ£" + session.getId() + " " + new Date());
userMap.remove(session.getId());
}
/* λ©μμ§ μ‘μμ (recv & send) */
@Override
protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
// μμ (recv)
System.out.println("λ©μμ§ μμ :" +message.getPayload()+" "+ new Date());
// μ‘μ (send) - λͺ¨λ clientμ μ μ‘νλ€.
for (WebSocketSession s : userMap.values()) {
s.sendMessage(message);
}
}
/* μμΈ λ°μ */
@Override
public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
System.out.println(session.getId() + " μμΈ λ°μ " + new Date());
}
}
5. λ·° & μλ°μ€ν¬λ¦½νΈ μμ±
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<table class="list_table" style="width: 85%">
<colgroup>
<col width="200px"><col width="500px">
</colgroup>
<tr>
<th>μ±ν
λͺ
</th>
<td style="text-align: left;">
<input type="text" id="name">
<input type="button" id="enterBtn" value="μ
μ₯" onclick="connect()">
<input type="button" id="exitBtn" value="λκ°κΈ°" onclick="disconnect()">
</td>
</tr>
<tr>
<th>μμ΄λ</th>
<td style="text-align: left;">
<input type="text" id="id" value="${login.id }" readonly="readonly">
</td>
</tr>
<tr>
<td colspan="2">
<textarea rows="10" cols="70" id="messageArea"></textarea>
</td>
</tr>
<tr>
<td colspan="2">
<input type="text" id="message" size="50">
<input type="button" id="sendBtn" value="μ μ‘" onclick="send()">
</td>
</tr>
</table>
<script>
let wSocket;
// μ μ
function connect() {
if(wSocket != undefined && wSocket.readyState != WebSocket.CLOSED) {
alert('μ΄λ―Έ μ
μ₯νμ
¨μ΅λλ€.');
return;
}
//WebSocket μμ±
wSocket = new WebSocket("ws://192.168.0.231:8090/sample10/echo.do");
wSocket.onopen = onOpen;
wSocket.onmessage = onMessage;
wSocket.close = onClose;
}
// μ μμ μ€λ¨
function disconnect() {
wSocket.close();
location.href = "chating.do";
}
// μ°κ²°μ΄ λμμ λ
function onOpen(evt) {
appendMessage("μ°κ²°λμμ΅λλ€.");
}
//μμ μ΄ λμμ λ
function onMessage(evt) {
let data = evt.data;
if(data.substring(0, 4) == "msg:") {
appendMessage(data.substring(4));
}
}
// λκ²Όμ λ
function onClose() {
appendMessage("μ°κ²°μ΄ λκ²Όμ΅λλ€.");
}
// λ©μμ§ μ‘μ
function send() {
let id = $('#id').val();
let msg = $('#message').val();
wSocket.send("msg:"+id+":"+msg);
$("#message").val("");
}
// μΆκ° λ¬Έμμ΄μ κΈ°μ
function appendMessage(msg) {
//λ©μμ§λ₯Ό μΆκ° νκ³ κ°ν
$("#messageArea").append(msg+"\n");
// μ€ν¬λ‘€μ μλ‘ μ΄λ μν¨λ€
const top = $('#messageArea').prop("scrollHeight");
$("#messageArea").scrollTop(top);
}
</script>
μΉμμΌ μ€μκ° μ±ν ꡬν νλ©΄
μΌμͺ½μ΄ Edge, μ€λ₯Έμͺ½μ΄ ChromeμΌλ‘ μ μνμλ€.
νλ¨ μ½μμ λ€λ₯Έ μΈμ IDκ°μ΄ μΆλ ₯λλ κ²μ νμΈν μ μλ€.
'π» κ°λ° > π TIL (Today I Learned)' μΉ΄ν κ³ λ¦¬μ λ€λ₯Έ κΈ
210422 TIL (D+71 μ€νλ§ File μ λ‘λ, λ€μ΄λ‘λ ꡬν) (0) | 2021.04.22 |
---|---|
ajax νμ© μΊλ¦°λ λ§λ€κΈ° (1) | 2021.04.21 |