Ajax에 대해서는 위 글을 참고한다.
타입에 따라서 돌려받을 데이터 형식(Text, XML, JSON)을 결정하여 각각의 작업 과정을 확인해 보도록 하자.
🍁Text
단일 데이터
Ex04.java
package com.test.ajax.controller;
import java.io.IOException;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/ex04.do")
public class Ex04 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
RequestDispatcher dispatcher = req.getRequestDispatcher("/WEB-INF/views/ex04.jsp");
dispatcher.forward(req, resp);
}
}
Ex04Data.java
private void m1(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 텍스트 반환(단일값)
AjaxDAO dao = new AjaxDAO();
int count = dao.getMemoCount();
resp.setContentType("text/plain"); // MIME 타입
resp.setCharacterEncoding("UTF-8");
PrintWriter writer = resp.getWriter();
writer.print(count);
writer.close();
}
ex04.jsp
$('#btn1').click(function(){
$.ajax({
type: 'GET',
url: '/ajax/ex04data.do',
data: 'type=1',
dataType: 'text', //돌려받을 데이터 형식
success: function(result) {
$('#result1').text(result);
},
error: function(a,b,c) {
console.log(a,b,c);
}
});
});
MIME 타입
resp.setContentType("text/plain");
MIME 타입은 돌려받는 브라우저 또는 ajax 객체에게 돌려받는 데이터가 이런 형식이 데이터라는 것을 알려주는 표시이다. 그래서 위 코드는 순수 텍스트 데이터라는 것을 알려주는 것을 의미한다.
한글 깨짐 방지
resp.setCharacterEncoding("UTF-8");
UTF-8로 한글이 출력될 수 있도록 한다.
다중 데이터
AjaxDAO.java
public ArrayList<MemoDTO> listMemo() {
try {
String sql = "select * from tblMemo";
stat = conn.createStatement();
rs = stat.executeQuery(sql);
ArrayList<MemoDTO> list = new ArrayList<MemoDTO>();
//ResultSet > 복사 > ArrayList(MemoDTO)
while (rs.next()) {
MemoDTO dto = new MemoDTO();
dto.setSeq(rs.getString("seq"));
dto.setSeq(rs.getString("name"));
dto.setSeq(rs.getString("pw"));
dto.setSeq(rs.getString("memo"));
dto.setSeq(rs.getString("regdate"));
list.add(dto);
}
return list;
} catch (Exception e) {
System.out.println("AjaxDAO.listMemo()");
e.printStackTrace();
}
return null;
}
Ex04Data.java
private void m2(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
AjaxDAO dao = new AjaxDAO();
ArrayList<MemoDTO> list = dao.listMemo();
// CSV
StringBuilder csv = new StringBuilder();
for (MemoDTO dto : list) {
csv.append(String.format("%s,%s,%s,%s,%s\r\n", dto.getSeq(), dto.getName(), dto.getPw(),
dto.getMemo().replace("\r\n", "\n"), dto.getRegdate()));
}
resp.setContentType("text/plain");
resp.setCharacterEncoding("UTF-8");
PrintWriter writer = resp.getWriter();
writer.print(csv.toString());
writer.close();
}
ex04.jsp
$('#btn1').click(function(){
$.ajax({
type: 'GET',
url: '/ajax/ex04data.do',
//data: 'type=1',
data: 'type=2',
dataType: 'text', //돌려받을 데이터 형식(text, xml, json)
success: function(result) {
//$('#result1').text(result);
const list = result.split('\r\n');
list.forEach(memo => {
//alert(memo);
const item = memo.split(',');
$('#result1').append('<div>' + item[0] + '</div>');
$('#result1').append('<div>' + item[1] + '</div>');
$('#result1').append('<div>' + item[2] + '</div>');
$('#result1').append('<br>);
});
},
error: function(a,b,c) {
console.log(a,b,c);
}
});
});
다량의 텍스트를 순수 텍스트로 표현하는 가장 무난한 방법은 CSV이다.
하지만 다량의 값은 XML이나 JSON으로 처리하는 게 더 좋기 때문에 위 방법은 잘 사용하지 않는다.
🍁XML (Extensible Markup Language)
다중 데이터 1
Ex04.java
package com.test.ajax.controller;
import java.io.IOException;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/ex04.do")
public class Ex04 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// Ex04.java
RequestDispatcher dispatcher = req.getRequestDispatcher("/WEB-INF/views/ex04.jsp");
dispatcher.forward(req, resp);
}
}
Ex04Data.java
$('#btn2').click(function() {
$.ajax({
type: 'GET',
url: '/ajax/ex04data.do',
data: 'type=3',
dataType: 'xml',
success: function(result) {
$('#result2').append('<div>번호: ' + $(result).find('seq').text() + '</div>');
$('#result2').append('<div>이름: ' + $(result).find('name').text() + '</div>');
$('#result2').append('<div>암호: ' + $(result).find('pw').text() + '</div>');
$('#result2').append('<div>메모: ' + $(result).find('memo').text() + '</div>');
$('#result2').append('<div>날짜: ' + $(result).find('regdate').text() + '</div>');
},
error: function(a, b, c) {
console.log(a, b, c);
}
});
});
ex04.jsp
private void m3(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
AjaxDAO dao = new AjaxDAO();
MemoDTO dto = dao.get(1);
// MemoDTO > (XML 형식) > ajax
// resp.setContentType("text/html");
// resp.setContentType("application/zip");
// resp.setContentType("text/plane");
resp.setCharacterEncoding("UTF-8");
resp.setContentType("text/xml");
PrintWriter writer = resp.getWriter();
writer.print("<?xml version='1.0' encoding='UTF-8'?>");
writer.print("<memo>");
writer.printf("<seq>%s</seq>", dto.getSeq());
writer.printf("<name>%s</name>", dto.getName());
writer.printf("<pw>%s</pw>", dto.getPw());
writer.printf("<memo>%s</memo>", dto.getMemo());
writer.printf("<regdate>%s</regdate>", dto.getRegdate());
writer.print("</memo>");
writer.close();
}
이는 서블릿이 HTML 문서를 만드는 것과 같은 상황이다.
대신 서블릿이 아니라 XML로 xml은 컬럼 이름으로 태그를 만들어 HTML문서를 만든다.
find 메서드
$(result).find('name').text());
xml을 jQuery로 감싸면 find 메서드를 사용할 수 있다.
xml과 javaScript는 같은 형제이기 때문에 태그를 검색할 수 있다.
다중 데이터 2
XML로 여러 개의 메모(MemoDTO x 3개)를 반환하도록 해보자.
Ex04Data.java
resp.setContentType("text/xml");
브라우저는 ContentType으로 데이터를 믿기 때문에 XML이라는 것을 알려 주어야한다.
PrintWriter writer = resp.getWriter();
XML을 동적으로 만드는 작업이기 때문에 Wrtier를 가지고 만든다.
이제 list를 XML 형식의 문자열로 출력 작업을 한다.
writer.print("<?xml version='1.0' encoding='UTF-8'?>");
먼저 XML 선언문을 만든다. 그리고 아래에 내가 만들고 싶은 태그 작업을 한다.
메모라는 루트 태그를 만들고, 그 안에 집어 넣어야 할 값들을 하위 태그로 만들어서 그 태그에 해시 데이터를 넣어야 하는데, 이번에는 이 작업을 여러 번 해야 한다. for문으로 루프를 돌려서 메모를 하나 출력하는 작업을 여러 번 할 수 있다.
그런데 그냥 실행하면 오류가 발생한다. 모든 마크업 언어(ML)은 최상위 태그가 유일해야 하는데, 루트 Element가 여러 개 이기 때문이다. 그래서 바깥에 루트가 되어 전체를 감싸는 <list> 태그를 만들어 주어야 한다. 이러면 XML로써 문제가 전혀 없다.
Ex04Data.java 전체 코드
private void m4(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
AjaxDAO dao = new AjaxDAO();
ArrayList<MemoDTO> list = dao.listMemo();
resp.setContentType("text/xml");
resp.setCharacterEncoding("UTF-8");
PrintWriter writer = resp.getWriter();
writer.print("<?xml version='1.0' encoding='UTF-8'?>");
writer.println("<list>");
for (MemoDTO dto: list) {
writer.println("<memo>");
writer.printf("<seq>%s</seq>", dto.getSeq());
writer.printf("<name>%s</name>", dto.getName());
writer.printf("<pw>%s</pw>", dto.getPw());
writer.printf("<memo>%s</memo>", dto.getMemo());
writer.printf("<regdate>%s</regdate>", dto.getRegdate());
writer.println("</memo>");
}
writer.println("</list>");
writer.close();
}
ex04.jsp
$('#btn2').click(function() {
$.ajax({
type: 'GET',
url: '/ajax/ex04data.do',
//data: 'type=3',
data: 'type=4',
dataType: 'xml',
success: function(result)
//alert($(result).html());
//each 메서드
$(result).find('list > memo').each((index, item) => {
$('#result2').append('<div>' + $(item).find('seq').text() + '</div>');
$('#result2').append('<div>' + $(item).find('name').text() + '</div>');
$('#result2').append('<div>' + $(item).find('pw').text() + '</div>');
$('#result2').append('<div>' + $(item).find('memo').text() + '</div>');
$('#result2').append('<div>' + $(item).find('regdate').text() + '</div>');
});
},
error: function(a, b, c) {
console.log(a, b, c);
}
});
});
문서상에서 리스트의 자식인 메모 태그만 찾는다.
each 메서드
$(result).find('list > memo').each((index, item) => {
each 메서드는 forEach()와 동일하다. (향상된 for문)
자바의 forEach(item, index)와 자바스크립트의 each(index, item)은 반대이다.
🍁JSON (JavaScript Object Notation)
🍂JSON이란?
JSON은 객체 표기법이다.
JSON을 더 정확히 말하자면 자바스크립트 문법을 빌려 어떤 객체를 표기하는 표현법이다.
JSON의 특징
{
"키": "값",
"키": "값",
"키": "값"
}
앞은 프로퍼티, 뒤는 값으로 작성하는 게 자바스크립트의 객체이다. 이를 본따서 만든 게 JSON이다.
자바스크립트가 아닌 곳에서도 사용할 수 있도록 문법을 고쳐 두었는데, 반드시 키와 값을 큰 따옴표("") 안에 묶어야 한다는 점이다.
즉, 키와 값을 문자열로 표기해야 한다. 단, 숫자 값은 ""를 생략할 수 있다.
이때 쌍따옴표만 사용할 수 있으며, 홑따옴표를 사용하는 게 불가능하다는 점에 주의한다.
그리고 hello: function() {} 이런 식으로 메서드 멤버 추가가 불가능하다. 메서드는 값이 아니기 때문에 추가할 수 없는 것이다.
JSON은 오로지 데이터를 저장하는 역할을 한다는 점에서 자바의 DTO와 동일한 역할을 한다.
JSON 객체
{
"seq": "5"
"name": "Isaac",
"pw": "1111",
"memo": "메모입니다.",
"regdate": "2023-10-26 09:40:00"
}
위와 같은 형식으로 출력될 수 있도록 JSON 객체를 만들어보도록 하자.
다중 데이터
Ex04Data.java
AjaxDAO dao = new AjaxDAO();
MemoDTO dto = dao.get(1);
데이터베이스에서 데이터를 가져오고, 미리 만들어 둔 get 메서드로 메모를 하나 출력한다.
이제 메모를 JSON 객체로 만들어서 돌려주도록 하자.
resp.setContentType("application/json"); //MIME
resp.setCharacterEncoding("UTF-8");
이 데이터가 JSON이라는 것을 알려 주어야 한다.
그리고 인코딩 타입을 UTF-8로 지정해준다.
PrintWriter writer = resp.getWriter();
writer.println("{");
writer.printf("\"seq\":\"%s\",", dto.getSeq());
writer.printf("\"name\":\"%s\",", dto.getName());
writer.printf("\"pw\":\"%s\",", dto.getPw());
writer.printf("\"memo\":\"%s\",", dto.getMemo());
writer.printf("\"regdate\":\"%s\"", dto.getRegdate());
writer.println("}");
writer.close();
JSON은 이스케이프("\") 때문에 문법이 헷갈리므로 천천히 작업하도록 한다.
Ex04Data.java 전체 코드
private void m5(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
AjaxDAO dao = new AjaxDAO();
MemoDTO dto = dao.get(1);
resp.setContentType("application/json"); //MIME
resp.setCharacterEncoding("UTF-8");
PrintWriter writer = resp.getWriter();
writer.println("{");
writer.printf("\"seq\":\"%s\",", dto.getSeq());
writer.printf("\"name\":\"%s\",", dto.getName());
writer.printf("\"pw\":\"%s\",", dto.getPw());
writer.printf("\"memo\":\"%s\",", dto.getMemo());
writer.printf("\"regdate\":\"%s\"", dto.getRegdate());
writer.println("}");
writer.close();
}
ex04.jsp
$('#btn3').click(function() {
$.ajax({
type: 'GET',
url: '/ajax/ex04data.do',
data: 'type=5',
dataType: 'json',
success: function(result) {
//alert(result.seq);
$('#result3').append('<div>' + result.seq + '</div>');
$('#result3').append('<div>' + result.name + '</div>');
$('#result3').append('<div>' + result.pw + '</div>');
$('#result3').append('<div>' + result.memo + '</div>');
$('#result3').append('<div>' + result.regdate + '</div>');
},
error: function(a, b, c) {
console.log(a, b, c);
}
})
});
JSON은 처음부터 자바스크립트의 데이터를 돌려주기 때문에 데이터를 가공할 필요가 없다.
result 자체가 이미 자바스크립트 객체이기 때문에 더 깔끔하게 출력할 수 있다.
자바스크립트 배열을 이용하는 방법
자바스크립트 배열
[
10
,
20
]
배열 [] 안에 데이터를 넣어서 데이터를 반환할 수 있다.
객체와 객체 사이에 콤마를 넣어준다.
마지막 데이터에는 ','를 쓰지 않도록 해야 하는데, 향상된 for문이기 때문에 마지막 번째 데이터인지 구분하기 번거롭다.
temp = temp.substring(0, temp.length() - 1);
그래서 콤마 제거 처리를 위해 위 구문을 작성한다.
이제 오류가 발생하지 않는다.
Ex04Data.java
private void m6(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
AjaxDAO dao = new AjaxDAO();
ArrayList<MemoDTO> list = dao.listMemo();
resp.setContentType("application/json"); //MIME
resp.setCharacterEncoding("UTF-8");
PrintWriter writer = resp.getWriter();
String temp = "";
temp += "[";
for (MemoDTO dto : list) {
temp += "{";
temp += String.format("\"seq\":\"%s\",", dto.getSeq());
temp += String.format("\"name\":\"%s\",", dto.getName());
temp += String.format("\"pw\":\"%s\",", dto.getPw());
temp += String.format("\"memo\":\"%s\",", dto.getMemo().replace("\r\n", "\\r\\n")); //개행 처리
temp += String.format("\"regdate\":\"%s\"", dto.getRegdate());
temp += "}";
temp += ",";
}
temp = temp.substring(0, temp.length() - 1); //콤마 처리
temp += "]";
writer.print(temp);
writer.close();
}
개행 처리와 콤마 처리를 마친 모습이다.
ex04.jsp
$('#btn3').click(function() {
$.ajax({
type: 'GET',
url: '/ajax/ex04data.do',
//data: 'type=5',
data: 'type=6',
dataType: 'json',
success: function(result) {
$(result).each((index, memo) => {
//alert(memo.seq);
$('#result3').append('<div>' + memo.seq + '</div>');
$('#result3').append('<div>' + memo.name + '</div>');
$('#result3').append('<div>' + memo.pw + '</div>');
$('#result3').append('<div>' + memo.memo + '</div>');
$('#result3').append('<div>' + memo.regdate + '</div>');
$('#result3').append('<hr>');
});
},
error: function(a, b, c) {
console.log(a, b, c);
}
})
});