• Home
  • About
    • Young's Github Pages photo

      一日不作一日不食

    • About
    • Github
  • Posts
    • All Posts
    • All Tags
  • Projects

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을 사용한 화면의 일부분 변경 코드
         }
});

01

  • 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>
...

02

  • 응답받은 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);
            }
      });
});

03

  • 크롬은 Parameter값이 한글일 때 자동으로 인코딩 처리
    • ‘가’ -> %AA%BB%CC 같이 인코딩을 해줌
    • ie는 자동 인코딩을 해주지 않음
      • encodeURI()를 사용해야 함
var name=$("#name").val(); // ie에서 한글 입력 시 에러 발생
var queryString="name="+name;

04

// javascript의 encoding 함수 -> encodeURI()로 인코딩 해줘야 한다.
var queryString="name="+encodeURI(name);

05

  • 없는 jsp페이지로 요청하면 404 에러 발생
...
$.ajax({
      url:"text_result1.jsp",
...

06

  • 잘못된 코드로 서버에서 처리 후 응답을 받으면 500 에러 발생
<!-- text_result.jsp -->
...
<%= temp 

07

  • JSP에서는 줄변경에 신경을 많이 쓴다.
    • 줄바꿈은 태그 안에서만 수행!
    • 스크립트릿 줄바꿈 시 HTML 줄바꿈 처리가 되버린다.
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
    ...
%>
<%= temp %>

08

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%><%
      ...
%><%= temp %>

09

  • 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>
...

10

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);
%>

11

  • 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>
...

12

  • 잘못된 Parsing
    • XML안에 name 노드가 여럿 존재할 때 노드명으로 바로 파싱하면 한꺼번에 값이 나옴
success:function(xml_data) {
      alert($(xml_data).find("name").text());
}

13

  • 노드가 여럿일 때 올바른 Parsing
    • JDOM을 사용해서 Parsing하는 것 보다 jQuery를 이용하는게 훨씬 간단
success:function(xml_data) {
      var nameNodes = $(xml_data).find("name"); // 배열
      
      $.each(nameNodes,function(idx, nameNode) { // 하나씩 파싱
            alert($(this).text()); // this == nameNode
      });
}

14

  • 파싱한 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);
}

15

  • 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>
...

16

  • 부서정보를 여러번 누르면 계속 추가된다.
    • 한번만 들어가게 막는다.
    • 테이블에서 첫 행일때(데이터 추가 전)만 추가하도록 조건 추가

17

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 에러
    • 서버는 처리를 잘 했으나 응답받은 데이터가 잘못된 형식인 경우 발생하는 에러

18

  • 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);
...

19

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());
%>

20

<!-- 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>

21



Java EEAJAX