본문 바로가기
Kosta DevOps 과정 280기/Java

Ajax 통신

by 롯슈83 2024. 7. 22.

Ajax(Asynchronous JavaScript and XML)

  • 비동기적인 웹 어플리케이션의 제작을 위한 웹 개발 기법
  • 현재의 자바스크립트는 사용자의 요청에 따라 동적으로 노드를 생성, 수정, 삭제하는 것이 목적
  • 사용자의 요청에 따라 서버로부터 데이터를 읽어오기 위한 방법
  • 이 때 우리가 다룰 서버의 기술은 jsp, 서블릿, 스프링이다.
  • 원래 서버의 프로그램인 jsp, 서블릿, 스프링은 동적인 html 을 생성하는 것이 목적이지만, Ajax 통신으로 요청될 때는 그에 필요한 데이터만 응답한다.
  • 이 때 데이터만 응답하는 방식으로 csv, xml, json(표준 데이터 형식)이있다.
    • csv : , 를 기준으로 데이터를 구분
    • xml : 초창기 웹 문서의 형식
    • json : 자바스크립트를 기반으로 한 데이터 형식

  • 네이버를 보면 문서의 전체를 다 읽고 바뀌는 것(풀 브라우징)이 아니라, 일부분 즉 연합 뉴스 등의 일부분만 바뀌는 것.
    • 풀 브라우징 : jsp, a태그를 눌렀을 때
      • 데이터 요청 동안 다른 일을 할 수 없음
    • 필요한 데이터(연합뉴스같은 갱신에 필요한 데이터처럼 일부분)만 요구하는 기술 = 비동기 방식 : ajax(<-> 동기 방식)
      • 데이터 요청 동안 다른 일을 할 수 있음

예제 : 모든 데이터를 json 형태로 응답하도록 jsp 작성

<%@page import="com.kosta.vo.DeptVO"%>
<%@page import="java.util.ArrayList"%>
<%@page import="com.kosta.dao.DeptDAO"%>
<%@ page language="java" contentType="application/json; charset=UTF-8"
    pageEncoding="UTF-8"%>
/*
[{
	"dno":"10",
	"dname":"기획팀",
	"dloc":"종각"
}, {
	"dno":"10",
	"dname":"기획팀",
	"dloc":"종각"
}]
*/
<%
	String data = "[";
	DeptDAO dao = new DeptDAO();
	ArrayList<DeptVO> list = dao.findAll();
	for(DeptVO d:list){
		data += "{";
		
		data += "\"dno\":";
		data += "\""+d.getDno()+"\",";
		
		data += "\"dname\":";
		data += "\""+d.getDname()+"\",";
		data += "\"dloc\":";
		data += "\""+d.getDloc()+"\"";
		
		data += "},\n";
	}
	data = data.substring(0, data.length()-1);
	data+= "]";
%>
<%= data %>

 

 

JavaScript 로 Ajax 통신하기

  • Ajax 통신을 위해서 XML HttpRequest() 객체를 생성한다.
    • var request = new XMLHttpRequest();
  • open 메소드를 이용하여 요청할 서버의 프로그램과 요청방식(동기, 비동기)을 설정한다.
    • request.open("get", "hello.jsp", false)
    • 이 때, 세번째 매개변수true 이면 비동기, false 이면 동기 방식이다.
  • send 메소드를 호출하여 Ajax 통신을 요청한다.
    • request.send();
  • 서버로부터 응답한 데이터는 request.responseText 에 담겨서 온다.

 

비동기 방식의 Ajax 통신

  • 비동기 방식으로 Ajax 통신을 할 때에는 서버로부터 응답이 완료되었을 때 노드를 생성하는 코드를 작성해야 한다.
  • 또, 서버의 응답이 오류가 아닌 OK 상태일 때 필요한 코드를 작성하도록 해야한다.
  • XMLHttpRequest 에서는 서버로부터 응답이 완료되었는지를 상태를 확인하기 위한 다음의 이벤트와 상태값을 이용한다.
    • request.onreadystatechange= function(){
      • if(request.readyState == 4){// 응답 완료
        • if(request.status == 200){
          • //응답 OK 상태
          • //노드를 생성하기 위한 코드
        • }
      • }
    • }

예제

  • 기본셋팅
package com.kosta.dao;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;

import com.kosta.db.ConnectionProvider;
import com.kosta.vo.DeptVO;

public class DeptDAO {
	public ArrayList<DeptVO> findAll(){
		ArrayList<DeptVO> list = new ArrayList<>();
		
		try {
			String sql = "select * from dept";
			Connection conn  = ConnectionProvider.getConnection();
			Statement stmt = conn.createStatement();
			ResultSet rs = stmt.executeQuery(sql);
			
			while(rs.next()) {
				list.add(new DeptVO(rs.getInt(1), rs.getString(2), rs.getString(3)));
			}
			ConnectionProvider.close(rs, stmt, conn);
		} catch (Exception e) {
			System.out.println(e);
		}
		
		return list;
	}
}
package com.kosta.db;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;

public class ConnectionProvider {	
	public static  Connection getConnection() {
		Connection conn = null;
		String driver = "oracle.jdbc.driver.OracleDriver";
		String url = "jdbc:oracle:thin:@localhost:1521:XE";
		String username = "c##madang";
		String password = "madang";
		try {
			Class.forName(driver);
			conn = DriverManager.getConnection(url, username, password);
		}catch (Exception e) {
			System.out.println("예외발생:"+e.getMessage());
		}	
		return conn;
	}
	
	public static void close(ResultSet rs, Statement stmt, Connection conn) {
		try {
			if(rs != null) {
				rs.close();
			}
			if(stmt != null) {
				stmt.close();
			}
			if(conn != null) {
				conn.close();
			}
		}catch (Exception e) {
			System.out.println("예외발생:"+e.getMessage());
		}
	}
	public static void close(Statement stmt, Connection conn) {
		try {		
			if(stmt != null) {
				stmt.close();
			}
			if(conn != null) {
				conn.close();
			}
		}catch (Exception e) {
			System.out.println("예외발생:"+e.getMessage());
		}
	}
}
  • 일반적으로 썼던 jsp
<%@page import="com.kosta.vo.DeptVO"%>
<%@page import="java.util.ArrayList"%>
<%@page import="com.kosta.dao.DeptDAO"%>
<%@ 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>
</head>
<body>
	<table border="1">
	<%
		DeptDAO dao = new DeptDAO();
		ArrayList<DeptVO> list = dao.findAll();
		for(DeptVO d:list){
			%>
				<tr>
					<td><%=d.getDno()%></td>
					<td><%=d.getDname()%></td>
					<td><%=d.getDloc()%></td>
				</tr>
			<%
		}
	%>
	</table>
</body>
</html>
  • json 을 jsp 에서 직접 작성
<%@page import="com.kosta.vo.DeptVO"%>
<%@page import="java.util.ArrayList"%>
<%@page import="com.kosta.dao.DeptDAO"%>
<%@ page language="java" contentType="application/json; charset=UTF-8"
    pageEncoding="UTF-8"%>
/*
[{
	"dno":"10",
	"dname":"기획팀",
	"dloc":"종각"
}, {
	"dno":"10",
	"dname":"기획팀",
	"dloc":"종각"
}]
*/
<%
	Thread.sleep(5000);
	String data = "[";
	DeptDAO dao = new DeptDAO();
	ArrayList<DeptVO> list = dao.findAll();
	for(DeptVO d:list){
		data += "{";
		
		data += "\"dno\":";
		data += "\""+d.getDno()+"\",";
		
		data += "\"dname\":";
		data += "\""+d.getDname()+"\",";
		data += "\"dloc\":";
		data += "\""+d.getDloc()+"\"";
		
		data += "},\n";
	}
	data = data.substring(0, data.length()-1);
	data+= "]";
%>
<%= data %>
  • json 작성 라이브러리 Gson 이용
<%@page import="com.google.gson.Gson"%>
<%@page import="com.kosta.vo.DeptVO"%>
<%@page import="java.util.ArrayList"%>
<%@page import="com.kosta.dao.DeptDAO"%>
<%@ page language="java" contentType="application/json; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
	Thread.sleep(5000);
	DeptDAO dao = new DeptDAO();
	ArrayList<DeptVO> list = dao.findAll();
	Gson gson = new Gson();
	String data = gson.toJson(list);
%>
<%= data %>
  • 동기방식으로 jsp
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script>
    window.onload = function(){
        document.querySelector("#btnRead").onclick=function(){
            let request = new XMLHttpRequest();
            //동기 방식의 get방식으로 jsp
            // 서버로부터 데이터가 올 때까지 아무것도 하지 않겠다. 
            //textarea를 쓰다가 버튼을 누르면 먹통됨.
            request.open("get", "listDept_json.jsp", false);
            request.send();
            //문자에 담겨져 오므로 객체를 생성하여for문 등의 수행을 작업한다.
            let arr = eval("("+request.responseText+")");
            let table = document.createElement("table");
            for(let i=0;i<arr.length;i++){
                let tr = document.createElement("tr");
                let td1 = document.createElement("td");
                let td2 = document.createElement("td");
                let td3 = document.createElement("td");
                let txt1 = document.createTextNode(arr[i].dno);
                let txt2 = document.createTextNode(arr[i].dname);
                let txt3 = document.createTextNode(arr[i].dloc);

                td1.appendChild(txt1);
                td2.appendChild(txt2);
                td3.appendChild(txt3);

                tr.appendChild(td1);
                tr.appendChild(td2);
                tr.appendChild(td3);

                table.appendChild(tr);
            }
            document.querySelector("#output").appendChild(table);
        }
    }
</script>
<style>
    table{
        border:1px solid #ddd;
        border-spacing: 0;
        border-collapse: separate;
    }
    table td{
        border:1px solid #ddd;
    }
</style>
</head>
<body>
    <textarea name="" id=""></textarea>
    <hr>
    <h1>Hello Kosta</h1>
    <button id="btnRead">Ajax 통신</button>
    <hr>
    <div id="output"></div>
    <h1>Hello Kosta</h1>
</body>
</html>
  • 비동기 방식'만' 설정
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script>
    window.onload = function(){
        document.querySelector("#btnRead").onclick=function(){
            let request = new XMLHttpRequest();
            //비동기 방식의 get방식으로 jsp

            //textarea를 쓰다가 버튼을 누르면 textarea는 작성이된다.

            //하지만 아래를 true 를 할 경우 아무리 기다려도 문장이 실행이 안된다.            
            request.open("get", "listDept_ajaxTest.jsp", true);
            request.send();

            //서버로부터 응답이 오기도 전에 동작하기 때문에 노드가 생성되지 않기 때문이다.
            //즉, 서버로부터 응답이 된 후 동작하게끔 코드를 변경해줘야한다.
            let arr = eval("("+request.responseText+")");
            let table = document.createElement("table");
            for(let i=0;i<arr.length;i++){
                let tr = document.createElement("tr");
                let td1 = document.createElement("td");
                let td2 = document.createElement("td");
                let td3 = document.createElement("td");
                let txt1 = document.createTextNode(arr[i].dno);
                let txt2 = document.createTextNode(arr[i].dname);
                let txt3 = document.createTextNode(arr[i].dloc);

                td1.appendChild(txt1);
                td2.appendChild(txt2);
                td3.appendChild(txt3);

                tr.appendChild(td1);
                tr.appendChild(td2);
                tr.appendChild(td3);

                table.appendChild(tr);
            }
            document.querySelector("#output").appendChild(table);
        }
    }
</script>
<style>
    table{
        border:1px solid #ddd;
        border-spacing: 0;
        border-collapse: separate;
    }
    table td{
        border:1px solid #ddd;
    }
</style>
</head>
<body>
    <textarea name="" id=""></textarea>
    <hr>
    <h1>Hello Kosta</h1>
    <button id="btnRead">Ajax 통신</button>
    <hr>
    <div id="output"></div>
    <h1>Hello Kosta</h1>
</body>
</html>
  • 비동기 설정 + 상태 확인
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script>
    window.onload = function(){
        document.querySelector("#btnRead").onclick=function(){
            let request = new XMLHttpRequest();
            
            request.onreadystatechange = function(){
                if(request.readyState == 4){
                    if(request.status == 200){
                        let arr = eval("("+request.responseText+")");
                        let table = document.createElement("table");
                        for(let i=0;i<arr.length;i++){
                            let tr = document.createElement("tr");
                            let td1 = document.createElement("td");
                            let td2 = document.createElement("td");
                            let td3 = document.createElement("td");
                            let txt1 = document.createTextNode(arr[i].dno);
                            let txt2 = document.createTextNode(arr[i].dname);
                            let txt3 = document.createTextNode(arr[i].dloc);

                            td1.appendChild(txt1);
                            td2.appendChild(txt2);
                            td3.appendChild(txt3);

                            tr.appendChild(td1);
                            tr.appendChild(td2);
                            tr.appendChild(td3);

                            table.appendChild(tr);
                        }
                        document.querySelector("#output").appendChild(table);
                    }
                }
            }

            request.open("get", "listDept_ajaxTest.jsp", true);
            request.send();            
        }
    }
</script>
<style>
    table{
        border:1px solid #ddd;
        border-spacing: 0;
        border-collapse: separate;
    }
    table td{
        border:1px solid #ddd;
    }
</style>
</head>
<body>
    <textarea name="" id=""></textarea>
    <hr>
    <h1>Hello Kosta</h1>
    <button id="btnRead">Ajax 통신</button>
    <hr>
    <div id="output"></div>
    <h1>Hello Kosta</h1>
</body>
</html>

'Kosta DevOps 과정 280기 > Java' 카테고리의 다른 글

스프링 베이직 시작 : 환경설정  (0) 2024.07.31
jquery와 Ajax  (0) 2024.07.22
세션을 이용한 상태유지  (0) 2024.07.16
프론트 컨트롤러  (0) 2024.07.15
MVC 패턴  (0) 2024.07.15