ajax 기능을 사용하여 요청과 응답 (jquery 이용)
jquery 홈페이지(https://jquery.com) → download → google CDN → jquery script 복사 → jquery함수에 ajax 메소드 이용해서 사용 가능
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.3/jquery.min.js"></script>
- $.ajax(setting) : AJAX 기능을 사용하여 요청과 응답을 처리하기 위한 메소드
- 매개변수에 AJAX 기능을 구현하기 위한 정보를 Object 객체로 전달
- 매개변수에 전달되는 Object 객체의 요소의 이름은 정해져 있으며 값 또는 함수로 요소값 표현
- $.get() 또는 $.post() 메소드를 사용하여 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); }
- 단축형 $.post(); 형식
- $.post(url[,data][,success][,dataType]) : AJAX 기능을 사용하여 웹프로그램을 POST 방식으로 요청하여 실행결과를 응답받아 처리하는 메소드
$.post("welcome_two.jsp", "name="+name, function(result) { $("#message").html(result); }, "html");

<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!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 기능 구현 가능
/*
$.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);
}
});
*/
$.post("welcome_two.jsp", "name="+name, function(result) {
$("#message").html(result);
}, "html");
});
</script>
</body>
</html>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
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>

<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!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",
//요청 웹프로그램의 응답결과의 문서형식과 dataType 속성값이 맞지 않은 경우 에러(200) 발생
dataType: "xml",
success: function(xmlDoc) {
//요청에 대한 응답결과가 XML 문서인 경우 매개변수에 XMLDocument 객체가 저장되어 제공
//alert(xmlDoc);//[object XMLDocument]
var count=$(xmlDoc).find("book").length;
if(count==0) {
$("#bookList").html("<p>검색된 교재가 하나도 없습니다.</p>");
return;
}
var html="<p>감색된 교재가 "+count+"권 있습니다.<p>";
html+="<ol>";
$(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);
}
});
</script>
</body>
</html>
<?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>

<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!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 문서인 경우 매개변수에 자바스크립트 객체가 저장되어 제공
//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>
<%@page import="java.util.Date"%>
<%@page import="java.text.SimpleDateFormat"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
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(르세라핌)"}
]
}
- 정상적인 아이디가 입력된 경우 ajax 기능 사용시 문제점
- 문제점) 비동기식 통신에 의해 요청에 대한 처리결과를 응답받기 전에 검증이 종료되어 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; }
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!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">
/*
$("#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").onkeyup(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);
}
});
});
*/
$("#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>
회원정보를 전달받아 AJAX_MEMBER 테이블에 삽입하고 삽입행의 갯수를 반환하는 메소드
아이디를 전달받아 AJAX_MEMBER 테이블에 저장된 해당 아이디의 회원정보를 검색하여 반환하는 메소드
이름과 이메일을 전달받아 AJAX_MEMBER 테이블에서 해당 이름과 이메일을 사용하는 회원의 아이디를 검색하여 반환하는 메소드
회원정보(이름과 이메일)을 전달받아 AJAX_MEMBER 테이블에서 해당 이름과 이메일을 사용하는 회원의 아이디를 검색하여 반환하는 메소드 (권장)
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 insertAjaxMember(AjaxMemberDTO ajaxMember) {
Connection con=null;
PreparedStatement pstmt=null;
int rows=0;
try {
con=getConnection();
String sql="insert into ajax_member values(?,?,?,?)";
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("[에러]insertAjaxMember() 메소드의 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 selectAjaxMemberId(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("[에러]selectAjaxMemberId() 메소드의 SQL 오류 = "+e.getMessage());
} finally {
close(con, pstmt, rs);
}
return id;
}
//4. 회원정보(이름과 이메일)을 전달받아 AJAX_MEMBER 테이블에서 해당 이름과 이메일을 사용하는
//회원의 아이디를 검색하여 반환하는 메소드
public String selectAjaxMemberId(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("[에러]selectAjaxMemberId() 메소드의 SQL 오류 = "+e.getMessage());
} finally {
close(con, pstmt, rs);
}
return id;
}
}
사용자로부터 이름과 이메일을 입력받아 해당 이름과 이메일을 사용하는 회원의 아이디를 클라이언트에게 전달하는 JSP 문서
search_id_two.jsp 문서를 AJAX 기능으로 요청하여 처리결과를 XML 문서로 응답받아 아이디가 출력되도록 프로그램 작성

data: "name="+name+"&email="+email,data: {"name":name, "email":email}, → 값을 Object 객체 형식으로 표현하여 전달 가능
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!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>
이름과 이메일을 전달받아 AJAX_MEMBER 테이블에서 해당 이름과 이메일을 사용하는 회원의 아이디를 검색하여 XML 데이타를 응답하는 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"%>
<%
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");
//String id=AjaxMemberDAO.getDAO().selectAjaxMemberId(name, email);
AjaxMemberDTO ajaxMember=new AjaxMemberDTO();
ajaxMember.setName(name);
ajaxMember.setEmail(email);
String id=AjaxMemberDAO.getDAO().selectAjaxMemberId(ajaxMember);
%>
<result>
<% if(id!=null) {//검색된 아이디가 있는 경우 %>
<code>ok</code>
<id><%=id%></id>
<% } else {//검색된 아이디가 없는 경우%>
<code>empty</code>
<% } %>
</result>
create table ajax_comment (num number primary key, writer varchar2(50), content varchar2(500), regdate date);
create sequence ajax_comment_seq;
package xyz.itwill.dto;
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;
}
}
댓글정보를 전달받아 AJAX_COMMENT 테이블에 삽입하고 삽입행의 갯수를 반환하는 메소드
댓글정보를 전달받아 AJAX_COMMENT 테이블에 저장된 해당 댓글정보를 변경하고 변경행의 갯수를 반환하는 메소드
댓글번호를 전달받아 AJAX_COMMENT 테이블에 저장된 해당 댓글번호의 댓글정보를 삭제하고 삭제행의 갯수를 반환하는 메소드
댓글번호를 전달받아 AJAX_COMMENT 테이블에 저장된 해당 댓글번호의 댓글정보를 검색하여 반환하는 메소드
AJAX_COMMENT 테이블에 저장된 모든 댓글정보를 검색하여 반환하는 메소드
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 * 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<>();
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;
}
}
AJAX_COMMENT 테이블의 댓글정보에 대한 삽입, 삭제, 변경 기능을 제공하고 댓글 목록을 검색하여 클라이언트에게 전달하는 JSP 문서
append 출력태그의 마지막 자식태그로 추가하여 출력 / appendto : 기존 태그를 찾아서 마지막 자식으로 추가하는 것

<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!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>
<%-- 댓글등록태그 --%>
<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>
<%-- 댓글목록 출력태그 --%>
<div id="comment_list"></div>
<%-- 댓글변경태그 --%>
<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>
<%-- 댓글삭제태그 --%>
<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();
//comment_list.jsp 문서를 AJAX 기능으로 요청하여 댓글목록을 XML 문서로 응답받아 태그로 출력하는 함수
function displayComment() {
$.ajax({
type: "get",
url: "comment_list.jsp",
dataType: "xml",
success: function(xmlDoc) {
//댓글목록 출력영역에 출력된 기존 댓글목록 삭제 - 초기화
$("#comment_list").children().remove();
var code=$(xmlDoc).find("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+="<button type='button' onclick='modifyCommnet("+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>");
}
},
erorr: function(xhr) {
alert("에러코드 = "+xhr.status);
}
});
}
//[댓글등록] 태그를 클릭한 경우 호출되는 이벤트 처리 함수 등록
// => 입력태그의 입력값(댓글정보)을 반환받아 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",
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);
}
});
});
//댓글변경태그와 댓글삭제태그를 초기화 처리하기 위한 함수
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("");
}
//댓글 출력태그에서 [댓글변경] 태그를 클릭한 경우 호출되는 이벤트 처리 함수
// => comment_get.jsp 문서를 AJAX 기능으로 요청하여 변경할 댓글정보를 XML 문서로 응답받아 처리
function modifyCommnet(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") {
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);
}
});
}
//댓글변경태그에서 [변경] 태그를 클릭한 경우 호출되는 이벤트 처리 함수 등록
// => 댓글변경태그에서 입력태그의 변경값을 반환받아 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);
}
});
});
//댓글변경태그에서 [취소] 태그를 클릭한 경우 호출되는 이벤트 처리 함수 등록
// => 댓글변경태그와 탯글삭제태그를 초기화 처리하기 위한 함수 호출
$("#modify_cancel_btn").click(init);
//댓글 출력태그에서 [댓글삭제] 태그를 클릭한 경우 호출되는 이벤트 처리 함수
function removeComment(num) {
init();
//댓글삭제태그를 보여지도록 처리하고 변경할 댓글 출력태그의 자식태그로 이동
$("#comment_remove").show().appendTo("#comment_"+num);
//댓글삭제태그에서 입력태그에 댓글번호 저장
$("#remove_num").val(num);
}
//댓글삭제태그에서 [삭제] 태그를 클릭한 경우 호출되는 이벤트 처리 함수
// => 댓글삭제태그에서 입력태그의 댓글번호를 반환받아 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},
dateType: "xml",
success: function(xmlDoc) {
var code=$(xmlDoc).find("code").text();
if(code=="success") {
displayComment();//댓글목록 출력
init();
} else {
alert("댓글 삭제 실패");
}
},
error: function(xhr) {
alert("에러코드 = "+xhr.status);
}
});
});
//댓글삭제태그에서 [취소] 태그를 클릭한 경우 호출되는 이벤트 처리 함수
// => 댓글변경태그와 탯글삭제태그를 초기화 처리하기 위한 함수 호출
$("#remove_cancel_btn").click(init);
</script>
</body>
</html>
AJAX_COMMENT 테이블에 저장된 모든 댓글정보를 검색하여 XML 데이타로 응답하는 JSP 문서
JSON 형식으로 값을 전달 시
<?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"%>
<%
List<AjaxCommentDTO> ajaxCommentList=AjaxCommentDAO.getDAO().selectAjaxCommentList();
%>
<result>
<% if(!ajaxCommentList.isEmpty()) {//검색된 댓글이 있는 경우 %>
<code>success</code>
<data><![CDATA[
[
<% for(int i=0;i<ajaxCommentList.size();i++) { %>
<% if(i>0) { %>,<% } %>
{"num":<%=ajaxCommentList.get(i).getNum()%>
<%-- 문제점)검색된 결과값에서 JSON 형식의 데이타로 표현할 수 없는 문자값이 존재하는 경우 에러 발생 --%>
<%-- 해결법)JSON 형식의 데이타로 표현할 수 없는 문자값을 변환하여 사용 --%>
,"writer":"<%=Utility.toJSON(ajaxCommentList.get(i).getWriter())%>"
,"content":"<%=Utility.toJSON(ajaxCommentList.get(i).getContent())%>"
,"regdate":"<%=ajaxCommentList.get(i).getRegdate()%>"}
<% } %>
]
]]></data>
<% } else {//검색된 댓글이 없는 경우 %>
<code>empty</code>
<message><![CDATA[첫번째 댓글을 입력해 주세요.]]></message>
<% } %>
</result>
package xyz.itwill.util;
public class Utility {
public static String toJSON(String source) {
return source.replace("\\", "\\\\").replace("\"", "\\\"").replace("\n", "\\n").replace("\r\n", "\\n");
}
}

<?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"%>
<%
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);
%>
<result>
<% if(rows>0) {//삽입행이 있는 경우 - 댓글 삽입 성공 %>
<code>success</code>
<% } else {//삽입행이 없는 경우 - 댓글 삽입 실패 %>
<code>error</code>
<% } %>
</result>

<?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"%>
<%
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()%>
,"writer":"<%=Utility.toJSON(ajaxComment.getWriter())%>"
,"content":"<%=Utility.toJSON(ajaxComment.getContent())%>"
,"regdate":"<%=ajaxComment.getRegdate()%>"}
]]></data>
<% } else {//검색된 댓글정보가 없는 경우 %>
<code>empty</code>
<% } %>
</result>

<?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"%>
<%
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);
%>
<result>
<% if(rows>0) {//변경행이 있는 경우 - 댓글 변경 성공 %>
<code>success</code>
<% } else {//변경행이 없는 경우 - 댓글 변경 실패 %>
<code>error</code>
<% } %>
</result>

<?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"%>
<%
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);
%>
<result>
<% if(rows>0) {//삭제행이 있는 경우 - 댓글 삭제 성공 %>
<code>success</code>
<% } else {//삭제행이 없는 경우 - 댓글 삭제 실패 %>
<code>error</code>
<% } %>
</result>