Java EE 정리 22
28 Mar 2019
Reading time ~4 minutes
Java EE 정리 22 - JSON, AJAX
JSON(JavaScript Object Notation)
- Java로 JSON 데이터를 만들고 AJAX로 이용해서 사용
- 이기종 언어간의 데이터 전달용
- XML과 동일한 목적
- JSON은 환경설정엔 쓰이지 않음
- XML에 비해 데이터의 총량이 적음
<?xml version="1.0" encoding="UTF-8"?>
<names>
<name>김정윤</name>
</names>
{ "name": "김정윤" }
json-simple 설치
- JSONSimple.jar는 JSON을 위한 외부라이브러리
- JSONObject, JSONArray를 쉽게 만들 수 있다.
- WEB-INF/lib에 설치
Java로 JSON 만들기
- JSON Object 생성
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
String name = "오영근";
int age = 30;
%>
{ "name":"<%= name %>", "age": <%=age %> }
- JSON Array 생성
<%
String[] nameArr={"김정윤","김희철","박영민","노진경"};
int[] ageArr = {30,28,27,32};
%>
[
<%
for(int i=0; i < nameArr.length;) {
%>
{"name":"<%= nameArr[i] %>","age":<%= ageArr[i] %>}
<%
i++; // 배열 마지막일 땐 ,를 안찍음
if (nameArr.length != i) { // 마지막 콤마 없애기
out.println(",");
}
}
%>
]
json-simple로 JSON 만들기
- JSON Object 생성
<%
// 1. 객체 생성
JSONObject jo = new JSONObject();
// 2. 값 할당, 문자열, 숫자, 불린, JSONObject, JSONArray를 할당가능
jo.put("key1", 10);
jo.put("key2", false);
jo.put("key3", "value3");
// 3. JSON 객체가 가진 값을 문자열로 생성
out.println(jo.toJSONString());
%>
<%
String name="오영근";
int age = 30;
JSONObject json = new JSONObject(); // { }
json.put("name", name); // { "name":"오영근" }
json.put("age", age); // { "name":"오영근", "age",30 }
out.println(json.toJSONString());
%>
- JSON Array 생성
<%
// 1. JSON Array 생성
JSONArray jsonArr = new JSONArray(); // [ ]
// 2. 값 할당 (JSON Object)
JSONObject jo1 = new JSONObject();
jo1.put("이름1-1", "값1");
jo1.put("이름1-2", "값2");
// 값이 순차적으로 들어가진 않음
jsonArr.add(jo1); // [{"이름1-1":"값1","이름1-2":"값2"}]
JSONObject jo2 = new JSONObject();
jo2.put("이름2-1", "값1");
jo2.put("이름2-2", "값2");
jsonArr.add(jo2); // [{...},{...}]
out.println(jsonArr.toJSONString());
%>
- json-simple을 이용하면 JSONArray를 쉽게 만들 수 있다.
<%
String[] nameArr={"김정윤","김희철","박영민","노진경"};
int[] ageArr = {30,28,27,32};
JSONArray jsonArr = new JSONArray();
JSONObject jsonObj = null;
for(int i=0; i < nameArr.length;i++) {
// 배열이 존재한다면 JSONObject를 생성
jsonObj = new JSONObject();
jsonObj.put("name", nameArr[i]);
jsonObj.put("age", ageArr[i]);
jsonArr.add(jsonObj); // 생성된 JSONObject를 JSONArray에 추가
}
out.println(jsonArr.toJSONString());
%>
- DB연동해서 JSON Object 만들기
- DAO엔 DB업무만, 업무로직은 Service에서 처리
public class EmpVO {
private int empno, sal;
private String ename, job, hiredate;
// 기본,인자있는 생성자, getter, setter
...
public class JsonEmpSearchDAO { // DAO, DB업무만 수행
private static JsonEmpSearchDAO j_dao;
private JsonEmpSearchDAO() {} // 싱글턴 패턴
public static JsonEmpSearchDAO getInstance() {
if (j_dao == null) {
j_dao = new JsonEmpSearchDAO();
}
return j_dao;
}
public Connection getConn() throws SQLException {
Connection con = null;
try {
// DBCP
Context ctx = new InitialContext();
System.out.println(ctx);
DataSource ds = (DataSource)ctx.lookup("java:comp/env/jdbc/jsp_dbcp");
System.out.println(ds);
con = ds.getConnection();
} catch (NamingException e) {
e.printStackTrace();
}
return con;
}
public List<EmpVO> selectEmpList(int deptno) throws SQLException {
List<EmpVO> list = new ArrayList<EmpVO>();
Connection con = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
con = getConn();
StringBuilder selectEmp = new StringBuilder();
selectEmp
.append(" select empno, ename, job, to_char(hiredate,'yyyy-MM-dd') hiredate, sal ")
.append(" from emp ")
.append(" where deptno = ? ")
.append(" order by sal ");
pstmt = con.prepareStatement(selectEmp.toString());
pstmt.setInt(1, deptno);
rs = pstmt.executeQuery();
EmpVO evo = null;
while(rs.next()) {
evo = new EmpVO(rs.getInt("empno"), rs.getInt("sal"),
rs.getString("ename"), rs.getString("job"),
rs.getString("hiredate"));
list.add(evo);
}
} finally {
if (rs != null) { rs.close(); }
if (pstmt != null) { pstmt.close(); }
if (con != null) { con.close(); }
}
return list;
}
}
public class JsonService { // Service, 업무로직 수행
public JSONObject searchEmpData(int deptno) {
JSONObject jsonObj = new JSONObject();
JsonEmpSearchDAO j_dao = JsonEmpSearchDAO.getInstance();
try {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
jsonObj.put("pubDate", sdf.format(new Date()));
List<EmpVO> list = j_dao.selectEmpList(deptno);
jsonObj.put("result", !list.isEmpty());
EmpVO evo = null;
// jsonObj에 넣을 JSONArray
JSONArray jsonArr = new JSONArray();
JSONObject tempObj = null;
for(int i=0; i<list.size(); i++) {
tempObj = new JSONObject();
evo = list.get(i);
tempObj.put("empno", evo.getEmpno());
tempObj.put("ename", evo.getEname());
tempObj.put("job", evo.getJob());
tempObj.put("hiredate", evo.getHiredate());
tempObj.put("sal", evo.getSal());
// JSONArry에 JSONObject들을 추가
jsonArr.add(tempObj);
}
// 조회된 결과를 가진 JSONArry를 JSONObject에 추가
jsonObj.put("resultData", jsonArr);
} catch (SQLException e) {
jsonObj.put("result", false);
e.printStackTrace();
}
return jsonObj;
}
}
<!-- request_jso.jsp -->
<%@page import="org.json.simple.JSONObject"%>
<%@page import="date0328.JsonService"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
String deptno = request.getParameter("deptno");
if (deptno == null) {
deptno = "10";
}
int intDeptno = Integer.parseInt(deptno);
JsonService jsonService = new JsonService();
JSONObject jsonObj = jsonService.searchEmpData(intDeptno);
out.println(jsonObj.toJSONString());
%>
AJAX(Asynchronous JavaScript And XML)
- 비동기로 동작하는 JavaScript와 XML
- 요즘엔 XML보다 JSON을 많이 사용
- RIA (Rich Internet Application)
- 기존의 웹 서비스와 다르게 클라이언트의 자원을 더 많이 사용하는 인터넷 애플리케이션
- 동기방식
- Web Service를 할 때 서버가 업무처리를 종료하고 난 이후에 클라이언트에게 응답하는 방식
- 지금까지 해온 a태그, form태그, location를 이용해서 Web Browser가 서버에게 요청한 방식
- 요청한 응답이 생성되어 전달될 때까지 HTML을 다시 그리기 위해 브라우저를 초기화
- 화면 일부분의 데이터가 변경되더라도 화면 전체를 새로 받아와서 새로 그린다.
- 네트워크의 사용 비용이 높다.
- 화면 깜빡임이 발생한다.
- 처음부터 끝까지 화면(HTML)을 모두 구현 후 응답
- 서버가 많은 일을 한다
- Web Service를 할 때 서버가 업무처리를 종료하고 난 이후에 클라이언트에게 응답하는 방식
- 비동기 방식
- Web Service를 할 때 서버가 업무처리를 종료하기도 전에 클라이언트에게 응답하여 클라이언트가 서비스를 계속해서 사용할 수 있는 방식
- JavaScript의 XMLHttpRequest 객체를 사용하여 요청을 보내는 방식
- 서버가 처리한 데이터만 받아 화면에 일부분을 변경하여 보여준다.
- 화면(HTML)을 받지 않고 데이터를 받는다.
- 서버가 처리한 데이터는 XML, JSON, HTML(비권장), Text(CSV)
- HTML이면 서버가 일을 더 많이함
- 화면의 일부분은 DOM을 사용해서 변경
- 데이터만 주고받으므로 네트워크 사용비용이 낮다.
- 화면 일부분만 갱신하므로 화면깜빡임이 발생하지 않음
- 데이터만 변경되기 때문에 이전 상태로 돌아가기 어렵다.