컴퓨터/JSP
[JSP/AJAX] AJAX
peridott
2024. 7. 29. 16:51
<%@ 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://code.jquery.com/jquery-3.7.1.min.js"></script>
</head>
<body>
<h1>AJAX개요</h1>
<p>
Asynchronous JavaScript And XML의 약자로<br>
서버로부터 데이터를 가져와 전체 페이지를 새로 고치지 않고 일부만 로드할 수 있게 하는 기법<BR>
* 동기식 / 비동기식<br>
> 동기식(a, form, submit)
<ul>
<li>요청 처리 후 그에 해당하는 응답페이지가 돌아와야만 그 다음 작업 가능</li>
<li>서버에 요청한 결과까지의 시간이 지연되면 무작정 계속 기다려야됨(흰페이지로 보여짐)</li>
<li>전체 페이지를 응답해주기 때문에 기본적으로 페이지가 깜박거림</li>
</ul>
> 비동기식 (ajax)
<ul>
<li>현재 페이지를 그대로 유지하면서 중간중간마다 추가적으로 필요한 요청을 보내 줄 수 있음</li>
<li>요청을 보냈다고 해서 다른 페이지로 넘어가지 않음 (현재 페이지 그대로 유지)</li>
<li>요청 보내놓고 그에 해당 하는 응답 (데이터)이 돌아올때 까지 현재페이지에서 다른 작업을 할 수 있음</li>
<li>페이지가 깜박거리지 않음</li>
</ul>
ex) 실시간 급상승 검색어 로딩, 검색어 자동완성, 아이디 중복체크, 찜하기/해제하기, 추천, 댓글, 무한스크롤링 (페이징 대체) 등등...
<br><br>
* 비동기식의 단점 <br>
- 현재 페이지에 지속적으로 리소스가 쌓임 => 페이지가 느려질 수 있음 <br>
- 에러 발생시 디버깅 어려움 <br>
- 요청 처리 후에 돌아온 응답데이터를 가지고 현재페이지에 새로운 요소를 만들어서 뿌려줘야 함 => dom요소들을 새롭게 만들어내는 구문을 잘익혀둬야됨
<br><br>
* AJAX 구현 방식 => 순수 JavaScript방식 / jQuery방식(코드가 간결하고 사용하기 휘움)
</p>
<pre>
* jQuery방식으로 AJAX통신
$.ajax({
속성명:속성값,
속성명:속성값,
속성명:속성값,
...
});
$.ajax({
url : "요청할 url" (action url),
type : "전송 방식" (get, post방식),
data : "요청시 전달할 값",
success : function(data){
전송에 성공하면 실행될 코드;
},
error:function(){
전송에 실패하면 실행될 코드;
}
})
* 주요속성
- url : 요청할 url(필수속성)
- type|mothod : 요청전송방식(get/post)
- data : 요청시 전달할 값
- success : ajax통신이 성공했을 때 실행할 함수 정의
- error : ajax 통신이 실패했을 때 실행할 함수 정의
- complete : ajax 통신의 성공과 실패에 상관없이 무조건 실행할 함수 정의
* 부수적인속성
- async : 서버와의 비동기 처리 방식 설정 여부(기본값 true:비동기)
- contentType : request의 데이터 인코딩 방식 정의(보내는 측의 데이터 인코딩)
- dataType : 서버에서 response로 오는 데이터의 데이터 형 설정, 값이 없다면 스마트하게 판단함
xml - 트리 형태의 데이터 구조
json - 맵 형식의 데이터 구조(일반적인 데이터 구조)
script - javascript 및 일반 String 형태 데이터
html - html 태그 자체를 return 하는 방식
text - String 데이터
- accept : 파라미터의 타입을 설정 (사용자 특화 된 파라미터 타입 설정 가능)
- beforesend : ajax 요청을 하기 전 실행되는 이벤트 callback 함수 (데이터 가공 및 header 관련 설정)
- cache : 요청 및 결과값을 scope에서 갖고 있지 않도록 하는 것 (기본값 true)
- contents : JQuery에서 response의 데이터를 파싱하는 방식 정의
- context : ajax 메소드 내 모든 영역에서 파싱 방식 정의
- crossDomain : 타 도메인 호출 가능 여부 설정(기본값 false)
- dataFilter : response를 받았을 때 정상적인 값을 return 할 수 있도록 데이터와 데이터 타입 설정
- global : 기본 이벤트 사용 여부(ajaxstart, ajaxstop) (버퍼링 같이 시작과 끝을 나타낼 때, 선처리 작업)
- password : 서버에 접속 권한(비밀번호)이 필요한 경우
- processData : 서버로 보내는 값에 대한 형태 설정 여부(기본 데이터를 원하는 경우 false설정)
- timeout : 서버 요청 시 응답 대기 시간(milisecond)
</pre>
<h1>jQuery 방식을 이용한 AJAX 테스트</h1>
<h3>1. 버튼 클릭시 get방식으로 서버에 요청 및 응답</h3>
입력 : <input id="input1">  <button id="btn1">전송</button>
<br>
응답 : <span id="output1">응답없음</span>
<script>
$(() => {
$("#btn1").click(function() {
$.ajax({
url : "ajax1.do",
data : {input : $("#input1").val()},
type : "get",
success : function(data) {
console.log("ajax통신 성공");
console.log(data);
$("#output1").text(data);
},
error : function() {
console.log("ajax통신 실패");
}
})
})
})
</script>
<form name="idCheck" action="idCheck.me">
<p>
아이디 : <input name="id" required> 
<input type="button" value="ID중복확인" id="btn2">
</p>
<input type="submit" value="회원가입" disabled>
</form>
<!--
<script type="text/javascript">
$(() => {
$("#btn2").click(function() {
const $idInput = $("form input[name=id]");
$.ajax({
url : "idCheck.me",
data : {id : $idInput.val()},
success : function(result) {
console.log(result);
if(result == 'idN') {
alert('이미 사용중이거나 탈퇴한 아이디 입니다.');
$idInput.val('');
$idInput.focus();
} else {
if(confirm("사용가능한 아이디 입니다. 사용하시겠습니까?")) {
$("form :submit").removeAttr("disabled");
$idInput.attr("readonly", true);
} else {
$idInput.focus();
}
}
},
error : function() {
console.log("아이디 중복체크 ajax통신 실패");
}
})
})
})
</script>
-->
<form name="regFrm" action="idCheck.me" id="enrollForm">
<p>아이디 : <input name="id" id="id" required></p>
<div id="checkResult" style="font-size:0.8em; display:none"></div>
<button type="submit" disabled>회원가입</button> 
<button type="reset">초기화</button>
</form>
<script>
$(() => {
const $idInput = $("#id");
$idInput.keyup(function() {
if($idInput.val().length >= 3) {
$.ajax({
url: "idCheck.me",
data : {id : $idInput.val()},
success : function(result) {
console.log(result);
if(result == 'idN') {
$("#checkResult").show();
$("#checkResult").css("color","red").text("중복된 아이디가 존재합니다. 다시 입력하세요");
$("#enrollForm :submit").attr("disabled", true);
} else {
$("#checkResult").show();
$("#checkResult").css("color","green").text("멋진 아이디 입니다.");
$("#enrollForm :submit").attr("disabled", false);
}
},
error : function() {
console.log("아이디 중복체크 ajax 통신 실패");
}
})
} else {
$("#checkResult").hide();
$("#enrollForm :submit").attr("disabled", true);
}
})
})
</script>
<hr>
<h3>2. 버튼 클릭시 post방식으로 서버에 여러개의 데이터 전송 및 응답</h3>
이름 : <input type="text" id="name"><br>
나이 : <input type="number" id="age"><br><br>
<button id="btn3">전송</button><br><br>
<!--
응답 : <label id="output3"></label>
<script type="text/javascript">
$(() => {
$("#btn3").click(function() {
$.ajax({
url : 'ajax2.do',
data : {
name : $("#name").val(),
age : $("#age").val()
},
type : "post",
success : function(result) {
console.log(result)
$("#output3").html(""result);
$("#name").val("");
$("#age").val("");
},
error : function() {
console.log("ajax 통신 실패");
}
})
})
})
</script>
-->
<ul id="output4">
</ul>
<script type="text/javascript">
$(() => {
$("#btn3").click(function() {
$.ajax({
url : 'ajax2.do',
data : {
name : $("#name").val(),
age : $("#age").val()
},
type : "post",
success : function(result) {
console.log(result)
/* JSONArray로 받았을 때
console.log(result[0])
console.log(result[1])
const value = "<li>이름 : " + result[0] + "</li>"
+ "<li>나이 : " + result[1] + "</li>";
*/
// JSONObject로 받았을 때
console.log(result.name);
console.log(result.age);
const value = "<li>이름 : " + result.name + "</li>"
+ "<li>나이 : " + result.age + "</li>";
$("#output4").html(value);
$("#name").val("");
$("#age").val("");
},
error : function() {
console.log("ajax 통신 실패");
}
})
})
})
</script>
<hr>
<h3>3. 서버에 데이터를 전송 후, 조회된 bean 객체를 응답데이터로 반환</h3>
검색하고자하는 회원 ID : <input id="input5">
<button id="btn5">조회</button>
<div id="output5"></div>
<script type="text/javascript">
$(() => {
$("#btn5").click(function() {
$.ajax({
url: "ajax5.do",
data : {id : $("#input5").val()},
success : function(result) {
console.log(result);
// JSONObject로 받았을 때
/*
const value = "<br>********** 검색 결과 **********<br>"
+ "ID : " + result.userId + "<br>"
+ "이름 : " + result.userName + "<br>"
+ "성별 : " + result.gender + "<br>"
+ "EMAIL : " + result.email;
$("#output5").html(value);
*/
// GSON으로 받았을 때
/*
const value = "<br>********** 검색 결과 **********<br>"
+ "ID : " + result.id + "<br>"
+ "이름 : " + result.name + "<br>"
+ "성별 : " + result.gender + "<br>"
+ "EMAIL : " + result.email;
$("#output5").html(value);
*/
},
error : function() {
console.log("ajax 통신 실패");
}
})
})
})
</script>
<hr>
<h3>4. 응답데이터로 조회된 여러 bean객체들이 담겨 있는 ArrayList받기</h3>
<button id="btn6">회원 전체 조회</button><br><br>
<table id="output6" border="1">
<thead>
<tr>
<th>ID</th>
<th>이름</th>
<th>성별</th>
<th>EMAIL</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
<script>
$(() => {
$("#btn6").click(function() {
$.ajax({
url : "ajax6.do",
success : function(result) {
console.log(result);
let value = "";
for(let i=0; i<result.length; i++) {
value += "<tr>"
+ " <td>" + result[i].id + "</td>"
+ " <td>" + result[i].name + "</td>"
+ " <td>" + result[i].gender + "</td>"
+ " <td>" + result[i].email + "</td>"
+ "</tr>";
}
$("#output6 tbody").html(value);
},
error : function() {
console.log("ajax 통신 실패");
}
})
})
})
</script>
</body>
</html>
package ajax01;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
public class AjaxServletController1 extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String str = request.getParameter("input");
System.out.println("요청시 전달한 값 : " + str);
// DB에서 요청처리를 다 했다는 가정하에 응답할 데이터
String responseDate = "입력한 값 : " + str + ", 길이 : " + str.length();
// 응답데이터 돌려주기
response.setContentType("text/html; charset=utf-8");
response.getWriter().print(responseDate);
}
}
package ajax01;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import org.json.simple.*;
public class AjaxServletController2 extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String name = request.getParameter("name");
int age = Integer.parseInt(request.getParameter("age"));
// v1. 응답데이터가 하나의 문자열일 때
/*
String responseData = "이름 : " + name + ", 나이 : " + age;
response.setContentType("text/html; charset=utf-8");
response.getWriter().print(responseData);
*/
// v2. 응답데이터가 여러개 일 때
/*
response.setContentType("text/html; charset=utf-8");
response.getWriter().print(name);
response.getWriter().print(age);
*/
// v3. 응답데이터가 여러개 일 때 json이나 배열로 반환
/*
JSON(JavaScript Object notation : 자바스크립트 객체 표기법)
- ajax 통신시 데이터를 전송에 자주 사용되는 포맷형식중 하나
> [value, value, value] => 자바스크립에서의 배열 객체 => JSONArray
> {key:value, key:value} => 자바스크립에서의 일반 객체 => JSONObject
*/
// v3.1 JSONArray 배열로 반환
/*
JSONArray jArr = new JSONArray();
jArr.add(name);
jArr.add(age);
// response.setContentType("text/html; charset=utf-8"); => jArr을 반환해 주어도 문자열로 들어감
response.setContentType("application/json; charset=utf-8");
response.getWriter().print(jArr);
*/
// v3.2 JSONObject 객체로 반환
JSONObject jObj = new JSONObject();
jObj.put("name", name);
jObj.put("age", age);
response.setContentType("application/json; charset=utf-8");
response.getWriter().print(jObj);
}
}
package ajax01;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import org.json.simple.JSONObject;
import com.google.gson.Gson;
public class AjaxServletController5 extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String id = request.getParameter("id");
Member bean = new MemberMgr().getMember(id);
// 1. 문자열로 반환 : Member의 toString() 호출
// response.getWriter().print(bean);
// 2. JSONObject
/*
JSONObject jobj = new JSONObject();
jobj.put("userId", bean.getId());
jobj.put("userName", bean.getName());
jobj.put("gender", bean.getGender());
jobj.put("email", bean.getEmail());
response.setContentType("application/json; charset=utf-8");
response.getWriter().print(jobj);
*/
// 3. JSONObject를 알아서 넣어주는 GSON라이브러리 사용
/*
* GSON라이브러리
- 객체 하나만 응답시는 JSONObject {key:value, key:value,...}의 형태로 만들어져서 응답
> 객체의 필드는 자동으로 key가 됨
- 자바 배열이나 ArrayList 응답시 JSONArray [value,value,...] 형태로 만들어져서 응답
*/
/*
Gson gson = new Gson();
gson.toJson(bean, response.getWriter());
*/
response.setContentType("application/json; charset=utf-8"); new
Gson().toJson(bean, response.getWriter());
}
}
package ajax01;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import org.json.simple.*;
import com.google.gson.Gson;
public class AjaxServletController6 extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ArrayList<Member> alist = new MemberMgr().getAllMember();
// 1. JSONArray [{}, {}, {}]
/*
JSONArray jArr = new JSONArray();
for(Member m : alist) {
JSONObject jobj = new JSONObject();
jobj.put("id", m.getId());
jobj.put("name", m.getName());
jobj.put("gender", m.getGender());
jobj.put("email", m.getEmail());
jArr.add(jobj);
}
response.setContentType("application/json; charset=utf-8");
response.getWriter().print(jArr);
*/
// 2. GSON
response.setContentType("application/json; charset=utf-8");
new Gson().toJson(alist, response.getWriter());
}
}
package ajax01;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
public class AjaxServletIdCheck extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String id = request.getParameter("id");
boolean result = new MemberMgr().checkId(id);
if(result) {
response.getWriter().print("idN");
} else {
response.getWriter().print("idY");
}
}
}
package ajax01;
import java.util.Arrays;
public class Member {
private String id;
private String pwd;
private String name;
private String gender;
private String birthday;
private String email;
private String zipcode;
private String address;
private String detail_address;
private String hobby[];
private String job;
public Member() {}
public Member(String id, String pwd, String name, String gender, String birthday, String email, String zipcode,
String address, String detail_address, String[] hobby, String job) {
super();
this.id = id;
this.pwd = pwd;
this.name = name;
this.gender = gender;
this.birthday = birthday;
this.email = email;
this.zipcode = zipcode;
this.address = address;
this.detail_address = detail_address;
this.hobby = hobby;
this.job = job;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public String getBirthday() {
return birthday;
}
public void setBirthday(String birthday) {
this.birthday = birthday;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getZipcode() {
return zipcode;
}
public void setZipcode(String zipcode) {
this.zipcode = zipcode;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getDetail_address() {
return detail_address;
}
public void setDetail_address(String detail_address) {
this.detail_address = detail_address;
}
public String[] getHobby() {
return hobby;
}
public void setHobby(String[] hobby) {
this.hobby = hobby;
}
public String getJob() {
return job;
}
public void setJob(String job) {
this.job = job;
}
@Override
public String toString() {
return "Member [id=" + id + ", pwd=" + pwd + ", name=" + name + ", gender=" + gender + ", birthday=" + birthday
+ ", email=" + email + ", zipcode=" + zipcode + ", address=" + address + ", detail_address="
+ detail_address + ", hobby=" + Arrays.toString(hobby) + ", job=" + job + "]";
}
}
package ajax01;
import java.sql.*;
import java.util.ArrayList;
public class MemberMgr {
private DBConnectionMgr pool;
Connection con = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
String sql = null;
public MemberMgr() {
pool = DBConnectionMgr.getInstance();
}
public boolean checkId(String id) {
boolean flag = false;
try {
con = pool.getConnection();
sql = "select id from member where id = ?";
pstmt = con.prepareStatement(sql);
pstmt.setString(1, id);
rs = pstmt.executeQuery();
flag = rs.next();
} catch (Exception e) {
e.printStackTrace();
} finally {
pool.freeConnection(con, pstmt, rs);
}
return flag;
}
public boolean insertMember(Member bean) {
boolean flag = false;
try {
con = pool.getConnection();
sql = "insert into member values(?,?,?,?,?,?,?,?,?,?,?)";
pstmt = con.prepareStatement(sql);
pstmt.setString(1, bean.getId());
pstmt.setString(2, bean.getPwd());
pstmt.setString(3, bean.getName());
pstmt.setString(4, bean.getGender());
pstmt.setString(5, bean.getBirthday());
pstmt.setString(6, bean.getEmail());
pstmt.setString(7, bean.getZipcode());
pstmt.setString(8, bean.getAddress());
pstmt.setString(9, bean.getDetail_address());
String[] hobby = bean.getHobby();
char hb[] = {'0','0','0','0','0'};
String lists[] = {"인터넷","여행","게임","영화","운동"};
if(hobby != null) {
for(int i=0; i<hobby.length; i++) {
for(int j=0; j<lists.length; j++) {
if(hobby[i].equals(lists[j])) {
hb[j] = '1';
break;
}
}
}
}
pstmt.setString(10, new String(hb));
pstmt.setString(11, bean.getJob());
if(pstmt.executeUpdate() == 1) { // 반환값 : insert가 안되었을 때 0반환, insert가 잘 되었을 때 1반환
flag = true;
}
} catch (Exception e) {
e.printStackTrace();
} finally {
pool.freeConnection(con, pstmt);
}
return flag;
}
public boolean loginMember(String id, String pwd) {
boolean flag = false;
try {
con = pool.getConnection();
sql = "select id from member where id=? and pwd=?";
pstmt = con.prepareStatement(sql);
pstmt.setString(1, id);
pstmt.setString(2, pwd);
rs = pstmt.executeQuery();
flag = rs.next();
} catch (Exception e) {
e.printStackTrace();
} finally {
pool.freeConnection(con, pstmt, rs);
}
return flag;
}
public Member getMember(String id) {
Member bean = new Member();
try {
con=pool.getConnection();
sql = "select * from member where id=?";
pstmt = con.prepareStatement(sql);
pstmt.setString(1, id);
rs = pstmt.executeQuery();
if(rs.next()) {
bean.setId(rs.getString("id"));
bean.setName(rs.getString("name"));
bean.setGender(rs.getString("gender"));
bean.setEmail(rs.getString("email"));
}
} catch (Exception e) {
e.printStackTrace();
} finally {
pool.freeConnection(con);
}
return bean;
}
public ArrayList<Member> getAllMember() {
ArrayList<Member> alist = new ArrayList<Member>();
try {
con=pool.getConnection();
sql = "select * from member";
pstmt = con.prepareStatement(sql);
rs = pstmt.executeQuery();
while(rs.next()) {
Member bean = new Member();
bean.setId(rs.getString("id"));
bean.setName(rs.getString("name"));
bean.setGender(rs.getString("gender"));
bean.setEmail(rs.getString("email"));
alist.add(bean);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
pool.freeConnection(con);
}
return alist;
}
}