Java EE 정리 23
29 Mar 2019
Reading time ~6 minutes
Java EE 정리 23 - AJAX(2)
AJAX
- selector로 찾고 일을 하지 않음
- 매개변수는 JavaScript Object 한개
- type
- 요청방식
- GET/ POST
- async
- 동작형태
- 비동기식(true), 동기식(false)으로 응답을 받을지 설정하는 것
- dataType
- 서버에서 응답받을 데이터 종류
- XML, JSON, HTML, TEXT
- ajax요청 dataType과 서버에서 처리한 후 응답하는 MIME Type은 꼭 같아야 한다.
- callback function
- error, success에 정의된 함수
- 서버에 응답이 왔을 때 자동으로 호출되는 함수
$.ajax({ url: "URL",
type: "요청방식(GET|POST)",
data: "QueryString",
async: "동작형태(true(비동기)|false(동기))",
dataType: "서버에서 응답받을 데이터 종류"
error: function(xhr) {
// 서버에서 에러에 대한 응답이 왔을 때 사용자에게 제공할 코드
}
success: function(서버에서 응답된 데이터를 받는 매개변수) {
// 서버에서 정상적인 응답이 왔을 때 사용자에게 제공할 코드
// DOM을 사용한 화면의 일부분 변경 코드
}
});
- AJAX 사용, TEXT 응답 예
- ajax는 form으로 사용하지 않음!
<!-- text_result.jsp -->
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
String name = request.getParameter("name");
// 텍스트 응답(CSV)
String temp = "";
if("이봉현".equals(name)) {
temp="이재찬,정택성,백인재";
} else if ("박영민".equals(name)){
temp="김정윤,노진경,최지우,김희철";
} else if (("오영근").equals(name)) {
temp="이재현,공선의,박정미,최혜원";
} else {
temp="김건하,박소영";
}
%>
<%= temp %>
<!-- ajax_text.jsp -->
...
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<script type="text/javascript">
$(function() {
$("#btn").click(function() {
var name=$("#name").val();
var queryString="name="+name;
$.ajax({
url:"text_result.jsp",
type:"get",
data: queryString,
dataType:"TEXT",
async:"true",
error: function(xhr) {
// XMLHttpRequest -> xhr을 사용하면 error의 이유를 확인 가능
// 200 - 서버가 정상 실행되어 응답 성공하였으나 응답의 형태가
// 처리 가능한 데이터가 아닐 때
alert("에러코드 : "+xhr.status+",에러 메세지 : "+xhr.statusText);
},
success: function(text_data) {
$("#memberDiv").html(text_data);
}
});
});
}); // ready
</script>
...
<div>
조장 : <input type="text" id="name" class="inputBox"/>
<input type="button" value="입력" class="btn" id="btn"/>
</div>
<div id="memberDiv">
</div>
...
- 응답받은 CSV TEXT를 split으로 잘라 사용가능
$("#btn").click(function() {
var name=$("#name").val();
var queryString="name="+name;
$.ajax({
url:"text_result.jsp",
type:"get",
data: queryString,
dataType:"TEXT",
async:"false",
error: function(xhr) {
alert("에러코드 : "+xhr.status+",에러 메세지 : "+xhr.statusText);
},
success: function(text_data) {
var output="<ul>";
var data = text_data.split(",");
for(var i=0; i < data.length; i++) {
output+="<li>"+data[i]+"</li>";
}
output+="</ul>";
$("#memberDiv").html(output);
}
});
});
- 크롬은 Parameter값이 한글일 때 자동으로 인코딩 처리
- ‘가’ -> %AA%BB%CC 같이 인코딩을 해줌
- ie는 자동 인코딩을 해주지 않음
- encodeURI()를 사용해야 함
var name=$("#name").val(); // ie에서 한글 입력 시 에러 발생
var queryString="name="+name;
// javascript의 encoding 함수 -> encodeURI()로 인코딩 해줘야 한다.
var queryString="name="+encodeURI(name);
- 없는 jsp페이지로 요청하면 404 에러 발생
...
$.ajax({
url:"text_result1.jsp",
...
- 잘못된 코드로 서버에서 처리 후 응답을 받으면 500 에러 발생
<!-- text_result.jsp -->
...
<%= temp
- JSP에서는 줄변경에 신경을 많이 쓴다.
- 줄바꿈은 태그 안에서만 수행!
- 스크립트릿 줄바꿈 시 HTML 줄바꿈 처리가 되버린다.
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
...
%>
<%= temp %>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%><%
...
%><%= temp %>
- AJAX 사용, HTML 응답 예
- 비권장, 서버가 HTML을 다 만들고 보내는 방식
- 서버가 모든 연산을 함, 클라이언트 자원을 사용하는 RIA가 아님
<!-- html_result.jsp -->
<!-- 서버가 모든 연산수행 -->
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
String name = request.getParameter("name");
// HTML로 응답
String[] temp = {""};
if("이봉현".equals(name)) {
temp="이재찬,정택성,백인재".split(",");
} else if ("박영민".equals(name)){
temp="김정윤,노진경,최지우,김희철".split(",");;
} else if (("오영근").equals(name)) {
temp="이재현,공선의,박정미,최혜원".split(",");;
} else {
temp="김건하,박소영".split(",");;
}
%>
<table>
<tr>
<th width="80">번호</th>
<th width="120">이름</th>
<% for(int i=0; i < temp.length; i++) { %>
</tr>
<td><%= i+1 %></td>
<td><%= temp[i] %></td>
<tr>
<% } %>
</tr>
</table>
<!-- ajax_html.jsp -->
<script type="text/javascript">
$(function() {
$("#btn").click(function() {
var name=$("#name").val();
var queryString="name="+encodeURI(name);
$.ajax({
url:"text_result.jsp",
type:"get",
data: queryString,
dataType:"TEXT",
async:"true",
error: function(xhr) {
alert("에러코드 : "+xhr.status
+",에러 메세지 : "+xhr.statusText);
},
success: function(text_data) {
var output="<strong>"
+name+"</strong>조장의 조원</ul>";
var data = text_data.split(",");
for(var i=0; i < data.length; i++) {
output+="<li>"+data[i]+"</li>";
}
output+="</ul>";
$("#memberDiv").html(output);
}
});
});
}); // ready
</script>
...
<div>
<select id="group">
<option value="이봉현">1조</option>
<option value="박영민">2조</option>
<option value="오영근">3조</option>
<option value="김건하">조기취업</option>
</select>
</div>
<div id="memberView">
</div>
...
jQuery를 사용한 XML Parsing
...
dataType:"xml",
success:function(xml_data) { // xml_data는 서버에서 응답한 XML문서
// 찾는 노드가 하나일 땐 파싱할 노드를 찾는다.
var 변수명 = $(xml_data).find("찾을 노드명").text(); // Parsing
// 찾는 노드가 여럿일 땐 파싱할 노드를 찾아 반복시킨다.
$.each($(xml_data).find("찾을 노드명"), function(idx, element) {
$(element).text(); // Parsing, element 대신 this를 써도 됨
});
}
...
- AJAX 사용, XML 응답 예 1
- 태그안에서 줄을 바꿔야 XML 선언부가 첫줄로 나온다!
<!-- xml_result.jsp -->
<%@page import="org.jdom2.output.Format"
%><%@page import="org.jdom2.output.XMLOutputter"
%><%@page import="org.jdom2.Element"
%><%@page import="org.jdom2.Document"
%><%@ page language="java" contentType="text/xml; charset=UTF-8"
pageEncoding="UTF-8"%><%
String name = request.getParameter("name");
// XML로 응답
String[] temp = {""};
if("이봉현".equals(name)) {
temp="이재찬,정택성,백인재".split(",");
} else if ("박영민".equals(name)){
temp="김정윤,노진경,최지우,김희철".split(",");;
} else if (("오영근").equals(name)) {
temp="이재현,공선의,박정미,최혜원".split(",");;
} else {
temp="김건하,박소영".split(",");;
}
// 1. XML 문서 객체 생성
Document xmlDoc = new Document();
// 2. 최상위 노드 생성
Element rootNode = new Element("names");
// 3. 자식 노드를 생성
Element nameNode = null;
for(int i=0; i < temp.length; i++) {
// 자식 노드 생성
nameNode = new Element("name");
// 자식 노드에 값 설정
nameNode.setText(temp[i]);
// 4. 생성된 자식 노드를 부모노드에 추가
rootNode.addContent(nameNode);
}
// 5. 자식노드를 가진 부모노드를 문서객체에 추가
xmlDoc.addContent(rootNode);
// 6. 출력
XMLOutputter x_out = new XMLOutputter(Format.getPrettyFormat());
x_out.output(xmlDoc, out);
%>
- jQuery로 XML을 Parsing하는게 JDOM 사용하는 것 보다 쉽다.
- :checked를 안해주면 무얼 선택해도 “이봉현”을 value로 가짐
<!-- ajax_xml.jsp -->
<script type="text/javascript">
$(function() {
$("#btn").click(function() {
// checked된 값
var name = $("[name='name']:checked").val();
var queryString = "name="+name;
$.ajax({
url:"xml_result.jsp",
type:"get",
data:queryString,
dataType:"xml",
async:"true",
error:function(xhr) {
alert(xhr.status);
},
success:function(xml_data) {
alert(xml_data);
}
});
});
}); // ready
</script>
...
<div>
<input type="radio" name="name" value="이봉현" checked="checked"/>1조
<input type="radio" name="name" value="박영민"/>2조
<input type="radio" name="name" value="오영근"/>3조
<input type="radio" name="name" value="김건하"/>조기취업
<input type="button" value="조회" class="btn" id="btn"/>
</div>
<div id="memberView">
</div>
...
- 잘못된 Parsing
- XML안에 name 노드가 여럿 존재할 때 노드명으로 바로 파싱하면 한꺼번에 값이 나옴
success:function(xml_data) {
alert($(xml_data).find("name").text());
}
- 노드가 여럿일 때 올바른 Parsing
- JDOM을 사용해서 Parsing하는 것 보다 jQuery를 이용하는게 훨씬 간단
success:function(xml_data) {
var nameNodes = $(xml_data).find("name"); // 배열
$.each(nameNodes,function(idx, nameNode) { // 하나씩 파싱
alert($(this).text()); // this == nameNode
});
}
- 파싱한 XML 데이터를 화면에 보여주기
success:function(xml_data) {
var nameNodes = $(xml_data).find("name"); // 배열
var output = "";
$.each(nameNodes,function(idx, nameNode) {
output+="<input type='checkbox' name='name' value='"
+$(this).text()+"'/>"+$(this).text()+"</br>";
});
$("#memberView").html(output);
}
- AJAX 사용, XML 응답 예 2
- 이전에 만든 depts XML을 파싱
- XML을 직접 요청 시 (오픈 API 등), 파라미터를 사용하지 않음
- ajax 매개변수인 JS Object에 data 속성이 필요 없다.
<?xml version="1.0" encoding="UTF-8"?>
<depts>
<dept>
<deptno></deptno>
<dname>SI 개발부</dname>
<loc>서울</loc>
</dept>
...
<!-- ajax_xml1.jsp -->
...
<script type="text/javascript">
$(function() {
$("#reqXml").click(function() {
// xml을 직접 요청(공공데이터가 XML을 요청하여 응답 받는 것과 동일)
// 파라미터를 사용하지 않는다(data: 를 사용하지 않는다)
$.ajax({
url:"../xml0326/depts.xml",
type:"get",
dataType:"xml",
error:function(xhr) {
alert(xhr.status+" / "+xhr.statusText);
},
success:function(xml) {
// 반복해야 할 노드를 찾고
var deptNodes = $(xml).find("dept");
// 찾은 노드를 반복시킨다
$.each(deptNodes, function(idx, deptNode) {
// 반복중인 노드의 값 얻기
var deptno = $(this).find("deptno").text();
var dname = $(this).find("dname").text();
var loc = $(this).find("loc").text();
$("#tab:last").append("<tr><td>"+deptno
+"</td><td>"+dname+"</td><td>"+loc+"</td></tr>");
});
}
});
});
}); // ready
</script>
...
<div>
<a href="#void" id="reqXml">부서정보</a>
</div>
<div>
<table border="1" id="tab">
<tr>
<th style="width:80px;">부서번호</th>
<th style="width:180px;">부서명</th>
<th style="width:100px;">위치</th>
</tr>
</table>
</div>
...
- 부서정보를 여러번 누르면 계속 추가된다.
- 한번만 들어가게 막는다.
- 테이블에서 첫 행일때(데이터 추가 전)만 추가하도록 조건 추가
success:function(xml) {
var deptNodes = $(xml).find("dept");
if($("#tab tr").size() == 1) { // 행이 한행일때만 추가
$.each(deptNodes, function(idx, deptNode) {
var deptno = $(this).find("deptno").text();
var dname = $(this).find("dname").text();
var loc = $(this).find("loc").text();
$("#tab:last").append("<tr><td>"+deptno
+"</td><td>"+dname+"</td><td>"+loc+"</td></tr>");
});
}
}
AJAX 200 에러 디버깅
- AJAX 200 에러
- 서버는 처리를 잘 했으나 응답받은 데이터가 잘못된 형식인 경우 발생하는 에러
- dataType을 “text”로 놓고 찍어서 확인해본다.
$.ajax({
url:"xml_result.jsp",
type:"get",
data:queryString,
dataType:"text",
async:"true",
error:function(xhr) {
alert(xhr.status);
},
success:function(xml_data) {
alert(xml_data);
...
jQuery를 사용한 JSON Parsing
- XML Parsing보다 간단
{ "name":"김정윤", "age":30 }
dataType:"json",
success:function(json_obj) {
var name = json_obj.name; // 김정윤
var age = json_obj.age; // 30
}
- AJAX 사용, JSON 응답 예
<!-- json_result.jsp --><%@page import="org.json.simple.JSONObject"
%><%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"
%><%
String name="김정윤";
int age = 30;
JSONObject jsonObj = new JSONObject();
jsonObj.put("name", name);
jsonObj.put("age", age);
out.println(jsonObj.toJSONString());
%>
<!-- ajax_json.jsp -->
...
<script type="text/javascript">
$(function() {
$("#setValue").click(function() {
$.ajax({
url:"json_result.jsp",
type:"post",
dataType:"json",
error:function(xhr) {
alert(xhr.status+" / "+xhr.statusText);
},
success: function(jsonObj) {
$("#name").val(jsonObj.name);
$("#age").val(jsonObj.age);
}
});
});
}); // ready
</script>
...
<div>
<a href="#void" id="setValue">값 설정</a>
</div>
<div>
이름 : <input type="text" name="name" id="name" class="inputBox"/><br/>
나이 : <input type="text" name="age" id="age" class="inputBox"/>
</div>