🍁jQuery로 개량하여 구현
ajax 메서드
$.ajax();
jQuery 함수를 $로 적고, 바로 .을 찍으면 ajax 메서드가 나타난다.
ajax는 태그와 관련된 기능이 아니라 독립적인 자바스크립트 기능이기 때문에 어떤 태그를 넣기가 애매하다. 독립적으로 ajax가 존재하도록 만들어야 하지만, 그냥 ajax();로 만들면 일반적인 함수인지 독립적인 함수인지 알 수 없기 때문에 앞에 jQuery를 붙여서 사용하는 것이다.
success 이벤트
<script>
$('#btn1').click(function() {
const isaac = {
name = 'Isaac',
age = 24,
hello: function() {
}
};
$.ajax({
//페이지 요청 정보
//ajax.open('GET', 'do')
type = 'GET',
url: '/ajax/ex03data.do',
//onreadystatechange + readyState(4) + status(200)
success: function(result) {
//result == ajax.responseText
}
});
});
</script>
ajax 메서드에는 페이지 요청 정보를 작성하며, 안전한 상황에서만 작업을 수행해야 한다. 그리고 onreadystatechange에서 readyState(4) + status(200)인 상황일 때 안전한 상황이라고 했는데, success: function(result)가 바로 이때의 상황을 의미한다. 그리고 이때 result는 ajax.responseText이다.
결과적으로 버튼을 클릭하면 ajax 메서드가 호출되면서 서버 쪽에서는 ex03data.do를 실행하며, success 이벤트가 호출되면서 result 매개변수에 값을 넣어서 돌려주게 된다.
데이터 전달
Ex03Data.java
//데이터 보내기
String name = req.getParameter("name");
ex03.jsp
//ex03data.do?name=Isaac
data: 'name=Isaac',
Ajax를 이용하여 서버에 데이터를 전달하고, 해당 데이터와 관련된 값을 가져올 수 있다.
에러 발생 시 호출(이벤트)
error: function(a, b, c){
console.log(a, b, c);
}
a, b, c로 Ajax 쪽에서 에러가 났을 때 무슨 일이 있었는지를 알 수 있게 된다.
동기 통신과 비동기 통신
시간이 흐름에 따라 브라우저(클라이언트)와 톰캣(웹 서버) 사이에서는 위와 같은 연결 과정이 발생한다.
브라우저에서 톰캣에 URL을 요청하면 인터넷 속도에 따라 요청이 수락되고, 작업이 발생한 뒤에 응답이 이루어진다.
동기 통신 상태는 요청이 들어가면 응답할 때까지 아무 일도 하지 않는 것을 의미한다. 그래서 동기 통신은 송수신 작업 과정이 한 줄로 이루어진다.
반면에 비동기 통신은 하나의 일이 끝나지 않더라도 다른 일을 할 수 있는 것을 의미한다. 예로 들어 비동기 통신은 요청 중에도 또 다른 요청을 하는 것도 가능하다.
따라서 동기 통신은 순서가 있는 작업을 할 떄, 비동기 통신은 순서가 없을 작업을 할 때 사용한다.
기본적으로 자바스크립트는 비동기 통신을 지원하지만, 프로퍼티의 옵션을 바꿈으로써 동기 통신으로 바꿀 수 있다.
통신 방식 변경 (async 프로퍼티)
//통신 방식 변경
async: true, //true(비동기), false(동기)
통신 방식을 동기 통신으로 변경하면 한 번에 한 가지 일만 할 수 있으므로 입력을 하더라도 기존 업무를 아직 끝내지 못했다면 업무를 끝내기 전까지 입력이 진행되지 않는다.
동기 통신은 업무가 끝나는 순간 그 일에 대한 결괏값을 return으로 받아올 수 있지만, 비동기 방식은 끝날 때까지 기다리지 않고 그 사이에 다른 업무를 하고 있기 때문에 return 값으로 받아오지 않고, success 이벤트를 만들어 값을 받아오는 것이다.
전체 코드
Ex03Data.java
package com.test.ajax.controller;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.test.ajax.repository.AjaxDAO;
@WebServlet("/ex03data.do")
public class Ex03Data extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//데이터 보내기
String name = req.getParameter("name");
//데이터 가져오기
AjaxDAO dao = new AjaxDAO();
//int count = dao.getMemoCount();
int count = dao.getMemoCount(name);
try {
//작업에 시간이 걸림..
Thread.sleep(10000);
} catch (Exception e) {
System.out.println("Ex03Data.doGet()");
e.printStackTrace();
}
PrintWriter writer = resp.getWriter();
writer.print(count);
writer.close();
//RequestDispatcher dispatcher = req.getRequestDispatcher("/WEB-INF/views/ex03data.jsp");
//dispatcher.forward(req, resp);
}
}
ex03.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="stylesheet" href="http://pinnpublic.dothome.co.kr/cdn/example-min.css">
<style>
</style>
</head>
<body>
<div>
<input type="text" id="txt1" value="${count}">
<input type="button" value="버튼1" id="btn1">
</div>
<div>
<input type="text" id="txt2">
<input type="button" value="버튼2" id="btn2">
</div>
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="http://pinnpublic.dothome.co.kr/cdn/example-min.js"></script>
<script>
$('#btn1').click(function() {
const isaac = {
name: 'Isaac',
age: 24,
hello: function() {
}
};
$.ajax({
//페이지 요청 정보
//ajax.open('GET', 'do')
type: 'GET',
url: '/ajax/ex03data.do',
//통신 방식 변경
async: true, //true(비동기), false(동기)
//ex03data.do?name=Isaac
data: 'name=Isaac',
//onreadystatechange + readyState(4) + status(200)
success: function(result) {
//result == ajax.responseText
$('#txt1').val(result);
},
//에러 발생 시 호출(이벤트)
error: function(a, b, c){
console.log(a, b, c);
}
});
});
</script>
</body>
</html>
AjaxDAO
package com.test.ajax.repository;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import com.test.ajax.controller.DBUtil;
public class AjaxDAO {
private Connection conn;
private Statement stat;
private PreparedStatement pstat;
private ResultSet rs;
public Connection getConn() {
return conn;
}
public void setConn(Connection conn) {
this.conn = conn;
}
public Statement getStat() {
return stat;
}
public void setStat(Statement stat) {
this.stat = stat;
}
public PreparedStatement getPstat() {
return pstat;
}
public void setPstat(PreparedStatement pstat) {
this.pstat = pstat;
}
public ResultSet getRs() {
return rs;
}
public void setRs(ResultSet rs) {
this.rs = rs;
}
public AjaxDAO() {
conn = DBUtil.open();
}
public int getMemoCount() {
try {
String sql = "select count(*) as cnt from tblMemo";
stat = conn.createStatement();
rs = stat.executeQuery(sql);
if (rs.next()) {
return rs.getInt("cnt");
}
} catch (Exception e) {
System.out.println("AjaxDAO.getMemoCount()");
e.printStackTrace();
}
return 0;
}
public int getMemoCount(String name) {
try {
String sql = String.format("select count(*) as cnt from tblMemo where name = '%s'", name);
stat = conn.createStatement();
rs = stat.executeQuery(sql);
if (rs.next()) {
return rs.getInt("cnt");
}
} catch (Exception e) {
System.out.println("AjaxDAO.getMemoCount()");
e.printStackTrace();
}
return 0;
}
}
jQuery로 개량하여 서버와의 통신을 순수 자바스크립트를 이용할 때보다 간단하게 구현할 수 있다.