Ajax의 개요와 JSON에 대해 알아보자
✔️ Ajax를 시작하기 전에 (공부 환경 설정)
1. Dynamic Web Project 생성
👉🏻Project name: Ajax_Project
👉🏻 Default output folder 경로: WebContent\WEB-INF\classes
👉🏻 Context root: ajax
👉🏻 배포 서술자 체크박스
✔️ 완료
![](https://blog.kakaocdn.net/dn/340Xd/btrPrqbjHET/ZIHXdUnjGhd9KNglYaYJxk/img.png)
![](https://blog.kakaocdn.net/dn/NV0Ig/btrPnephFsy/axmb1szr9LJgJSFlhq2zuk/img.png)
2. 첫 화면이 될 index.jsp 생성 후 서버에 올리기
![](https://blog.kakaocdn.net/dn/H4bOM/btrPtiQ9mkB/fkQE9uI9pIqdRwLzdHuFF0/img.png)
![](https://blog.kakaocdn.net/dn/cORs2B/btrPrrOTLDF/I6eoFMImGqDrpijHfziN9K/img.png)
![](https://blog.kakaocdn.net/dn/b1F0wd/btrPulfzfuz/LKNd4GV6t3HPyEyg46MPy0/img.png)
Ajax
👉🏻 Asynchronous JavaScript And XML의 약자
👉🏻 서버로부터 데이터를 가져와 전체 페이지를 새로고침하지 않고 일부만 로드할 수 있게 하는 기법
👉🏻 우리가 기존에 a 태그 또는 form 태그를 통해 요청했던 방식은 "동기식 요청"이었음
=> 응답 페이지가 돌아와야 그 결과를 볼 수 있었음 (페이지 화면이 깜빡거림)
✔️ 비동기식 요청을 보내기 위해서는 AJAX라는 기술이 필요함
동기식 / 비동기식
✔️ 동기식: 요청 처리 후 그에 해당되는 응답페이지가 돌아와야만 그 다음 작업이 가능
👉🏻만약 서버에서 호출된 결과까지의 시간이 지연되면 무작정 기다려야 함
👉🏻 흰페이지로 보여짐 / 와이파이 잘 안 잡히는 곳에서 새로운 페이지 열 때처럼!
👉🏻 전체 페이지가 리로드됨 (새로고침! 즉, 페이지가 기본적으로 깜빡거림)
✔️ 비동기식: 현재 페이지를 그대로 유지하면서 중간중간마다 추가적인 요청을 보내줄 수 있음
👉🏻 요청을 한다고 해서다른 페이지로 넘어가지 않음 (현재 페이지 그대로임)
👉🏻 요청을 보내 놓고 그에 해당되는 응답이 돌아올 때까지 현재 페이지에서 다른 작업도 할 수 있음
👉🏻 즉, 페이지가 깜빡거리지 않음!
예) 네이버 홈페이지의 아이디 중복 체크 기능 (다른 웹 사이트도 마찬가지)
네이버 홈페이지의 검색어 자동오나성 기능 (다른 웹사이트들도 마찬가지)
네이트 홈페이지의 인기 검색어 기능 (다른 웹사이트들도 마찬가지) 등등
비동기식의 단점
✔️ 현재 페이지에 요청을 계속 보내고 응답을 계속 받는다면 지속적으로 리소스가 쌓임
👉🏻 페이지가 현저히 느려질 수 있음
✔️ 현재 페이지 내 복잡도가 기하급수적으로 증가 => 성능의 문제, 에러 발생 시 디버깅이 어려움
✔️ 요청 후 돌아온 응답 데이터를 가지고 현재 페이지에서 새로운 요소를 만들어서 출력해야 함
👉🏻 DOM 요소를 새로이 만들어 내는 구문을 잘 익혀 둬야 함
AJAX 구현방식
👉🏻 JavaScript 방식 / jQuery 방식
✔️ 우리는 코드가 간결하고 사용하기 쉬운 jQuery 방식으로 공부할 것!
👉🏻 head 영역에 제이쿼리 연결 온라인 방식 script 구문 추가
👉🏻 참고: min 버전까지는 지원 가능하나 온라인 방식 중 slim 방식은 ajax 지원하지 않으므로 주의!
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<!-- 제이쿼리 연결 온라인 방식 -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.1/jquery.min.js"></script>
</head>
jQuery 방식에서의 AJAX 통신
[ 표현법 ]
$.ajax({
속성명 : 속성값,
속성명 : 속성값,
...
});
주요 속성
<요청을 보내는 역할>
👉🏻 url: 요청할 서블릿의 url 매핑값(필수로 작성)
✔️ form 태그의 action 속성과 같은 역할
👉🏻 type / method: 요청 전송 방식 (get / post, 생략 시 get 방식이 기본)
✔️ form 태그의 method 속성과 같은 역할
👉🏻 data: 요청 시 전달할 값들을 키-밸류 세트로 작성
✔️ form 태그 내부의 input 태그들과 같은 역할
<응답을 받아 주는 역할>
👉🏻 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)
jQuery 방식을 이용한 AJAX 테스트
1. 버튼 클릭 시 get 방식으로 서버에 데이터 전송 및 응답
요청만! 하는 index.jsp
👉🏻 url로 localhost:8888/ajax을 입력했을 때 뜨는 메인 창
👉🏻 응답을 받아 주지 않은 상태임!
👉🏻 공부할 때는 응답까지 받아 주는 index.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>
<!-- 제이쿼리 연결 온라인 방식 -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.1/jquery.min.js"></script>
</head>
<body>
<h1>jQuery 방식을 이용한 AJAX 테스트</h1>
<h3>1. 버튼 클릭 시 get 방식으로 서버에 데이터 전송 및 응답</h3>
입력:<input type="text" id="input1">
<button id="btn1">전송</button>
<br><br>
응답: <label id="output1">현재 응답 없음</label>
<script>
$(function() {
// 전송 버튼이 클릭되는 순간 요청 보내기
$("#btn1").click(function() {
// 기존의 동기식 통신
// location.href = "jqAjax1.do?input=xxx";
// 비동기식 통신
$.ajax({
// 요청 보내기
url : "jqAjax1.do", // 어느 url로 보낼 것인지
data : {input : $("#input1").val()}, // 보낼 데이터, "키 : 밸류" 세트로 보내야 함
type : "get", // 요청 방식 지정
}
});
});
</script>
</body>
</html>
JqAjaxController1 서블릿 생성
👉🏻 요청을 받아 줄 서블릿
👉🏻 url mapping: /jqAjax1.do
👉🏻 1. 혹시라도 응답 데이터에 한글이 있을 경우 깨질 것을 대비해 응답 데이터에 대한 mimetype과 charset을 설정
👉🏻 2. JSP와의 통로 열기
package com.kh.controller;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class JqAjaxController1
*/
@WebServlet("/jqAjax1.do")
public class JqAjaxController1 extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public JqAjaxController1() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// System.out.println("잘 호출되나...?"); // 전송 버튼 눌렀을 때 콘솔에 잘 뜸!
// request.getParameter("키값"): String 타입의 밸류값
String str = request.getParameter("input");
// System.out.println("요청 시 전달값 : " + str);
// 요청 처리를 다 했다는 가정 하에 응답할 데이터
String responseData = "입력된 값: " + str + ", 길이: " + str.length();
// 요청을 보냈던 곳으로 응답데이터를 돌려주기
// (기존의 동기식 요청에서는 응답 데이터를 Servlet) 내장 객체에 실어서 페이지 통째로 돌려줌
// => 비동기식 요청에서는 응답 데이터만 넘겨 줌
// 1. 혹시라도 응답 데이터에 한글이 있을 경우 응답 데이터가 깨질 수 있기 때문에
// 응답 데이터에 대한 mimetype과 charset을 설정해야 함
response.setContentType("text/html; charset=UTF-8");
// 자바 코드로 HTML 코드 실어서 응답 페이지를 자바 코드로 바꿀 때 써 봤었음!
// 이 과정 안 해 주면 한글이 모두 물음표로 처리되는 현상 발생!
// (RequestGetServlet.java 참고! 서버 진도 초반에 써 봤음)
// 2. JSP와의 통로 열어 주기
// => PrintWriter 형식의 통로를 열어줌
response.getWriter().print(responseData);
// => 이것도 자바 코드 안에 html 코드 넣을 때 사용했던 메소드
// 서블릿으로 화면 구성할 때 써 봄!
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
현재 상황
index.jsp에서는 $.ajax 관련 function으로 type까지만 넣어 준 상태!
메인 페이지에서 텍스트 입력 후 전송 버튼을 눌렀을 때 doget 메소드가 호출되어
인코딩, 통로 연 뒤 응답 데이터를 넘긴 상태!
(다만 index.jsp에서 응답을 받아 주지 않은 상태이기 때문에 변화가 없음)
응답도 받아주는! index.jsp
👉🏻 url로 localhost:8888/ajax을 입력했을 때 뜨는 메인 창
👉🏻 응답까지 받아 준 상태임!
<%@ 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>
<!-- 제이쿼리 연결 온라인 방식 -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.1/jquery.min.js"></script>
</head>
<body>
<h1>jQuery 방식을 이용한 AJAX 테스트</h1>
<h3>1. 버튼 클릭 시 get 방식으로 서버에 데이터 전송 및 응답</h3>
입력:<input type="text" id="input1">
<button id="btn1">전송</button>
<br><br>
응답: <label id="output1">현재 응답 없음</label>
<script>
$(function() {
// 전송 버튼이 클릭되는 순간 요청 보내기
$("#btn1").click(function() {
// 기존의 동기식 통신
// location.href = "jqAjax1.do?input=xxx";
// 비동기식 통신
$.ajax({
// 요청 보내기
url : "jqAjax1.do", // 어느 url로 보낼 것인지
data : {input : $("#input1").val()}, // 보낼 데이터, "키 : 밸류" 세트로 보내야 함
type : "get", // 요청 방식 지정
// 응답을 받아 주기
success : function(result) { // 성공 시 응답 데이터가 자동으로 매개변수로 넘어옴
// console.log("ajax 통신 성공!");
// console.log(result);
$("#output1").text(result).css("color", "blue");
},
error : function() {
console.log("ajax 통신 실패!");
},
complete : function () {
console.log("ajax 통신 성공 여부와 상관없이 무조건 호출!");
}
});
});
});
</script>
</body>
</html>
2. 버튼 클릭 시 post 방식으로 서버에 데이터 전송 및 응답
index.jsp
👉🏻 url로 localhost:8888/ajax을 입력했을 때 뜨는 메인 창
<h3>2. 버튼 클릭 시 post 방식으로 서버에 데이터 전송 및 응답</h3>
이름: <input type="text" id="input2_1"> <br>
나이: <input type="number" id="input2_2"> <br>
<button onclick="test2();">전송</button>
<!-- 내용이 길어질 것 같으니 선언적 함수 사용! -->
<br><br>
응답: <label id="output2">현재 응답 없음</label>
<script>
function test2() {
$.ajax({
url : "jqAjax2.do",
data : {
name : $("#input2_1").val(),
age : $("#input2_2").val(),
},
type : "post",
success : function(result) {
console.log(result);
},
error : function () {
console.log("ajax 통신 실패!");
}
});
}
</script>
JqAjaxController2 서블릿 생성
👉🏻 요청을 받아 줄 서블릿
👉🏻 url mapping: /jqAjax2.do
package com.kh.controller;
import java.io.IOException;
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 org.json.simple.JSONArray;
/**
* Servlet implementation class JqAjaxController2
*/
@WebServlet("/jqAjax2.do")
public class JqAjaxController2 extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public JqAjaxController2() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// System.out.println("잘실행되나..?");
// 기존의 동기식 요청에서는
// post방식으로 요청이 들어왔을 경우 인코딩 설정을 먼저 해 주고 나서 요청 시 전달값을 뽑았어야 했음
// => 비동기식 요청에서는 기본 인코딩 세팅이 UTF-8이기 때문에 인코딩 설정은 생략
String name = request.getParameter("name");
int age = Integer.parseInt(request.getParameter("age"));
// 요청 처리를 다 했다는 가정 하에 응답할 데이터 (문자열)
/*
String responseData = "이름: " + name + ", 나이: " + age;
// System.out.println(responseData);
// 데이터 응답하기
response.setContentType("text/html; charset=UTF-8");
response.getWriter().print(responseData);
*/
// 여러 개의 데이터로 응답하고 싶다면?
// 요청 처리를 다 했다는 가정 하에 응답할 데이터 (문자열)
response.setContentType("text/html; charset=UTF-8");
response.getWriter().print(name);
response.getWriter().print(age);
// '말똥27'이 콘솔에 출력됨 => 한 개의 문자열처럼 이어져서 응답됨
// => 즉, Ajax는 기본적으로 결과를 오로지 한 개만 응답할 수 있는 구조임!
// 만약 여러 개의 응답 데이터를 넘기고 싶다면 JSON이라는 개념을 활용해야 함
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
여러 개의 응답 데이터를 따로 보내고 싶은데 이렇게 한 개의 문자열로 함께 출력됨
이럴 때 필요한 게 JSON
* JSON(JavaScript Object Notation) : 자바 스크립트 객체 표기법
👉🏻 ajax 통신 시 데이터 전송에 사용되는 포맷 형식 중 하나
👉🏻 JSON 처리 시 사용되는 클래스 종류는 기본적으로 자바에서 제공하지 않음 (외부 라이브러리 필요)
👉🏻 응답 데이터가 여러 개일 경우 JSON에서 제공하는 두 가지 형태 중 선택하여 가공
1. JSONArray[value, value, value, ...] => 자바 스크립트의 배열 형식
2. JSONObject{key:value, key:value, key:value, ...} => 자바 스크립트의 객체 형식
✔️ 자바스크립트에서의 배열은 자바의 ArrayList와 유사함 (타입 제한 X, 사이즈 제한 X, 인덱스 개념 O)
<JSON 라이브러리 다운로드 링크>
https://code.google.com/archive/p/json-simple/downloads
Google Code Archive - Long-term storage for Google Code Project Hosting.
code.google.com
Json-simple-1.1.1.jar 다운로드 후 dev 폴더에 보관
![](https://blog.kakaocdn.net/dn/b7vszz/btrPtJuSsvb/O8qEdxkB2IioLapdlDjV60/img.png)
현재 사용 중인 프로젝트의 WebContent-WEB-INF-lib 폴더에도 넣어 주기
![](https://blog.kakaocdn.net/dn/HMuhj/btrPsAyMOgx/IGTMl1RhaHvcQTET2lTBk0/img.png)
JSON 연동 끝!
JSON 라이브러리를 추가한 JqAjaxContoller2 (JSONArray 타입)
👉🏻 여러 개의 데이터를 배열 형식으로 담아 보내기 가능
package com.kh.controller;
import java.io.IOException;
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 org.json.simple.JSONArray;
/**
* Servlet implementation class JqAjaxController2
*/
@WebServlet("/jqAjax2.do")
public class JqAjaxController2 extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public JqAjaxController2() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// System.out.println("잘실행되나..?");
// 기존의 동기식 요청에서는
// post방식으로 요청이 들어왔을 경우 인코딩 설정을 먼저 해 주고 나서 요청 시 전달값을 뽑았어야 했음
// => 비동기식 요청에서는 기본 인코딩 세팅이 UTF-8이기 때문에 인코딩 설정은 생략
String name = request.getParameter("name");
int age = Integer.parseInt(request.getParameter("age"));
// JSONArray 타입으로 넘기기
JSONArray jArr = new JSONArray(); // 임포트 해 주기
jArr.add(name);
jArr.add(age);
// 이 코드 작성 시 내부적으로 빈 배열 생성 후 -> ["말똥"] -> ["말똥", 27]
// 위와 같이 차곡차곡 채워짐
// => 자바스크립트에서의 배열은 자바의 ArrayList와 유사함 (타입 제한 X, 사이즈 제한 X, 인덱스 개념 O)
// jArr을 응답 데이터로 넘기기
// 응답할 데이터의 컨텐트 타입을 제대로 지정해야 문자열 형식으로 넘어가지 않음!
response.setContentType("application/json; charset=UTF-8");
response.getWriter().print(jArr);
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
같은 값을 입력했을 때 자바스크립트의 배열 형식으로 출력됨
하지만! 테스트 해 보면 진짜 배열의 형식과는 다름
👉🏻 배열처럼 보이는 문자열로 넘어가 있음!
"text/html; charset=UTF-8"과 같이 기존에 우리가 넘길 때 text 형식으로 넘겼기 때문임!
"application/json; charset=UTF-8"로 수정해 줄 것
// jArr을 응답 데이터로 넘기기
// 응답할 데이터의 컨텐트 타입을 제대로 지정해야 문자열 형식으로 넘어가지 않음!
response.setContentType("application/json; charset=UTF-8");
response.getWriter().print(jArr);
👉🏻 이제 콘솔에서 펼쳐 볼 수 있는 진짜 배열로 넘어감!
index.jsp
<h3>2. 버튼 클릭 시 post 방식으로 서버에 데이터 전송 및 응답</h3>
이름: <input type="text" id="input2_1"> <br>
나이: <input type="number" id="input2_2"> <br>
<button onclick="test2();">전송</button>
<!-- 내용이 길어질 것 같으니 선언적 함수 사용! -->
<br><br>
응답: <label id="output2">현재 응답 없음</label>
<script>
function test2() {
$.ajax({
url : "jqAjax2.do",
data : {
name : $("#input2_1").val(),
age : $("#input2_2").val(),
},
type : "post",
success : function(result) {
// console.log(result);
// json setContentType 바꾸기 전 테스트용
// var arr = [1, 2, "abc"];
// console.log(arr);
// JSONArray로 응답받을 경우
/*
$("#output2").text("이름: " + result[0] + ", 나이: " + result[1]);
// 초기화되는 효과 추가
$("#input2_1").val("");
$("#input2_2").val("");
*/
// JSONObject로 응답받을 경우
// console.log(result);
// $("#output2").text(result); // 응답: [object Object]
$("#output2").text("이름: " + result.name + ", 나이: " + result.age);
// 초기화되는 효과 추가
$("#input2_1").val("");
$("#input2_2").val("");
},
error : function () {
console.log("ajax 통신 실패!");
}
});
}
</script>
JSON 라이브러리를 추가한 JqAjaxContoller2 (JSONObject 타입)
👉🏻 여러 개의 데이터를 배열 형식으로 담아 보내기 가능
package com.kh.controller;
import java.io.IOException;
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 org.json.simple.JSONObject;
/**
* Servlet implementation class JqAjaxController2
*/
@WebServlet("/jqAjax2.do")
public class JqAjaxController2 extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public JqAjaxController2() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String name = request.getParameter("name");
int age = Integer.parseInt(request.getParameter("age"));
// JSONObject 타입으로 넘기기
JSONObject jObj = new JSONObject(); // 내부적으로 맵 계열의 빈 오브젝트 타입이 하나 만들어짐 {}
jObj.put("name", name); // {name:"김말똥"}
jObj.put("age", age); // {name:"김말똥", age:27}
// => 자바 스크립트에서의 객체는 자바에서의 HashMap과 유사 (키-밸류 세트, 사이즈 제한 X, 키값 중복 X, 밸류 중복 O, 인덱스 개념 X)
// jObj를 응답 데이터로 넘기기
response.setContentType("application/json; charset=UTF-8");
response.getWriter().print(jObj);
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
여기까지 진행 후 JSP_Project의 member에서 아이디 중복 확인 실습 후 돌아옴
3. 서버로 데이터 전송 후, 조회된 VO 객체를 응답 데이터로 받기
index.jsp
👉🏻 url로 localhost:8888/ajax을 입력했을 때 뜨는 메인 창
<h3>3. 서버로 데이터 전송 후, 조회된 VO 객체를 응답 데이터로 받기</h3>
회원번호 입력: <input type="number" id="input3">
<button onclick="test3();">조회</button>
<br><br>
<div id="output3"></div>
<script>
function test3() {
$.ajax({
url : "jqAjax3.do",
data : {no: $("#input3").val()},
type : "get",
success : function(result) {
// console.log(result);
var resultStr = "회원번호: " + result.memberNo + "<br>"
+ "이름: " + result.memberName + "<br>"
+ "나이: " + result.age + "<br>"
+ "성별: " + result.gender + "<br>";
$("#output3").html(resultStr);
},
error : function() {
console.log("ajax 통신 실패!");
}
});
}
</script>
JqAjaxController3 서블릿 생성
👉🏻 요청을 받아 줄 서블릿
👉🏻 url mapping: /jqAjax3.do
package com.kh.controller;
import java.io.IOException;
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 org.json.simple.JSONObject;
import com.kh.model.vo.Member;
/**
* Servlet implementation class JqAjaxController3
*/
@WebServlet("/jqAjax3.do")
public class JqAjaxController3 extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public JqAjaxController3() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 요청 시 전달값인 회원번호 (no) 뽑기
int memberNo = Integer.parseInt(request.getParameter("no"));
// 데이터를 조회했다라는 가정 하에 간단하게 Member 객체 구성
Member m = new Member(memberNo, "고길동", 50, "남");
// 만들어진 객체를 응답 데이터로 넘기기
// response.setContentType("text/html; charset=UTF-8");
// 알게 모르게 내부적으로 toString() 메소드가 호출돼서 문자열로 응답이 넘어감
// response.getWriter().print(m /* .toString() */);
// { 속성명 : 속성값, 속성명 : 속성값, ...} => JSONObject
JSONObject jObj = new JSONObject(); // {}
jObj.put("memberNo", m.getMemberNo()); // {memberNo:30}
jObj.put("memberName", m.getMemberName()); // {memberNo:30, memberName:"고길동"}
jObj.put("age", m.getAge()); // {memberNo:30, memberName:"고길동", age:50}
jObj.put("gender", m.getGender()); // {memberNo:30, memberName:"고길동", age:50, gender:"남"}
response.setContentType("application/json; charset=UTF-8");
response.getWriter().print(jObj);
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
Member 클래스 생성
👉🏻 실습을 위한 member 클래스 생성, 패키지 경로도 추가되었으므로 반드시 확인!
package com.kh.model.vo;
public class Member {
private int memberNo;
private String memberName;
private int age;
private String gender;
public Member() {
}
public Member(int memberNo, String memberName, int age, String gender) {
super();
this.memberNo = memberNo;
this.memberName = memberName;
this.age = age;
this.gender = gender;
}
public int getMemberNo() {
return memberNo;
}
public void setMemberNo(int memberNo) {
this.memberNo = memberNo;
}
public String getMemberName() {
return memberName;
}
public void setMemberName(String memberName) {
this.memberName = memberName;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
@Override
public String toString() {
return "Member [memberNo=" + memberNo + ", memberName=" + memberName + ", age=" + age + ", gender=" + gender
+ "]";
}
}
위의 Controller처럼 JSON 사용해서 하나하나 put 하는 게 정석적인 방법은 맞음!
근데 필드 많아지면 언제 한땀한땀 1줄씩 코드 만들면서 넣고 있을래요,,?
필드가 많아질 때 알아서 하나하나 넣어 주는 라이브러리가 있음!
*GSON: Google JSON
GSON 외부 라이브러리를 연동해야지만 사용 가능!
<Gson 라이브러리 다운로드 링크 접속 후 jar 파일 다운로드>
https://mvnrepository.com/artifact/com.google.code.gson/gson/2.8.2
![](https://blog.kakaocdn.net/dn/bIDFui/btrPuOKeP4a/H9eizmzkiRvFDywA3LBDd0/img.png)
dev 폴더와 현재 사용 중인 Project의 WebContent/WEB-INF-lib 경로에 넣어 주기
![](https://blog.kakaocdn.net/dn/bXTUpy/btrPyGcZebM/8bx9vsbgtdtnPlMK6Yf5ck/img.png)
<GSON 적용 전>
package com.kh.controller;
import java.io.IOException;
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 org.json.simple.JSONObject;
import com.kh.model.vo.Member;
/**
* Servlet implementation class JqAjaxController3
*/
@WebServlet("/jqAjax3.do")
public class JqAjaxController3 extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public JqAjaxController3() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 요청 시 전달값인 회원번호 (no) 뽑기
int memberNo = Integer.parseInt(request.getParameter("no"));
// 데이터를 조회했다라는 가정 하에 간단하게 Member 객체 구성
Member m = new Member(memberNo, "고길동", 50, "남");
// 만들어진 객체를 응답 데이터로 넘기기
// response.setContentType("text/html; charset=UTF-8");
// 알게 모르게 내부적으로 toString() 메소드가 호출돼서 문자열로 응답이 넘어감
// response.getWriter().print(m /* .toString() */);
// { 속성명 : 속성값, 속성명 : 속성값, ...} => JSONObject
JSONObject jObj = new JSONObject(); // {}
jObj.put("memberNo", m.getMemberNo()); // {memberNo:30}
jObj.put("memberName", m.getMemberName()); // {memberNo:30, memberName:"고길동"}
jObj.put("age", m.getAge()); // {memberNo:30, memberName:"고길동", age:50}
jObj.put("gender", m.getGender()); // {memberNo:30, memberName:"고길동", age:50, gender:"남"}
response.setContentType("application/json; charset=UTF-8");
response.getWriter().print(jObj);
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
<GSON 적용 후>
package com.kh.controller;
import java.io.IOException;
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.google.gson.Gson;
import com.kh.model.vo.Member;
/**
* Servlet implementation class JqAjaxController3
*/
@WebServlet("/jqAjax3.do")
public class JqAjaxController3 extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public JqAjaxController3() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 요청 시 전달값인 회원번호 (no) 뽑기
int memberNo = Integer.parseInt(request.getParameter("no"));
// 데이터를 조회했다라는 가정 하에 간단하게 Member 객체 구성
Member m = new Member(memberNo, "고길동", 50, "남");
response.setContentType("application/json; charset=UTF-8");
// Gson gson = new Gson(); // lib 경로에 다운로드 한 gson.jar 복붙 후 임포트 해 주기
// toJson(응답할객체, 응답할스트림객체);
// gson.toJson(m, response.getWriter());
// => response.getWriter()라는 통로로 m 이라는 객체를 응답 데이터로 넘길 거야
// 단, 변환 시 전달되는 키값은 VO 객체의 각 필드값으로 자동으로 잡혀 가공 후 넘겨 줌!
new Gson().toJson(m, response.getWriter()); // 한 줄로도 표현 가능!
// VO 객체 하나만 응답 시 JSONObject 타입으로 만들어져서 응답
// ArrayList 응답 시 JSONArray 타입으로 만들어져서 응답
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
![](https://blog.kakaocdn.net/dn/cd9Ugf/btrPyARwv73/BJBkzZjaLS5eHDulNUMoXK/img.png)
4. 응답 데이터로 여러 개의 객체들이 담겨 있는 ArrayList 받기
index.jsp
👉🏻 url로 localhost:8888/ajax을 입력했을 때 뜨는 메인 창
<h3>4. 응답 데이터로 여러 개의 객체들이 담겨 있는 ArrayList 받기</h3>
<button onclick="test4();">회원 전체조회</button>
<br><br>
<table id="output4" border="1" style="text-align:center;">
<thead>
<tr>
<th>회원번호</th>
<th>회원명</th>
<th>나이</th>
<th>성별</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
<script>
function test4() {
$.ajax({
url : "jqAjax4.do",
success : function(result) {
// console.log(result);
// 현재 result에는 회원들의 정보가 담긴 자바 스크립트의 객체배열이 담겨 있음
var str = "";
for(var i = 0; i < result.length; i++) {
// console.log(result[i]);
// console.log(result[i].memberName);
str += "<tr>"
+ "<td>" + result[i].memberNo + "</td>"
+ "<td>" + result[i].memberName + "</td>"
+ "<td>" + result[i].age + "</td>"
+ "<td>" + result[i].gender + "</td>"
+ "</tr>";
}
$("#output4 tbody").html(str)
},
error : function() {
console.log("ajax 통신 실패!");
}
});
}
</script>
JqAjaxController4 서블릿 생성
👉🏻 요청을 받아 줄 서블릿
👉🏻 url mapping: /jqAjax4.do
package com.kh.controller;
import java.io.IOException;
import java.util.ArrayList;
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.google.gson.Gson;
import com.kh.model.vo.Member;
/**
* Servlet implementation class JqAjaxController4
*/
@WebServlet("/jqAjax4.do")
public class JqAjaxController4 extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public JqAjaxController4() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// DB로부터 회원 정보를 전체 조회 했다는 가정 하에
// 간단히 Member만 들어갈 수 있는 ArrayList 객체 생성
ArrayList<Member> list = new ArrayList<>();
list.add(new Member(1, "고길동", 50, "남"));
list.add(new Member(2, "박말똥", 17, "여"));
list.add(new Member(3, "김갑생", 22, "여"));
list.add(new Member(4, "김루꽁", 28, "여"));
// 응답 데이터로 ArrayList를 통째로 넘기기
// => 그냥 넘기면 문자열 형식으로 응답이 넘어갈 것!
// 해결방안 1. 각각의 Member를 JSONObject로 가공 후에
// JSONArrayList로 가공하고 보내는 방법(순수 JSON jar 파일 이용)
// ======= 로직 매우 복잡할 것 같으니 GSON을 이용하자!
// 해결방안 2. GSON 이용하기
response.setContentType("application/json; charset=UTF-8");
new Gson().toJson(list, response.getWriter());
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
ajax를 사용해 만든 동적 요소에 이벤트 걸기
👉🏻 ajax 사용 시 동적으로 만들어진 요소를 사용하게 되는데
이 요소에 이벤트를 걸 때는 제이쿼리에서 배운 이벤트 속성 중 3번째 속성을 사용해야 함!
ajax로 만든 동적 요소에 제이쿼리 방식으로 이벤트 걸기 (방법 3만 적용 가능)