반응형
1. 비동기식 통신으로 하는 아이디 중복검사
AJAX엔진에게 요청 VS 프로그램에게 요청
- 디자인 전체 변경 필요하면 - 새 팝업창 만들어 새로운 프로그램에게 요청할 것
- 값만 전달하여 페이지의 일부만 변경 원하면 - AJAX엔진을 이용해 요청할 것
- (단, AJAX는 현재 웹프로그램과 같은 서버의 웹프로그램만 요청 가능하고,
- 다른 서버에 존재하는 웹프로그램 요청 처리 불가능)
Oracle 데이타베이스 이용할 것임
- JdbcDAO.java + context.xml + ojdbc.jar 빌드처리
1) AJAX_MEMBER 테이블
CREATE TABLE AJAX_MEMBER (
ID VARCHAR2(20) PRIMARY KEY,
PASSWD VARCHAR2(50),
NAME VARCHAR2(50),
EMAIL VARCHAR2(100)
);
2) AjaxMemberDTO.java
package xyz.itwill.dto;
/*
이름 널? 유형
------ -------- -------------
ID NOT NULL VARCHAR2(20)
PASSWD VARCHAR2(50)
NAME VARCHAR2(50)
EMAIL VARCHAR2(100)
*/
public class AjaxMemberDTO {
private String id;
private String passwd;
private String name;
private String email;
public AjaxMemberDTO() {
// TODO Auto-generated constructor stub
}
public String getId() {return id;}
public void setId(String id) {this.id = id;}
public String getPasswd() {return passwd;}
public void setPasswd(String passwd) {this.passwd = passwd;}
public String getName() {return name; }
public void setName(String name) {this.name = name; }
public String getEmail() {return email; }
public void setEmail(String email) {this.email = email;}
}
3) AjaxMemberDAO.java
package xyz.itwill.dao;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import xyz.itwill.dto.AjaxMemberDTO;
public class AjaxMemberDAO extends JdbcDAO{
private static AjaxMemberDAO _dao;
private AjaxMemberDAO() {
// TODO Auto-generated constructor stub
}
static { _dao=new AjaxMemberDAO(); }
public static AjaxMemberDAO getDAO() {
return _dao;
}
//1.
//회원정보를 전달받아 AJAX_MEMBER 테이블에 삽입하고 삽입행의 갯수를 반환하는 메소드
public int insertAjaxMemeber(AjaxMemberDTO ajaxMember) {
Connection con=null;
PreparedStatement pstmt=null;
int rows=0;
try {
con=getConnection();
String sql = "insert into ajax_member vlaues(?,?,?,?)";
pstmt=con.prepareStatement(sql);
pstmt.setString(1, ajaxMember.getId());
pstmt.setString(2, ajaxMember.getPasswd());
pstmt.setString(3, ajaxMember.getName());
pstmt.setString(4, ajaxMember.getEmail());
rows=pstmt.executeUpdate();
}catch (SQLException e) {
System.out.println("[에러] insertAjaxMemeber() 메소드의 SQL 오류 = "+e.getMessage());
}finally {
close(con, pstmt);
}
return rows;
}
//2.
//아이디를 전달받아 AJAX_MEMBER 테이블에 저장된 해당 아이디의 회원정보를 검색하여 반환하는 메소드
public AjaxMemberDTO selectAjaxMember(String id) {
Connection con=null;
PreparedStatement pstmt=null;
ResultSet rs=null;
AjaxMemberDTO ajaxMember=null;
try {
con=getConnection();
String sql = "select * from ajax_member where id= ?";
pstmt=con.prepareStatement(sql);
pstmt.setString(1, id);
rs=pstmt.executeQuery();
if(rs.next()) {
ajaxMember = new AjaxMemberDTO();
ajaxMember.setId(rs.getString("id"));
ajaxMember.setPasswd(rs.getString("passwd"));
ajaxMember.setName(rs.getString("name"));
ajaxMember.setEmail(rs.getString("email"));
}
}catch (SQLException e) {
System.out.println("[에러] selectAjaxMember() 메소드의 SQL 오류 = "+e.getMessage());
}finally {
close(con, pstmt,rs);
}
return ajaxMember;
}
//3.
//이름과 이메일을 전달받아 AJAX_MEMBER 테이블에서 해당 이름과 이메일을 사용하는 회원의 아이디를
//검색하여 반환하는 메소드
public String selectMemberId(String name, String email) {
Connection con=null;
PreparedStatement pstmt=null;
ResultSet rs=null;
String id=null;
try {
con=getConnection();
String sql = "select id from ajax_member where name=? and email=?";
pstmt=con.prepareStatement(sql);
pstmt.setString(1, name);
pstmt.setString(2, email);
rs=pstmt.executeQuery();
if(rs.next()) {
//id = rs.getString("id");
id = rs.getString(1);
}
}catch (SQLException e) {
System.out.println("[에러] selectMemberId() 메소드의 SQL 오류 = "+e.getMessage());
}finally {
close(con, pstmt,rs);
}
return id;
}
//4.
//회원정보(이름과 이메일)을 전달받아 AJAX_MEMBER 테이블에서 해당 이름과 이메일을 사용하는 회원의 아이디를
//검색하여 반환하는 메소드
public String selectMemberId(AjaxMemberDTO ajaxMember) {
Connection con=null;
PreparedStatement pstmt=null;
ResultSet rs=null;
String id=null;
try {
con=getConnection();
String sql = "select id from ajax_member where name=? and email=?";
pstmt=con.prepareStatement(sql);
pstmt.setString(1, ajaxMember.getName());
pstmt.setString(2, ajaxMember.getEmail());
rs=pstmt.executeQuery();
if(rs.next()) {
//id = rs.getString("id");
id = rs.getString(1);
}
}catch (SQLException e) {
System.out.println("[에러] selectMemberId() 메소드의 SQL 오류 = "+e.getMessage());
}finally {
close(con, pstmt,rs);
}
return id;
}
}
4) member_join_input.jsp - 요청
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
//<%-- 회원정보를 입력받기 위한 JSP 문서 --%>
//<%-- => [회원가입] 태그를 클릭한 경우 form 태그를 이용하여 회원정보 삽입페이지(member_join_action.jsp)을
//POST 방식으로 요청하여 이동 - 사용자 입력값(회원정보) 전달 --%>
//<%-- => 회원정보 삽입페이지 요청 전 사용자 입력값에 대한 검증
// - 입력검증, 형식검증, 중복검증(AJAX) 등 --%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>AJAX</title>
<script type="text/javascript" src="<%=request.getContextPath()%>/js/ajax.js"></script>
<style type="text/css">
.title { width: 100px; padding-right: 10px; text-align: center; font-weight: bold; }
.input { width: 200px; }
.message { width: 500px; color: red; }
.msg { display: none; }
#btn { text-align: center; }
</style>
</head>
<body>
<h1>회원가입</h1>
<hr>
<form action="member_join_action.jsp" method="post" id="joinForm">
<table>
<tr>
<td class="title">아이디</td>
<td class="input"><input type="text" name="id" id="id"></td>
<td class="message">
<span id="idNullMsg" class="msg idMsg">아이디를 입력해 주세요.</span>
<span id="idValidMsg" class="msg idMsg">아이디를 형식에 맞게 입력해 주세요.</span>
<span id="idDuplMsg" class="msg idMsg">이미 사용중인 아이디입니다.</span>
</td>
</tr>
<tr>
<td class="title">비밀번호</td>
<td class="input"><input type="password" name="passwd" id="passwd"></td>
<td class="message">
<span id="passwdNullMsg" class="msg">비밀번호를 입력해 주세요.</span>
<span id="passwdValidMsg" class="msg">비밀번호를 형식에 맞게 입력해 주세요.</span>
</td>
</tr>
<tr>
<td class="title">이름</td>
<td class="input"><input type="text" name="name" id="name"></td>
<td class="message">
<span id="nameNullMsg" class="msg">이름을 입력해 주세요.</span>
<span id="nameValidMsg" class="msg">이름을 형식에 맞게 입력해 주세요.</span>
</td>
</tr>
<tr>
<td class="title">이메일</td>
<td class="input"><input type="text" name="email" id="email"></td>
<td class="message">
<span id="emailNullMsg" class="msg">이메일을 입력해 주세요.</span>
<span id="emailValidMsg" class="msg">이메일을 형식에 맞게 입력해 주세요.</span>
</td>
</tr>
<tr>
<td colspan="2" id="btn"><button type="submit">회원가입</button></td>
</tr>
</table>
</form>
<script type="text/javascript">
//1.
document.getElementById("id").focus();
//2.
document.getElementById("joinForm").onsubmit=function() {
//모든 메세지 관련 엘리먼트를 미배치
var msgList=document.querySelectorAll(".msg");
for(i=0;i<msgList.length;i++) {
msgList.item(i).style.display="none";
}
//입력검증 & 형식검증 & 중복검증
// => 중복검증은 따로실행할 것이고, 검증 실패 시 false를 저장해서 메세지를 출력하고 submit 이벤트 실행 취소되도록 만듦
// => false : 검증 실패(Submit 이벤트 취소), true : 검증 성공
var validResult=true; //입력값 검증 결과를 저장하기 위한 변수
var id=document.getElementById("id").value;
var idReg=/^[a-zA-Z]\\\\w{5,19}$/g;
if(id=="") {
document.getElementById("idNullMsg").style.display="block";
validResult=false;
} else if(!idReg.test(id)) {
document.getElementById("idValidMsg").style.display="block";
validResult=false;
} else if(!idCheckResult) { //아이디가 중복된 경우 (중복검증)
document.getElementById("idDuplMsg").style.display="block";
validResult=false;
}
var passwd=document.getElementById("passwd").value;
var passwdReg=/^(?=.*[a-zA-Z])(?=.*[0-9])(?=.*[~!@#$%^&*_-]).{6,20}$/g;
if(passwd=="") {
document.getElementById("passwdNullMsg").style.display="block";
validResult=false;
} else if(!passwdReg.test(passwd)) {
document.getElementById("passwdValidMsg").style.display="block";
validResult=false;
}
var name=document.getElementById("name").value;
var nameReg=/^[가-힣]{2,10}$/g;
if(name=="") {
document.getElementById("nameNullMsg").style.display="block";
validResult=false;
} else if(!nameReg.test(name)) {
document.getElementById("nameValidMsg").style.display="block";
validResult=false;
}
var email=document.getElementById("email").value;
var emailReg=/^([a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+(\\\\.[-a-zA-Z0-9]+)+)*$/g;
if(email=="") {
document.getElementById("emailNullMsg").style.display="block";
validResult=false;
} else if(!emailReg.test(email)) {
document.getElementById("emailValidMsg").style.display="block";
validResult=false;
}
return validResult;
}
//3. 아이디 중복검증
//아이디 중복 검증에 대한 결과값을 저장하기 위한 전역변수 선언
//=> false: 아이디 사용 불가능, true: 아이디 사용 가능
var idCheckResult = false;
//아이디 입력태그에서 키보드를 누른 경우 호출되는 이벤트 처리 함수 등록
//document.getElementById("id").onblur= function() { //네이버처럼 만들라면?
document.getElementById("id").onkeyup= function() {
//alert("Keyup Event");
idCheckResult = false;
var id = document.getElementById("id").value;
if(id.length<6) return; //아이디가 6글자 미만은 중복검사 미실행
//사용자로부터 입력받은 아이디의 중복검사를 위한 웹프로그램을 AJAX 기능을 이용하여
//요청하고 응답결과를 XML 문서로 응답받아 처리
//=> [GET 방식의 요청] : 전달값 2개 미만 , 한글없음, 검색 이용(select)
new xyz.itwill.Ajax("get", "member_id_check.jsp", "id="+id, function(xhr) {
if(xhr.readyState==4){
if(xhr.status==200){
var xmlDoc = xhr.responseXML;
var code = xmlDoc.getElementsByTagName("code").item(0).firstChild.nodeValue;
//네이버처럼 만들라면?
//document.getElementById("idDuplMsg").style.display="block";
//아이디가 중복되지 않는 경우
if(code=="possible") idCheckResult = true;
}else{
alert("에러코드 = "+xhr.status);
}
}
})
}
</script>
</body>
</html>
5) member_id_check.jsp - 응답
<?xml version="1.0" encoding="utf-8"?>
<%@page import="xyz.itwill.dto.AjaxMemberDTO"%>
<%@page import="xyz.itwill.dao.AjaxMemberDAO"%>
<%@ page language="java" contentType="text/xml; charset=UTF-8"
pageEncoding="UTF-8"%>
//<%-- 아이디를 전달받아 AJAX_MEMBER 테이블에 저장된 기존 회원의 아이디와 비교하여
// 아이디 중복검사 결과값을 XML 데이타로 응답하는 JSP 문서 --%>
<%
//전달값을 반환받아 저장
String id = request.getParameter("id");
//비정상적인 요청에 대한 처리 - 전달값이 없는 경우
if(id==null || id.equals("")){
response.sendError(HttpServletResponse.SC_BAD_REQUEST);
return;
}
//아이디를 전달받아 AJAX_MEMBER 테이블에 저장된 해당 아이디의 회원정보를 검색하여 반환하는
//DAO 클래스의 메소드 호출
//=> 반환값 :
//=> null(회원정보 미검색) - 아이디 사용 가능
//=> AjaxMemberDTO객체(회원정보 검색) - 아이디 사용 불가능
AjaxMemberDTO ajaxMember = AjaxMemberDAO.getDAO().selectAjaxMember(id);
%>
<result>
<%if(ajaxMember==null){//검색된 회원정보가 없는 경우 - 아이디 사용 가능 %>
<code>possible</code>
<%}else {//검색된 회원정보가 있는 경우 - 아이디 사용 불가능 %>
<code>impossible</code>
<%} %>
</result>
6) member_join_action.jsp
<%@page import="xyz.itwill.dao.AjaxMemberDAO"%>
<%@page import="xyz.itwill.dto.AjaxMemberDTO"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
//<%-- 회원정보를 전달받아 AJAX_MEMBER 테이블에 삽입하고
//회원가입 출력페이지(member_join_result.jsp)로
//이동하기 위한 URL 주소를 클라이언트에게 전달하는 JSP 문서 --%>
<%
if(request.getMethod().equals("GET")){
response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
return;
}
request.setCharacterEncoding("utf-8");
String id = request.getParameter("id");
String passwd = request.getParameter("passwd");
String name = request.getParameter("name");
String email = request.getParameter("email");
AjaxMemberDTO ajaxMember = new AjaxMemberDTO();
ajaxMember.setId(id);
ajaxMember.setPasswd(passwd);
ajaxMember.setName(name);
ajaxMember.setEmail(email);
AjaxMemberDAO.getDAO().insertAjaxMemeber(ajaxMember);
response.sendRedirect("member_join_result.jsp");
%>
7) member_join_result.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
//<%-- 회원가입 메세지를 클라이언트에게 전달하는 JSP 문서 --%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>회원가입 성공</h1>
<hr>
<p>회원가입을 축하합니다.</p>
</body>
</html>

2. 비동기식 통신으로 하는 제시어기능
1) SUGGEST 테이블
create table suggest(word varchar(50) primary key, url varchar2(100));
insert into suggest values('AJAX','<http://www.itwill.xyz/>');
insert into suggest values('AJAX 예제','<http://www.itwill.xyz/>');
insert into suggest values('AJAX 프로그래밍','<http://www.itwill.xyz/>');
insert into suggest values('AJA','<http://www.itwill.xyz/>');
insert into suggest values('자바','<https://www.oracle.com/>');
insert into suggest values('자바교재','<http://www.itwill.xyz/>');
insert into suggest values('자장가','<http://www.itwill.xyz/>');
insert into suggest values('자유','<http://www.itwill.xyz/>');
insert into suggest values('Spring','<https://spring.io/>');
insert into suggest values('Spring Framework','<https://spring.io/>');
insert into suggest values('Servlet','<https://www.servlets.com/>');
insert into suggest values('네이버','<https://www.naver.com/>');
insert into suggest values('다음','<https://www.daum.net/>');
insert into suggest values('구글','<https://www.google.com/>');
commit;
2) SuggestDTO.java
package xyz.itwill.dto;
/*
이름 널? 유형
---- -------- -------------
WORD NOT NULL VARCHAR2(50)
URL VARCHAR2(100)
*/
public class SuggestDTO {
private String word;
private String url;
public SuggestDTO() {
// TODO Auto-generated constructor stub
}
public String getWord() {return word;}
public void setWord(String word) {this.word = word;}
public String getUrl() {return url;}
public void setUrl(String url) {this.url = url;}
}
3) SuggestDAO.java
package xyz.itwill.dao;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import xyz.itwill.dto.SuggestDTO;
public class SuggestDAO extends JdbcDAO{
private static SuggestDAO _dao;
private SuggestDAO() {
// TODO Auto-generated constructor stub
}
static {
_dao=new SuggestDAO();
}
public static SuggestDAO getDAO() {
return _dao;
}
//검색어를 전달받아 SUGGEST 테이블에서 해당 검색어가 포함된 제시어 관련 정보를 모두 검색하여 반환하는 메소드
public List<SuggestDTO> selectSuggestList(String keyword) {
Connection con=null;
PreparedStatement pstmt = null;
ResultSet rs = null;
List<SuggestDTO> suggestList = new ArrayList<SuggestDTO>();
try {
con=getConnection();
//StringBuffer sql;
//sql.append("select rownum,temp.* from (select * from suggest where upper(word) ");
//sql.append("like '%'||upper(?)||'%' order by word) temp where rownum<=10");
String sql="select rownum,temp.* from (select * from suggest where upper(word) "+ "like '%'||upper(?)||'%' order by word) temp where rownum<=10";
pstmt=con.prepareStatement(sql);
pstmt.setString(1, keyword);
rs=pstmt.executeQuery();
while(rs.next()) {
SuggestDTO suggest = new SuggestDTO();
suggest.setWord(rs.getString("word"));
suggest.setUrl(rs.getString("url"));
suggestList.add(suggest);
}
}catch (SQLException e) {
System.out.println("[에러] selectSuggestList() 메소드의 SQL 오류 = "+e.getMessage());
}finally {
close(con, pstmt,rs);
}
return suggestList;
}
}
4) suggest_one.jsp - 요청
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
//<%-- 검색어를 입력받아 검색어가 포함된 제시어를 클라이언트에게 전달하는 JSP 문서 --%>
//<%-- => 검색어가 입력될 경우 suggest_two.jsp 문서를 AJAX 기능으로 요청하여 검색어가 포함된
//제시어 관련 정보를 XML 문서로 응답받아 출력되도록 처리 --%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>AJAX</title>
<script type="text/javascript" src="<%=request.getContextPath()%>/js/ajax.js"></script>
<style type="text/css">
#keyword{ /*제시어 출력 태그는 다른 태그 위에 출력되어야 하므로 반드시 position: absolute or relative로 변경 */
position: absolute;
top:100px;
left:10px;
width: 300px;
font-size: 16px;
}
#suggest{
position: absolute;
top:120px;
left: 10px;
width: 300px;
border: 1px solid black;
cursor: pointer;
font-size: 16px;
z-index: 999; /* 다른 태그들 보다 가장 맨 위쪽으로 배치될 수 있도록 큰 값 부여 */
background: rgba(255,255,255);
display: none;
}
#choice{
position: absolute;
top:150px;
left: 10px;
}
</style>
</head>
<body>
<h1>제시어 기능</h1>
<hr />
<div>
<!--<%--검색어를 입력받기 위한 태그 --%>-->
<input type="text" id="keyword">
<!--<%--제시어를 제공받아 출력하기 위한 태그 --%>-->
<div id="suggest">
<div id="suggestList">
Java <br>
Java 교재<br>
Java 책<br>
</div>
</div>
<!--<%--선택된 제시어 관련 정보를 출력하기 위한 태그 --%>-->
<div id="choice"></div>
</div>
<script type="text/javascript">
document.getElementById("keyword").focus();
//키보드를 눌렀을 때 실행되는 이벤트 처리 함수 등록
document.getElementById("keyword").onkeyup = function() {
//키보드 입력값 가져오기
var keyword = this.value;
//console.log(keyword);
//키보드 입력값이 없다면 제시어 숨기고 함수 종료
if(keyword==""){
document.getElementById("suggest").style = "display:none;";
return;
}
//키보드 입력값이 있다면 AJAX엔진을 통해 비동기식 [POST]방식으로 요청 (한글이 입력될 수 있으므로 GET 사용 안함)
new xyz.itwill.Ajax("post", "suggest_two.jsp", "keyword="+keyword, function(xhr) {
if(xhr.readyState==4){
if(xhr.status==200){
var xmlDoc = xhr.responseXML;
var code = xmlDoc.getElementsByTagName("code").item(0).firstChild.nodeValue;
if(code=="success"){
var data = xmlDoc.getElementsByTagName("data").item(0).firstChild.nodeValue;
var suggestList = JSON.parse(data);
var html="";
for(i=0; i<suggestList.length; i++) {
html+="<a href=\\\\"javascript:selectSuggest('"+suggestList[i].word+"','"+suggestList[i].url+"');\\\\">"+suggestList[i].word+"</a><br>";
}
document.getElementById("suggestList").innerHTML = html;
document.getElementById("suggest").style="display:block;"
}else {
document.getElementById("suggest").style="display:none;"
}
}else{
alert("에러코드 = "+ xhr.status);
}
}
});
}
function selectSuggest(word, url) {
//alert(word+" = "+url);
document.getElementById("keyword").value=word; //입력태그의 입력값 변경
document.getElementById("choice").innerHTML="<a href="+url+">"+word+"</a>"; //태그변경
document.getElementById("suggest").style="display:none;" //제시어 안보이도록
}
</script>
</body>
</html>
5) suggest_two.jsp - 응답
<?xml version="1.0" encoding="utf-8"?>
<%@page import="xyz.itwill.dao.SuggestDAO"%>
<%@page import="xyz.itwill.dto.SuggestDTO"%>
<%@page import="java.util.List"%>
<%@ page language="java" contentType="text/xml; charset=UTF-8"
pageEncoding="UTF-8"%>
//<%-- 검색어를 전달받아 SUGGEST 테이블에서 검색어가 포함된 제시어 관련 정보를 검색하여 XML 데이타로
//응답하는 JSP 문서 --%>
<%
request.setCharacterEncoding("utf-8");
String keyword=request.getParameter("keyword");
List<SuggestDTO> suggestList=null;
if(keyword!=null && !keyword.equals("")) {//전달값(검색어)이 있는 경우
suggestList=SuggestDAO.getDAO().selectSuggestList(keyword);
}
%>
<result>
<%if(suggestList!=null && !suggestList.isEmpty()){ //검색된 제시어 관련 정보가 있는 경우%>
<code>success</code>
<data><![CDATA[
[
<%for(int i=0; i<suggestList.size(); i++){%>
<%if(i>0) {%>,<%}%> <%--[object] [object] 사이를 구분하기 위해 콤마 필요--%>
{
"word":"<%=suggestList.get(i).getWord()%>",
"url":"<%=suggestList.get(i).getUrl()%>"
}
<%}%>
]
]]></data>
<%} else { //검색된 제시어 관련 정보가 없는 경우%>
<code>empty</code>
<%} %>
</result>

3. jQuery + Ajax (jQuery모듈)
1) welcome_two.jsp 문서를 AJAX 기능으로 요청하여 처리결과를 "HTML 문서"로 응답받아 태그내용을 변경하여 클라이언트에게 전달
자주 사용하는 jQuery 메소드
- find() | filter() | text() | each()
welcome_one.jsp - HTML 문서로 응답
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
//<%-- welcome_two.jsp 문서를 AJAX 기능으로 요청하여 처리결과를 HTML 문서로 응답받아 태그내용을
//변경하여 클라이언트에게 전달하는 JSP 문서 - jQuery 라이브러리의 Ajax 모듈 사용 --%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>AJAX</title>
<script src="<https://ajax.googleapis.com/ajax/libs/jquery/3.6.3/jquery.min.js>"></script>
</head>
<body>
<h1>jQuery AJAX</h1>
<hr>
<label for="name">이름 입력</label>
<input type="text" id="name">
<button type="button" id="btn">전송</button>
<hr>
<div id="message"></div>
<script type="text/javascript">
$("#btn").click(function() {
var name=$("#name").val();
if(name=="") {
$("#message").text("이름을 입력해 주세요.");
return;
}
$("#name").val("");
//$.ajax(setting) : AJAX 기능을 사용하여 요청과 응답을 처리하기 위한 메소드
// => 매개변수에 AJAX 기능을 구현하기 위한 정보를 Object 객체로 전달
// => 매개변수에 전달되는 Object 객체의 요소의 이름은 정해져 있으며,
// => 값 또는 함수로 요소값 표현
//[단축형] $.get() 또는 $.post() 메소드를 사용하여 AJAX 기능 구현 가능
// => Object 객체로 전달이 아닌, 매개변수에 필요한 값이나 함수만 전달하면 됨
//방법1.
//$.ajax()
$.ajax({
type: "post",//요청방식 설정
url: "welcome_two.jsp",//요청 웹프로그램의 URL 주소 설정
data: "name="+name,//요청 웹프로그램에 값을 전달하기 위한 이름과 값을 설정
dataType: "html",//응답결과에 대한 문서형식 설정 - 요소값 : text, html, script, xml, json 등
//정상적인 응답결과(200)를 제공받아 처리하기 위한 함수의 등록 설정
// => 처리함수의 매개변수에는 응답결과가 자동으로 저장되어 제공
success: function(result) {
$("#message").html(result);
},
//비정상적인 응답결과(4XX or 5XX)를 제공받아 처리하기 위한 함수의 등록 설정
// => 처리함수의 매개변수에는 XMLHttpRequest 객체가 자동으로 저장되어 제공
error: function(xhr) {
alert("에러코드 = "+xhr.status);
}
});
//방법2.
//$.post(url[,data][,success][,dataType]) : AJAX 기능을 사용하여
//웹프로그램을 POST 방식으로 요청하여 처리결과를 응답받아 태그를 변경하는 메소드
$.post("welcome_two.jsp", "name="+name, function(result) {
$("#message").html(result);
}, "html");
});
</script>
</body>
</html>
welcome_two.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
//<%-- 이름을 전달받아 환영메세지를 HTML 태그로 전달하는 JSP 문서 --%>
<%
if(request.getMethod().equals("GET")){
response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
return;
}
request.setCharacterEncoding("utf-8");
String name = request.getParameter("name");
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>AJAX</title>
</head>
<body>
<%=name %>님, 환영합니다.
</body>
</html>
2) books_two.jsp 문서를 AJAX 기능으로 요청하여 처리결과를 "XML 문서"로 응답받아 태그내용을 변경하여 클라이언트에게 전달
books_one.jsp - XML 문서로 응답
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
//<%-- books_two.jsp 문서를 AJAX 기능으로 요청하여 처리결과를 XML 문서로 응답받아 태그내용을
//변경하여 클라이언트에게 전달하는 JSP 문서 --%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>AJAX</title>
<script src="<https://ajax.googleapis.com/ajax/libs/jquery/3.6.3/jquery.min.js>"></script>
</head>
<body>
<h1>jQuery AJAX</h1>
<hr>
<div id="bookList"></div>
<script type="text/javascript">
$.ajax({
type: "get",
url: "books_two.jsp",
//전달값이 없으므로 작성안함
//data : "",
//요청 웹프로그램의 응답결과의 문서형식과 dataType 속성값이 맞지 않은 경우
//에러(200) 발생
dataType: "xml",
success: function(xmlDoc) {
>
//요청에 대한 응답결과가 XML 문서인 경우
//매개변수에 XMLDocument 객체가 저장되어 제공
//alert(xmlDoc); //[object XMLDocument]
//xmlDoc객체를 제이쿼리객체로 만들어 제이쿼리 메소드 이용
var count = $(xmlDoc).find("book").length;
if(count==0){
$("#bookList").html("<p>검색된 교재가 하나도 없습니다.");
return;
}
var html = "<p>검색된 교재가"+count+"권 있습니다.</p>";
html += "<ol>"
//제이쿼리는 for문 보다 each()메소드 사용하는 것이 훨씬 좋음
$(xmlDoc).find("book").each(function() {
var title = $(this).find("title").text();
var author = $(this).find("author").text();
html +="<li><b>"+title+"</b>["+author+"]</li>"
});
html += "</ol>"
$("#bookList").html(html);
},
error: function(xhr) {
alert("에러코드 = "+xhr.status); // xml로 받기로 했는데 html로 준다면 에러코드:200
}
});
</script>
</body>
</html>
books_two.jsp
<?xml version="1.0" encoding="utf-8"?>
<%@ page language="java" contentType="text/xml; charset=UTF-8"
pageEncoding="UTF-8"%>
<books>
<book>
<title>Java의 정석</title>
<author>남궁성</author>
</book>
<book>
<title>JSP 웹프로그래밍</title>
<author>오정임</author>
</book>
<book>
<title>스프링 입문</title>
<author>유이치</author>
</book>
</books>
3) songs_two.jsp 문서를 AJAX 기능으로 요청하여 처리결과를 "JSON 문서"로 응답받아 태그내용을 변경하여 클라이언트에게 전달
songs_one.jsp - JSON 문서로 응답
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
//<%-- songs_two.jsp 문서를 AJAX 기능으로 요청하여 처리결과를 JSON 문서로 응답받아 태그내용을
//변경하여 클라이언트에게 전달하는 JSP 문서 --%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>AJAX</title>
<script src="<https://ajax.googleapis.com/ajax/libs/jquery/3.6.3/jquery.min.js>"></script>
</head>
<body>
<h1>jQuery AJAX</h1>
<hr>
<h2>음원차트(<span id="now"></span>현재기준)</h2>
<div id="songList"></div>
<script type="text/javascript">
$.ajax({
type: "get",
url: "songs_two.jsp",
dataType: "json",
success: function(obj) {
//요청에 대한 응답결과가 JSON 문서인 경우,
//매개변수에 "자바스크립트 객체"가 저장되어 제공
//=> jQuery AJAX를 이용하면 처리결과가 자동으로
//=> 자바스크립트 객체가 저장되므로 JSON.parse() 호출하지 않아도 됨
//alert(obj);//[Object Object]
$("#now").html(obj.now);
var html="<ol>";
$(obj.songs).each(function() {
html += "<li><b>"+this.title+"</b>["+this.singer+"</li>";
})
html += "</ol>";
$("#songList").html(html);
},
error: function(xhr) {
alert("에러코드 = "+xhr.status);
}
});
</script>
</body>
</html>
songs_two.jsp
<%@page import="java.text.SimpleDateFormat"%>
<%@page import="java.util.Date"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
//<%-- 음원차트를 JSON 형식의 데이타로 전달하는 JSP 문서 --%>
//<%-- 현재 날짜와 시간 및 음원차트를 JSON 형식의 데이타로 전달하는 JSP 문서 --%>
<%
String now = new SimpleDateFormat("yyyy년 MM월 dd일 HH시").format(new Date());
%>
{
"now":"<%=now %>",
"songs":[
{"title":"Ditto","singer":"NewJeans"},
{"title":"OMG","singer":"NewJeans"},
{"title":"Hype boy","singer":"NewJeans"},
{"title":"사건의 지평선","singer":"윤하 (YOUNHA)"},
{"title":"ANTIFRAGILE","singer":"LE SSERAFIM (르세라핌)"}
]
}

4. 비동기식 통신으로 하는 아이디 중복검사
1) member_join_input.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
//<%-- 회원정보를 입력받기 위한 JSP 문서 --%>
//<%-- => [회원가입] 태그를 클릭한 경우 form 태그를 이용하여 회원정보 삽입페이지(member_join_action.jsp)을 POST 방식으로 요청하여 이동 - 사용자 입력값(회원정보) 전달 --%>
//<%-- => 회원정보 삽입페이지 요청 전 사용자 입력값에 대한 검증 - 입력검증, 형식검증, 중복검증(AJAX) 등 --%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>AJAX</title>
<script src="<https://ajax.googleapis.com/ajax/libs/jquery/3.6.3/jquery.min.js>"></script>
<style type="text/css">
.title { width: 100px; padding-right: 10px; text-align: center; font-weight: bold; }
.input { width: 200px;}
.message { width: 500px; color: red;}
.msg { display: none;}
#btn { text-align: center;}
</style>
</head>
<body>
<h1>회원가입</h1>
<hr>
<form action="member_join_action.jsp" method="post" id="joinForm">
<table>
<tr>
<td class="title">아이디</td>
<td class="input"><input type="text" name="id" id="id"></td>
<td class="message">
<span id="idNullMsg" class="msg idMsg">아이디를 입력해 주세요.</span>
<span id="idValidMsg" class="msg idMsg">아이디를 형식에 맞게 입력해 주세요.</span>
<span id="idDuplMsg" class="msg idMsg">이미 사용중인 아이디입니다.</span>
</td>
</tr>
<tr>
<td class="title">비밀번호</td>
<td class="input"><input type="password" name="passwd" id="passwd"></td>
<td class="message">
<span id="passwdNullMsg" class="msg">비밀번호를 입력해 주세요.</span>
<span id="passwdValidMsg" class="msg">비밀번호를 형식에 맞게 입력해 주세요.</span>
</td>
</tr>
<tr>
<td class="title">이름</td>
<td class="input"><input type="text" name="name" id="name"></td>
<td class="message">
<span id="nameNullMsg" class="msg">이름을 입력해 주세요.</span>
<span id="nameValidMsg" class="msg">이름을 형식에 맞게 입력해 주세요.</span>
</td>
</tr>
<tr>
<td class="title">이메일</td>
<td class="input"><input type="text" name="email" id="email"></td>
<td class="message">
<span id="emailNullMsg" class="msg">이메일을 입력해 주세요.</span>
<span id="emailValidMsg" class="msg">이메일을 형식에 맞게 입력해 주세요.</span>
</td>
</tr>
<tr>
<td colspan="2" id="btn"><button type="submit">회원가입</button></td>
</tr>
</table>
</form>
<script type="text/javascript">
//방법1.
/*
$("#id").focus();
$("#joinForm").submit(function() {
//모든 메세지 관련 엘리먼트를 미배치
$(".msg").hide();
//입력값 검증 결과를 저장하기 위한 변수
// => false : 검증 실패(Submit 이벤트 취소), true : 검증 성공
var validResult=true;
var id=$("#id").val();
var idReg=/^[a-zA-Z]\\\\w{5,19}$/g;
if(id=="") {
$("#idNullMsg").show();
validResult=false;
} else if(!idReg.test(id)) {
$("#idValidMsg").show();
validResult=false;
} else if(!idCheckResult) {//아이디가 중복된 경우
$("#idDuplMsg").show();
validResult=false;
}
var passwd=$("#passwd").val();
var passwdReg=/^(?=.*[a-zA-Z])(?=.*[0-9])(?=.*[~!@#$%^&*_-]).{6,20}$/g;
if(passwd=="") {
$("#passwdNullMsg").show();
validResult=false;
} else if(!passwdReg.test(passwd)) {
$("#passwdValidMsg").show();
validResult=false;
}
var name=$("#name").val();
var nameReg=/^[가-힣]{2,10}$/g;
if(name=="") {
$("#nameNullMsg").show();
validResult=false;
} else if(!nameReg.test(name)) {
$("#nameValidMsg").show();
validResult=false;
}
var email=$("#email").val();
var emailReg=/^([a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+(\\\\.[-a-zA-Z0-9]+)+)*$/g;
if(email=="") {
$("#emailNullMsg").show();
validResult=false;
} else if(!emailReg.test(email)) {
$("#emailValidMsg").show();
validResult=false;
}
return validResult;
});
//아이디 중복 검증에 대한 결과값을 저장하기 위한 전역변수 선언
// => false : 아이디 사용 불가능, true : 아이디 사용 가능
var idCheckResult=false;
//아이디 입력태그에서 키보드를 누른 경우 호출되는 이벤트 처리 함수 등록
$("#id").keyup(function() {
idCheckResult=false;
var id=$("#id").val();
if(id.length<6) return;
$.ajax({
type: "get",
url: "member_id_check.jsp",
data: "id="+id,
dataType: "xml",
success: function(xmlDoc) {
var code=$(xmlDoc).find("code").text();
if(code=="possible") {
idCheckResult=true;
}
},
error: function(xhr) {
alert("에러코드 = "+xhr.status);
}
});
});
*/
//방법2.
$("#id").focus();
$("#joinForm").submit(function() {
$(".msg").hide();
var validResult=true;
var id=$("#id").val();
var idReg=/^[a-zA-Z]\\w{5,19}$/g;
if(id=="") {
$("#idNullMsg").show();
validResult=false;
} else if(!idReg.test(id)) {
$("#idValidMsg").show();
validResult=false;
} else {//정상적인 아이디가 입력된 경우
//문제점)비동기식 통신에 의해 요청에 대한 처리결과를 응답받기 전에 검증이 종료되어
//form 태그 실행 가능 - 정상적인 아이디 중복 검사 실행 불가능
//해결법)동기식 통신으로 웹프로그램을 요청하여 응답받아 처리
$.ajax({
type: "get",
url: "member_id_check.jsp",
data: "id="+id,
//async : 동기식 통신과 비동기식 통신을 구분하기 위한 속성
// => false : 동기식 통신, true : 비동기식 통신(기본)
async: false,
dataType: "xml",
success: function(xmlDoc) {
var code=$(xmlDoc).find("code").text();
if(code=="impossible") {//아이디가 중복된 경우
$("#idDuplMsg").show();
validResult=false;
}
},
error: function(xhr) {
alert("에러코드 = "+xhr.status);
}
});
}
var passwd=$("#passwd").val();
var passwdReg=/^(?=.*[a-zA-Z])(?=.*[0-9])(?=.*[~!@#$%^&*_-]).{6,20}$/g;
if(passwd=="") {
$("#passwdNullMsg").show();
validResult=false;
} else if(!passwdReg.test(passwd)) {
$("#passwdValidMsg").show();
validResult=false;
}
var name=$("#name").val();
var nameReg=/^[가-힣]{2,10}$/g;
if(name=="") {
$("#nameNullMsg").show();
validResult=false;
} else if(!nameReg.test(name)) {
$("#nameValidMsg").show();
validResult=false;
}
var email=$("#email").val();
var emailReg=/^([a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+(\\.[-a-zA-Z0-9]+)+)*$/g;
if(email=="") {
$("#emailNullMsg").show();
validResult=false;
} else if(!emailReg.test(email)) {
$("#emailValidMsg").show();
validResult=false;
}
return validResult;
});
</script>
</body>
</html>
2) member_id_check.jsp
- 아이디 중복 검사 확인해주는 프로그램 AJAX로 요청함
- 아이디를 전달받아 AJAX_MEMBER 테이블에 저장된 기존 회원의 아이디와 비교하여 아이디 중복검사 결과값을 XML 데이타로 응답하는 JSP 문서
3) member_join_action.jsp
- 회원정보를 전달받아 AJAX_MEMBER 테이블에 삽입하고 회원가입 출력페이지(member_join_result.jsp)로 이동하기 위한 URL 주소를 클라이언트에게 전달하는 JSP 문서
4) member_join_result.jsp
- 회원가입 메세지를 클라이언트에게 전달하는 JSP 문서

5. search_id_two.jsp 문서를 AJAX 기능으로 요청하여 처리결과를 "XML 문서"로 응답받아 아이디를 출력되도록 프로그램 작성
1) search_id_one.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
//<%-- 사용자로부터 이름과 이메일을 입력받아 해당 이름과 이메일을 사용하는 회원의 아이디를
//클라이언트에게 전달하는 JSP 문서 --%>
//<%-- => search_id_two.jsp 문서를 AJAX 기능으로 요청하여 처리결과를 XML 문서로 응답받아
//아이디를 출력되도록 프로그램 작성 --%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>AJAX</title>
<script src="<https://ajax.googleapis.com/ajax/libs/jquery/3.6.3/jquery.min.js>"></script>
</head>
<body>
<h1>아이디 찾기</h1>
<hr />
<table>
<tr>
<td>이름</td>
<td><input type="text" id="name"></td>
</tr>
<tr>
<td>이메일</td>
<td><input type="text" id="email"></td>
</tr>
<tr>
<td colspan="2"><button type="button" id="btn">아이디 찾기</button></td>
</tr>
</table>
<hr>
<div id="result"><%-- 홍길동님의 아이디는 [abc123]입니다.--%></div>
<script type="text/javascript">
$("#btn").click(function() {
var name = $("#name").val();
if(name==""){
$("#result").html("이름을 입력해주세요.");
$("#name").focus();
return;
}
var email = $("#email").val();
if(email==""){
$("#result").html("이메일을 입력해주세요.");
$("#email").focus();
return;
}
$("#name").val(""); //입력태그 초기화
$("#email").val("");
$.ajax({
type : "post",
url : "search_id_two.jsp",
//data : "name="+name+"&email="+email,
//값을 Object 객체 형식으로 표현하여 전달 가능 - 권장
data : {"name":name,"email":email},
dataType : "xml",
success : function(xmlDoc) {
var code=$(xmlDoc).find("code").text();
if(code=="ok"){
var id=$(xmlDoc).find("id").text();
$("#result").html(name+"님의 아이디는["+id+"] 입니다.")
} else {
$("#result").html(name+"님의 아이디는 존재하지 않습니다.")
}
},
error : function(xhr) {
alert("에러코드 = "+xhr.status);
}
});
})
</script>
</body>
</html>
2) search_id_two.jsp - XML 데이타로 응답
<?xml version="1.0" encoding="utf-8"?>
<%@page import="xyz.itwill.dto.AjaxMemberDTO"%>
<%@page import="xyz.itwill.dao.AjaxMemberDAO"%>
<%@ page language="java" contentType="text/xml; charset=UTF-8"
pageEncoding="UTF-8"%>
//<%-- 이름과 이메일을 전달받아 AJAX_MEMBER 테이블에 저장된 해당 이름과 이메일을 사용하는
//회원의 아이디를 검색하여 XML 데이타로 응답하는 JSP 문서 --%>
<%
if(request.getMethod().equals("GET")){
response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
return;
}
request.setCharacterEncoding("utf-8");
String name = request.getParameter("name");
String email = request.getParameter("email");
//방법1.
//String id = AjaxMemberDAO.getDAO().selectMemberId(name, email);
//방법2.
AjaxMemberDTO ajaxMember = new AjaxMemberDTO();
ajaxMember.setName(name);
ajaxMember.setEmail(email);
String id = AjaxMemberDAO.getDAO().selectMemberId(ajaxMember);
//Spring프레임워크를 공부하면 전달값을 자동으로 받아서 DTO 객체를 필드값으로 가져오기 때문에
//즉, 자동화 처리해줌으로 방법2로 만들자
%>
<result>
<%if(id!=null){//검색된 아이디가 있는 경우%>
<code>ok</code>
<id><%=id %></id>
<%} else {//검색된 아이디가 없는 경우%>
<code>empty</code>
<%} %>
</result>

6. AJAX 기능(비동기식)으로 요청하여 페이지 이동 없이 출력, 삽입, 삭제, 변경하는 프로그램
- 비동기식 요청으로 페이지 새로 고침없이 댓글 출력,삽입, 삭제, 변경
- 클라이언트는 오직 하나의 프로그램 comment_list.jsp만 요청하여 응답받을 것임
- 하지만, 내부적으로는 이벤트가 발생 시 마다 comment_list는 AJAX엔진 요청
- AJAX엔진은 다른 웹프로그램( comment_list | comment_add | comment_get | comment_modify | comment_remove )을 요청
- 각각의 웹프로그램은 처리 결과를 XML로 응답할 것임
- AJAX엔진은 전달받은 XML 데이터들을 이용해 댓글 출력, 삽입, 삭제, 변경할 것임 ( 파싱해 출력한다)
1) AJAX_COMMENT 테이블
create table ajax_comment(
num number primary key,
writer varchar2(50),
content varchar2(500),
regdate date);
2) ajax_comment_seq 시퀀스
create sequence ajax_comment_seq;
3) AjaxCommentDTO.java
package xyz.itwill.dto;
/*
이름 널? 유형
------- -------- -------------
NUM NOT NULL NUMBER
WRITER VARCHAR2(50)
CONTENT VARCHAR2(500)
REGDATE DATE
*/
public class AjaxCommentDTO {
private int num;
private String writer;
private String content;
private String regdate;
public AjaxCommentDTO() {
// TODO Auto-generated constructor stub
}
public int getNum() { return num;}
public void setNum(int num) { this.num = num;}
public String getWriter() { return writer;}
public void setWriter(String writer) { this.writer = writer;}
public String getContent() { return content;}
public void setContent(String content) {this.content = content;}
public String getRegdate() {return regdate;}
public void setRegdate(String regdate) {this.regdate = regdate;}
}
4) AjaxCommentDAO.java
package xyz.itwill.dao;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import xyz.itwill.dto.AjaxCommentDTO;
public class AjaxCommentDAO extends JdbcDAO {
private static AjaxCommentDAO _dao;
private AjaxCommentDAO() {
// TODO Auto-generated constructor stub
}
static {
_dao=new AjaxCommentDAO();
}
public static AjaxCommentDAO getDAO() {
return _dao;
}
//1.
//댓글정보를 전달받아 AJAX_COMMENT 테이블에 삽입하고 삽입행의 갯수를 반환하는 메소드
public int insertAjaxComment(AjaxCommentDTO ajaxComment) {
Connection con=null;
PreparedStatement pstmt=null;
int rows=0;
try {
con=getConnection();
String sql = "insert into ajax_comment values(ajax_comment_seq.nextval,?,?,sysdate)";
pstmt=con.prepareStatement(sql);
pstmt.setString(1, ajaxComment.getWriter());
pstmt.setString(2, ajaxComment.getContent());
rows=pstmt.executeUpdate();
} catch (SQLException e) {
System.out.println("[에러] insertAjaxComment() 메소드의 SQL 오류"+e.getMessage());
} finally {
close(con, pstmt);
}
return rows;
}
//2.
//댓글정보를 전달받아 AJAX_COMMENT 테이블에 저장된 해당 댓글 정보를 변경하고 변경행의 갯수를 반환하는 메소드
public int updateAjaxComment(AjaxCommentDTO ajaxComment) {
Connection con=null;
PreparedStatement pstmt=null;
int rows=0;
try {
con=getConnection();
String sql = "update ajax_comment set writer=?, content=? where num=?";
pstmt=con.prepareStatement(sql);
pstmt.setString(1, ajaxComment.getWriter());
pstmt.setString(2, ajaxComment.getContent());
pstmt.setInt(3, ajaxComment.getNum());
rows=pstmt.executeUpdate();
} catch (SQLException e) {
System.out.println("[에러] updateAjaxComment() 메소드의 SQL 오류"+e.getMessage());
} finally {
close(con, pstmt);
}
return rows;
}
//3.
//댓글번호를 전달받아 AJAX_COMMENT 테이블에 저장된 해당 댓글번호의 댓글정보를 삭제하고 삭제행의 갯수를 반환하는 메소드
public int deleteAjaxComment(int num) {
Connection con=null;
PreparedStatement pstmt=null;
int rows=0;
try {
con=getConnection();
String sql = "delete from ajax_comment where num=?";
pstmt=con.prepareStatement(sql);
pstmt.setInt(1, num);
rows=pstmt.executeUpdate();
} catch (SQLException e) {
System.out.println("[에러] deleteAjaxComment() 메소드의 SQL 오류"+e.getMessage());
} finally {
close(con, pstmt);
}
return rows;
}
//4.
//댓글번호를 전달받아 AJAX_COMMENT 테이블에 저장된 해당 댓글번호의 댓글정보를 검색하여 반환하는 메소드
public AjaxCommentDTO selectAjaxComment(int num) {
Connection con=null;
PreparedStatement pstmt=null;
ResultSet rs=null;
AjaxCommentDTO ajaxComment=null;
try {
con=getConnection();
String sql="select num,writer,content,regdate from ajax_comment where num=?";
pstmt=con.prepareStatement(sql);
pstmt.setInt(1, num);
rs=pstmt.executeQuery();
if(rs.next()) {
ajaxComment=new AjaxCommentDTO();
ajaxComment.setNum(rs.getInt("num"));
ajaxComment.setWriter(rs.getString("writer"));
ajaxComment.setContent(rs.getString("content"));
ajaxComment.setRegdate(rs.getString("regdate"));
}
} catch (SQLException e) {
System.out.println("[에러]selectAjaxComment() 메소드의 SQL 오류 = "+e.getMessage());
} finally {
close(con, pstmt, rs);
}
return ajaxComment;
}
//5.
//AJAX_COMMENT 테이블에 저장된 모든 댓글정보를 검색하여 반환하는 메소드
public List<AjaxCommentDTO> selectAjaxCommentList() {
Connection con=null;
PreparedStatement pstmt=null;
ResultSet rs=null;
List<AjaxCommentDTO> ajaxCommentList=new ArrayList<AjaxCommentDTO>();
try {
con=getConnection();
String sql="select * from ajax_comment order by num desc"; //최신글이 맨 위로 오도록
pstmt=con.prepareStatement(sql);
rs=pstmt.executeQuery();
while(rs.next()) {
AjaxCommentDTO ajaxComment =new AjaxCommentDTO();
ajaxComment.setNum(rs.getInt("num"));
ajaxComment.setWriter(rs.getString("writer"));
ajaxComment.setContent(rs.getString("content"));
ajaxComment.setRegdate(rs.getString("regdate"));
ajaxCommentList.add(ajaxComment);
}
} catch (SQLException e) {
System.out.println("[에러]selectAjaxCommentList() 메소드의 SQL 오류 = "+e.getMessage());
} finally {
close(con, pstmt, rs);
}
return ajaxCommentList;
}
}
5) Utility.java
package xyz.itwill.util;
public class Utility {
//JSON 형식의 데이타를 전달받아 JSON 형식으로 사용 불가능한 문자값을 사용 가능한
//문자값으로 변환하여 반환하는 메소드
public static String toJSON(String source) {
return source.replace("\\\\\\\\", "\\\\\\\\\\\\\\\\").replace("\\\\"", "\\\\\\\\\\\\"")
.replace("\\\\n", "\\\\\\\\n").replace("\\\\r\\\\n", "\\\\\\\\n");
}
}
6) comment.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
//<%-- AJAX_COMMENT 테이블의 댓글정보에 대한 삽입,삭제,변경 기능을 제공하고 댓글 목록을 검색하여
//클라이언트에게 전달하는 JSP 문서 --%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>AJAX</title>
<script src="<https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js>"></script>
<style type="text/css">
h1 {
text-align: center;
}
.comment_table { width: 500px; margin: 0 auto; border: 2px solid #cccccc; border-collapse: collapse; }
.title { width: 100px; padding: 5px 10px; text-align: center; border: 1px solid #cccccc; }
.input { width: 400px; padding: 5px 10px; border: 1px solid #cccccc; }
.btn { text-align: center; border: 1px solid #cccccc; }
#comment_add { margin-bottom: 5px; }
#comment_modify, #comment_remove { margin: 10px; display: none; }
#add_message, #modify_message { width: 500px; margin: 0 auto; margin-bottom: 20px; text-align: center; color: red; }
#remove_message { padding: 3px; text-align: center; border: 1px solid #cccccc; }
.comment { width: 550px; margin: 0 auto; margin-bottom: 5px; padding: 3px; border: 1px solid #cccccc; }
.no_comment { width: 550px; margin: 0 auto; margin-bottom: 5px; border: 2px solid #cccccc; text-align: center; }
</style>
</head>
<body>
<h1>AJAX 댓글</h1>
<hr>
<!--<%-- 1. 댓글 등록 태그 --%>-->
<div id="comment_add">
<table class="comment_table">
<tr>
<td class="title">작성자</td>
<td class="input"><input type="text" id="add_writer"></td>
</tr>
<tr>
<td class="title">댓글내용</td>
<td class="input"><textarea rows="3" cols="50" id="add_content"></textarea></td>
</tr>
<tr>
<td class="btn" colspan="2">
<button type="button" id="add_btn">댓글등록</button>
</td>
</tr>
</table>
<div id="add_message"> </div>
</div>
<!--<%--2. 댓글목록 출력 태그 --%>-->
<div id="comment_list"></div>
<!--<%--3. 댓글 변경 태그 --%>-->
<!--<%-- display: none --%>-->
<div id="comment_modify">
<input type="hidden" id="modify_num" value="">
<table class="comment_table">
<tr>
<td class="title">작성자</td>
<td class="input"><input type="text" id="modify_writer"></td>
</tr>
<tr>
<td class="title">댓글내용</td>
<td class="input"><textarea rows="3" cols="50" id="modify_content"></textarea></td>
</tr>
<tr>
<td class="btn" colspan="2">
<button type="button" id="modify_btn">변경</button>
<button type="button" id="modify_cancel_btn">취소</button>
</td>
</tr>
</table>
<div id="modify_message"> </div>
</div>
<!--<%--4. 댓글 삭제 태그 --%>-->
<!--<%-- display: none --%>-->
<div id="comment_remove">
<input type="hidden" id="remove_num" value="">
<div id="remove_message">
<b>정말로 삭제 하시겠습니까?</b>
<button type="button" id="remove_btn">삭제</button>
<button type="button" id="remove_cancel_btn">취소</button>
</div>
</div>
<script type="text/javascript">
displayComment(); //script가 실행되자마자 바로 실행할 함수
//1.
//comment_list.jsp 문서를 AJAX 기능으로 요청하여 댓글목록을 XML 문서로 응답받아 태그로 출력하는 함수
function displayComment() {
$.ajax({
type : "get", //전달값이 없거나 간단한 방식은 [GET]방식으로 요청
url : "comment_list.jsp",
dataType :"xml",
success : function(xmlDoc) {
//댓글목록 출력영역에 출력된 기존 댓글 목록 삭제 - 초기화
$("#comment_list").children().remove();
var code = $(xmlDoc).find("code").text(); //<code>코드의 text 저장
if(code=="success"){//검색된 댓글이 있는 경우
//data 엘리먼트의 값(댓글목록 - JSON)을 반환받아 자바스크립트 객체로 변환
var commentArray = JSON.parse($(xmlDoc).find("data").text());
$(commentArray).each(function() {
//Array 객체의 요소값(Object 객체 - 댓글정보)을 HTML 태그로 변환
var html = "<div class='comment' id='comment_"+this.num+"'>"
html += "<b>["+this.writer+"]</b><br>"; //작성자
html += this.content.replace(/\\\\n/g,"<br>")+"<br>"; //댓글내용
html += "("+this.regdate+")<br>"; //작성날짜
//이 버튼은 HTML 문서가 읽어들인 후 AJAX 결과를 받아 나중에 만들어진 태그기 때문에
//id 속성으로 이벤트등록 못함
//함수 호출 - 매개변수로 글번호 전달
html += "<button type='button' onclick='modifyComment("+this.num+");'>댓글변경</button>"; //변경버튼
//함수 호출 - 매개변수로 글번호 전달
html += "<button type='button' onclick='removeComment("+this.num+");'>댓글삭제</button>"; //삭제버튼
html += "</div>";
//댓글목록 출력 영역에 댓글정보를 마지막 자식태그로 추가하여 출력
$("#comment_list").append(html);
})
}else {//검색된 댓글이 없는 경우
var message = $(xmlDoc).find("message").text();
$("#comment_list").html("<div class='no_comment'>"+message+"</div>")
}
},
error : function(xhr) {
alert("에러코드 = "+xhr.status);
}
});
}
/2.
//[댓글등록] 태그를 클릭한 경우 호출되는 이벤트 처리 함수 등록
//=> 입력태그의 입력값(댓글정보)을 반환받아 AJAX_COMMENT 테이블에 삽입하는 comment_add.jsp
//문서를 AJAX 기능으로 요청하고 실행 결과를 XML 문서로 응답받아 처리
$("#add_btn").click(function() {
var writer = $("#add_writer").val(); //전달값
if(writer==""){
$("#add_message").html("작성자를 입력해주세요.");
$("#add_writer").focus();
return;
}
var content = $("#add_content").val(); //전달값
if(content==""){
$("#add_message").html("내용을 입력해주세요.");
$("#add_content").focus();
return;
}
//입력태그 및 메세지출력 초기화
$("#add_writer").val("");
$("#add_content").val("");
$("#add_message").html("");
$.ajax({
type:"post", //값이 여러개이며, 한글도 포함이기 때문에 POST로 요청
url: "comment_add.jsp",
data: {"writer":writer,"content":content},
dataType: "xml",
success: function(xmlDoc) {
var code = $(xmlDoc).find("code").text();
if(code=="success"){ //댓글 삽입 성공
displayComment(); //댓글목록출력
}else{ //댓글 삽입 실패
alert("댓글 삽입 실패");
}
},
error: function(xhr) {
alert("에러코드 = "+xhr.status);
}
})
});
//3.
//[댓글변경태그]와 [댓글삭제태그]를 초기화 처리하기 위한 함수
function init() {
//댓글변경태그를 숨기고 document 객체의 자식태그로 이동
$("#comment_modify").hide().appendTo(document.documentElement);
//댓글변경태그에서 입력태그 초기화
$("#modify_num").val("");
$("#modify_writer").val("");
$("#modify_content").val("");
//댓글변경태그에서 메세지 출력태그 초기화
$("#modify_message").html("");
//댓글삭제태그를 숨기고 document 객체의 자식태그로 이동
$("#comment_remove").hide().appendTo(document.documentElement);
//댓글삭제태그에서 입력태그 초기화
$("#remove_num").val("");
}
//4.
//댓글 출력태그에서 [댓글변경] 태그를 클릭한 경우 호출되는 이벤트 처리 함수
//=> comment_get.jsp 문서를 AJAX 기능으로 요청하여 변경할 댓글정보를 XML 문서로 응답받아 처리
function modifyComment(num) {
//alert(num); //글번호 잘 출력됨
init();
//댓글변경태그를 보여지도록 처리하고 + 변경할 댓글출력태그의 자식태그로 이동
$("#comment_modify").show().appendTo("#comment_"+num);
$.ajax({
type:"get",
url: "comment_get.jsp",
data: {"num":num},
dataType: "xml",
success: function(xmlDoc) {
var code = $(xmlDoc).find("code").text();
if(code=="success"){
//data 엘리먼트의 값(댓글 - JSON)을 반환받아 자바스크립트 객체로 변환
var comment = JSON.parse($(xmlDoc).find("data").text());
//댓글변경태그에서 입력태그의 입력값을 검색결과값으로 변경
$("#modify_num").val(comment.num);
$("#modify_writer").val(comment.writer);
$("#modify_content").val(comment.content);
}else{
init();
}
},
error: function(xhr) {
alert("에러코드 = "+xhr.status);
}
})
};
//5.
//댓글변경태그에서 [변경] 태그를 클릭한 경우 호출되는 이벤트 처리 함수 등록
// => 댓글변경태그에서 입력태그의 변경값을 반환받아 AJAX_COMMENT 테이블에 댓글정보를 변경하는
//comment_modify.jsp 문서를 AJAX 기능으로 요청하고 실행 결과를 XML 문서로 응답받아 처리
$("#modify_btn").click(function() {
//입력태그의 변경값을 반환받아 변수에 저장 - 입력값 가져오기
var num = $("#modify_num").val();//댓글번호
var writer = $("#modify_writer").val();//작성자
if(writer=="") {
$("#modify_message").html("작성자를 입력해 주세요.");
$("#modify_writer").focus();
return;
}
var content = $("#modify_content").val();//내용
if(content=="") {
$("#modify_message").html("내용을 입력해 주세요.");
$("#modify_content").focus();
return;
}
$.ajax({
type:"post",
url: "comment_modify.jsp",
data: {"num":num, "writer":writer, "content":content},
dataType: "xml",
success: function(xmlDoc) {
var code = $(xmlDoc).find("code").text();
if(code=="success"){ //댓글 변경 성공
displayComment(); //댓글목록출력
init(); //반드시 초기화!!
}else{ //댓글 변경 실패
alert("댓글 변경 실패");
}
},
error: function(xhr) {
alert("에러코드 = "+xhr.status);
}
})
});
//6.
//댓글변경태그에서 [취소] 태그를 클릭한 경우 호출되는 이벤트 처리 함수 등록
//=> 댓글변경태그와 댓글삭제태그를 초기화 처리하기 위한 함수 호출
$("#modify_cancel_btn").click(init);
//7.
//댓글 출력태그에서 [댓글삭제] 태그를 클릭한 경우 호출되는 이벤트 처리 함수
function removeComment(num) {
init();
//alert(num); //글번호 잘 출력됨
//댓글삭제태그를 보여지도록 처리하고 변경할 댓글 출력태그의 자식태그로 이동
$("#comment_remove").show().appendTo("#comment_"+num);
//댓글삭제태그에서 입력태그에 댓글번호 저장
$("#remove_num").val(num);
}
//8.
//댓글삭제태그에서 [삭제] 태그를 클릭한 경우 호출되는 이벤트 처리 함수
//=> 댓글삭제태그에서 댓글번호를 반환받아 AJAX_COMMENT 테이블에 저장도니 해당 댓글번호의 댓글 정보를 삭제하는
//comment_remove.jsp 문서를 AJAX 기능으로 요청하고 실행결과를 XML 문서로 응답받아 처리
$("#remove_btn").click(function() {
var num = $("#remove_num").val();
$.ajax({
type:"get",
url: "comment_remove.jsp",
data: {"num":num},
dataType: "xml",
success: function(xmlDoc) {
var code = $(xmlDoc).find("code").text();
console.log(code); //success
if(code=="success"){
displayComment();//댓글목록 출력
init();
}else{
alert("댓글 삭제 실패");
}
},
error: function(xhr) {
alert("에러코드 = "+xhr.status);
}
})
});
//9.
//댓글삭제태그에서 [취소] 태그를 클릭한 경우 호출되는 이벤트 처리 함수 등록
//=> 댓글변경태그와 댓글삭제태그를 초기화 처리하기 위한 함수 호출
$("#remove_cancel_btn").click(init);
</script>
</body>
</html>
7) comment_list.jsp - 댓글리스트검색
<?xml version="1.0" encoding="utf-8"?>
<%@page import="xyz.itwill.util.Utility"%>
<%@page import="xyz.itwill.dao.AjaxCommentDAO"%>
<%@page import="xyz.itwill.dto.AjaxCommentDTO"%>
<%@page import="java.util.List"%>
<%@ page language="java" contentType="text/xml; charset=UTF-8"
pageEncoding="UTF-8"%>
//<%-- AJAX_COMMENT 테이블에 저장된 모든 댓글정보를 검색하여
//XML 데이타로 응답하는 JSP 문서 --%>
//댓글리스트검색 | 댓글삽입 | 댓글검색 | 댓글수정 | 댓글삭제를 위해 처리 결과를
//XML 데이타로 응답하는 JSP 문서
<%
List<AjaxCommentDTO> ajaxComment = AjaxCommentDAO.getDAO().selectAjaxCommentList();
%>
<result>
<%if(!ajaxComment.isEmpty()){ //검색된 댓글이 있는 경우%>
<code>success</code>
<data><![CDATA[
[
<%for(int i=0; i<ajaxComment.size(); i++){%>
<%if(i>0){%>,<%}%>
{
"num":<%=ajaxComment.get(i).getNum()%>,
<%-- 문제점) 검색된 결과값에서 JSON 형식의 데이타로 표현할 수 없는 문자값이 존재하는 경우 에러 발생 --%>
<%-- 해결법) JSON 형식의 데이타로 표현할 수 없는 문자값을 변환하여 사용 --%>
"writer" : "<%=Utility.toJSON(ajaxComment.get(i).getWriter())%>",
"content" : "<%=Utility.toJSON(ajaxComment.get(i).getContent())%>",
"regdate" : "<%=Utility.toJSON(ajaxComment.get(i).getRegdate())%>"
}
<%}%>
]
]]></data>
<%} else { //검색된 댓글이 없는 경우%>
<code>empty</code>
<message><![CDATA[첫번째 댓글을 입력해 주세요.]]></message>
<%} %>
</result>
8) comment_add.jsp - 댓글삽입
<?xml version="1.0" encoding="utf-8"?>
<%@page import="xyz.itwill.dao.AjaxCommentDAO"%>
<%@page import="xyz.itwill.dto.AjaxCommentDTO"%>
<%@ page language="java" contentType="text/xml; charset=UTF-8"
pageEncoding="UTF-8"%>
//<%-- 댓글정보(작성자와 댓글내용)을 전달받아 AJAX_COMMENT 테이블에 삽입하고 처리결과를
//XML 데이타로 응답하는 JSP 문서 --%>
<%
if(request.getMethod().equals("GET")) {
response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
return;
}
request.setCharacterEncoding("utf-8");
String writer=request.getParameter("writer");
String content=request.getParameter("content");
AjaxCommentDTO ajaxComment=new AjaxCommentDTO();
ajaxComment.setWriter(writer);
ajaxComment.setContent(content);
int rows=AjaxCommentDAO.getDAO().insertAjaxComment(ajaxComment);
//System.out.println(rows); //0.. 왜?
//DAO 메소드에 반드시 삽입행 업데이트 코드 넣어주기 : rows=pstmt.executeUpdate();
%>
<result>
<% if(rows>0) {//삽입행이 있는 경우 - 댓글 삽입 성공 %>
<code>success</code>
<% } else {//삽입행이 없는 경우 - 댓글 삽입 실패 %>
<code>error</code>
<% } %>
</result>
9) comment_get.jsp - 댓글검색
<?xml version="1.0" encoding="utf-8"?>
<%@page import="xyz.itwill.util.Utility"%>
<%@page import="xyz.itwill.dao.AjaxCommentDAO"%>
<%@page import="xyz.itwill.dto.AjaxCommentDTO"%>
<%@ page language="java" contentType="text/xml; charset=UTF-8"
pageEncoding="UTF-8"%>
//<%-- 댓글번호를 전달받아 AJAX_COMMENT 테이블에 저장된 해당 댓글번호의 댓글정보를 검색하여
//XML 데이타로 응답하는 JSP 문서 --%>
<%
if(request.getParameter("num")==null){
response.sendError(HttpServletResponse.SC_BAD_REQUEST);
return;
}
int num = Integer.parseInt(request.getParameter("num"));
AjaxCommentDTO ajaxComment = AjaxCommentDAO.getDAO().selectAjaxComment(num);
%>
<result>
<%if(ajaxComment!=null){ %>
<code>success</code>
<data><![CDATA[
{
"num":"<%=ajaxComment.getNum()%>",
<%-- Utility클래스가 import 되었는지 반드시 확인!! --%>
"writer":"<%=Utility.toJSON(ajaxComment.getWriter())%>",
"content":"<%=Utility.toJSON(ajaxComment.getContent())%>",
"regdate":"<%=ajaxComment.getRegdate()%>"
}
]]></data>
<%} else{ %>
<code>error</code>
<%} %>
</result>
10) comment_modify.jsp - 댓글수정
<?xml version="1.0" encoding="utf-8"?>
<%@page import="xyz.itwill.dao.AjaxCommentDAO"%>
<%@page import="xyz.itwill.dao.AjaxMemberDAO"%>
<%@page import="xyz.itwill.dto.AjaxCommentDTO"%>
<%@ page language="java" contentType="text/xml; charset=UTF-8"
pageEncoding="UTF-8"%>
//<%-- 댓글정보를 전달받아 AJAX_COMMENT 테이블에 저장도니 해당 댓글정보를 변경하고 처리결과를
//XML 데이타로 응답하는 JSP 문서 --%>
<%
if(request.getMethod().equals("GET")){
response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
return;
}
request.setCharacterEncoding("utf-8");
int num = Integer.parseInt(request.getParameter("num"));
String writer = request.getParameter("writer");
String content = request.getParameter("content");
AjaxCommentDTO ajaxComment = new AjaxCommentDTO();
ajaxComment.setNum(num);
ajaxComment.setWriter(writer);
ajaxComment.setContent(content);
int rows = AjaxCommentDAO.getDAO().updateAjaxComment(ajaxComment);
//System.out.println(rows);
%>
<result>
<% if(rows>0) {//변경행이 있는 경우 - 댓글 변경 성공 %>
<code>success</code>
<% } else {//변경행이 없는 경우 - 댓글 변경 실패 %>
<code>error</code>
<% } %>
</result>
11) comment_remove.jsp - 댓글삭제
<?xml version="1.0" encoding="utf-8"?>
<%@page import="xyz.itwill.dao.AjaxCommentDAO"%>
<%@ page language="java" contentType="text/xml; charset=UTF-8"
pageEncoding="UTF-8"%>
//<%-- 댓글번호를 전달받아 AJAX_COMMENT 테이블에 저장된 해당 댓글번호의 댓글정보를 저장하고
//처리결과를 XML 데이타로 응답하는 JSP 문서 --%>
<%
if(request.getParameter("num")==null){
response.sendError(HttpServletResponse.SC_BAD_REQUEST);
return;
}
int num = Integer.parseInt(request.getParameter("num"));
int rows = AjaxCommentDAO.getDAO().deleteAjaxComment(num);
//System.out.println("num ="+num);
%>
<result>
<%if(rows>0){ //삭제행이 있는 경우 - 댓글 삭제 성공 %>
<code>success</code>
<%} else { //삭제행이 없는 경우 - 댓글 삭제 실패 %>
<code>error</code>
<%} %>
</result>

7. RSS 서비스를 제공하는 웹프로그램(ex.경향신문) 요청
- ex) 경향신문의 RSS
1) rss_reader.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
//<%-- RSS 서비스를 제공하는 웹프로그램을 AJAX 기능으로 요청하여 처리 결과를 응답받아 클라이언트에게 전달하는 JSP 문서 --%>
//<%-- RSS(Really Simple Syndication 또는 RDF Site Summary) : 실시간으로 변경되는 정보를 빠르게 제공하기 위한 웹프로그램 --%>
//<%-- ex) 블로그데이타, 뉴스서비스(ex.경향신문) --%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>AJAX</title>
<script src="<https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js>"></script>
</head>
<body>
<h1>RSS Reader</h1>
<hr />
<div id="display"></div>
<script type="text/javascript">
$.ajax({
type : "get", //전달값 없음
//문제점) 현재 실행중인 웹프로그램과 동일한 서버에 작성된 웹프로그램을 AJAX 기능을 사용하여 요청과 응답 처리 가능하지만,
//다른 서버에 작성된 웹프로그램을 AJAX 기능을 사용하여 요청할 경우 에러(에러코드: 0) 발생
//url : "<https://www.khan.co.kr/rss/rssdata/kh_entertainment.xml>",
//해결법) 다른 서버에 작성된 웹프로그램은 프록시 프로그램을 사용하여 AJAX 기능으로 요청하여 실행 결과를 응답받아 처리 가능
url : "rss_proxy.jsp",
dataType :"xml",
success : function(xmlDoc) {
var channelTitle = $(xmlDoc).find("channel").children("title").text();
console.log(channelTitle);
var html="<h2>"+channelTitle+"</h2>";
html +="<ul>";
$(xmlDoc).find("item").each(function() {
var title = $(this).find("title").text();
var link = $(this).find("link").text();
var date;
if($(this).find("pubDate").length!=0){
date = $(this).find("pubDate").text();
} else {
date = $(this).find("dc\\\\:date").text();
}
html+="<li><a href='"+link+"'>"+title+"["+date+"]</a></li>";
});
html +="</ul>";
$("#display").html(html);
},
error : function(xhr) {
alert("에러코드 = "+xhr.status);
}
});
</script>
</body>
</html>
[프록시] 가상의 웹브라우저를 이용한 프로그램
- 직접적인 접근이 차단되었을 때 우회통로를 만들어서 접근 가능 : 프록시
- ex) 중국은 우회해서 넷플릭스를 본다
가상의 브라우저 위에서 요청과 응답처리를 위한 빌드처리
httpclient & codec & logging 파일 접속
- binary폴더 >> zip파일 다운 >> 압축해제 >> jar파일 빌드 처리
2) rss_proxy.jsp
<%@page import="org.apache.commons.httpclient.methods.GetMethod"%>
<%@page import="org.apache.commons.httpclient.HttpClient"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
//<%-- 가상의 클라이언트(브라우저)를 이용하여 "다른 서버에 작성된 웹프로그램을 요청"하고 실행결과를 응답받아 "그대로" 클라이언트에게 전달하는 JSP 문서 --%>
//<%-- => HttpClient 객체 사용하여 프록시(Proxy) 기능을 제공하는 웹프로그램 작성 --%>
//<%-- HttpClient : 가상의 웹브라우저이고, HttpClient 클래스를 다운로드 받아 빌드 처리해야함 --%>
//<%-- <https://www.apache.org> 사이트에서 필요한 라이브러리 파일을 다운로드 받아 프로젝트에 빌드 처리--%>
//<%-- => commons-httpclient-3.1.jar, commons-codec-1.15.jar, commons-logging-1.2.jar --%>
<%
//1.
//요청 웹프로그램의 URL 주소 저장
String url = "<https://www.khan.co.kr/rss/rssdata/kh_entertainment.xml>";
//2.
//HttpClient객체 생성 - 가상의 브라우저 기능을 제공하기 위한 객체
//=> 주의) org.apache.commons.httpclient.HttpClient로 import하기
HttpClient client = new HttpClient();
//3.
//GetMethod 객체 생성 - 가상의 브라우저를 이용하여 GET 방식으로 웹프로그램을 요청하기 위한 메소드
//PostMethod 객체 : 가상의 브라우저를 이용하여 POST 방식으로 웹프로그램을 요청하기 위한 메소드
GetMethod method = new GetMethod(url);
//4.
try{
//HttpClient.executeMethod(Method method) : 가상의 브라우저를 이용하여 웹프로그램을 요청하는 메소드
// => 요청에 대한 실행결과의 상태코드(Status Code - 응답상태 : int) 반환
int statusCode=client.executeMethod(method);
//프록시 프로그램(rss_proxy.jsp)의 리스폰즈 메세지를 저장하기 위한 객체 초기화
response.reset();
//프록시 프로그램(rss_proxy.jsp)의 출력스트림 초기화
out.clearBuffer();
//프록시 프로그램(rss_proxy.jsp)을 요청한 웹프로그램(클라이언트)에게 반환받은 상태코드 전달
response.setStatus(statusCode);
if(statusCode==HttpServletResponse.SC_OK){//정상적인 실행결과를 응답받은 경우 - 상태코드:200
//Method.getResponseBodyAsString() : 요청에 실행결과를 문자열로 반환하는 메소드
// => ResponseBody를 String으로 가져오는 메소드
// => 실행결과를 반환받아 원하는 문자형태(캐릭터셋)로 변환하여 저장
String result = new String(method.getResponseBodyAsString().getBytes("8859_1"),"utf-8");
//프록시 프로그램(rss_proxy.jsp)을 요청한 웹프로그램(클라이언트)에게 실행결과에 대한 문서형태를 전달
response.setContentType("text/xml; charset=utf-8");
//프록시 프로그램(rss_proxy.jsp)을 요청한 웹프로그램(클라이언트)에게 실행결과를 전달
out.println(result);
}
}finally{
//가상의 브라우저를 이용하여 접속된 서버의 연결 해제
//Method.releaseConnection() : 접속 서버의 연결을 해제하는 메소드
if(method!=null) method.releaseConnection();
}
%>
- 실행 시 출력됨
반응형
'web > javascript' 카테고리의 다른 글
[js - ajax] 15. ajax엔진 1개 vs 다수 | 응답 데이터 XML vs JSON vs XML&JSON (0) | 2024.05.21 |
---|---|
[js - ajax] 14. Asynchronus + Javascript (0) | 2024.05.20 |
[js - jquery] 13. jqeury 이벤트 기능 | 에니메이션 기능 (0) | 2024.05.20 |
[js - jquery] 12. jquery 개념 | 선택자 | each() | css() | attr() | text() | html() | 태그 추가,삭제,이동 (0) | 2024.05.19 |
[js] 11. 자바스크립트 쿠키(Cookie) 사용법 (0) | 2024.05.19 |