<< 학습 목표 >>
1. JSON 형식 데이터를 설명할 수 있다.
2. JSON 형식 데이터를 만들 수 있다.
3. JSON 형식 데이터를 Jquery의 Ajax를 사용해 서버로 보낼 수 있다.
4. 서버는 클라이언트가 보낸 JSON 형식 데이터를 꺼낼 수 있다.
실무에서는 데이터를 주고 받을 때 JSON 형식 데이터를 많이 활용함
아주 오래 전에는 XML을 많이 활용했음
JSON은 JavaScript Object Notation의 약자로 JS가 객체를 표현하는 데이터 형식임
이름
나이
키
연락처
홍길동
29세
167.1cm
010-1111-1111
위와 같은 정보를 JSON으로 표현하면 다음과 같음
<script>
let person = {
name: "홍길동",
age: 29,
height: 167.1,
tel: "010-1111-1111"
};
</script>
JSON은 { } 안에 name: value, name: value 의 형식으로 데이터를 표현함
value가 배열일 경우에는 [value, value, ...] 로 표현할 수 있음
<script>
let person = {
name: "홍길동",
age: 29,
height: 167.1,
tel: "010-1111-1111",
schoolList: ["대한초등학교", "민국중학교", "한국고등학교"]
};
</script>
이후에는 계속 같은 형식의 반복임
만약 JSON(객체) 안에 JSON(객체) 를 표현하고 싶다면 똑같은 형식이 반복됨
<script>
let person = {
name: "홍길동",
age: 29,
height: 167.1,
tel: "010-1111-1111",
school: {
name: "대한초등학교",
grade: "6학년",
classNumber: "1반",
studentNumber: "25번"
}
};
</script>
JSON 배열(객체 배열) 도 표현할 수 있음
<script>
let personList = [{name: "홍길동", age: 23}, {name: "고영희", age: 21}, {name: "김철수", age: 22}];
</script>
JSON을 문자열로 바꿔야하는 경우가 생기는데 그럴 때는 JSON.stringify 메서드를 사용하면 됨
<script>
let person = {
name: "홍길동",
age: 29,
height: 167.1,
tel: "010-1111-1111"
};
let str = JSON.stringify(person);
</script>
또는 문자열을 JSON으로 바꿔야하는 경우가 생기는데 그럴 때는 JSON.parse 메서드를 사용하면 됨
<script>
let str = '{"name":"홍길동","age":29,"height":167.1,"tel":"010-1111-1111"}';
let person = JSON.parse(str);
</script>
여기까지 JSON을 전부 알아봤음
굉장히 간단하면서 객체를 표현할 수 있기 때문에 실무에서 데이터를 주고 받을 때 주로 사용하는 데이터 형식임
여기서 끝내기 아쉬우니 Jquery의 Ajax를 사용해서 데이터를 보낼 때 JSON 데이터를 서버로 보내보자
먼저 서버로 JSON 데이터를 보낼 웹 페이지를 만들자
webapp -> chapter03 -> sendJson.html 을 만들고 아래 코드를 입력하자
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>서버로 JSON 데이터 보내기</title>
</head>
<body>
<button type="button">데이터 보내기</button>
<script src="https://code.jquery.com/jquery-3.6.3.min.js" integrity="sha256-pvPw+upLPUjgMXY0G+8O0xUf+/Im1MZjXxxgOcBQBXU=" crossorigin="anonymous"></script>
<script>
let json = {name: "홍길동", age: 21, height: 178.1};
$.ajax({
url: "/studyProject/chapter03/receive_json",
type: "POST",
contentType: "application/json",
data: JSON.stringify(json),
success: function() {
alert("서버가 제대로 데이터를 받았음");
},
error: function() {
alert("어떤 문제가 생겼음");
}
});
</script>
</body>
</html>
클라이언트가 서버로 JSON 데이터를 보낼 때 주의 할 점 두 가지가 있음
1. 보낼 데이터는 JSON.stringify 메서드를 사용해서 JSON 형식의 문자열로 변환해야함
2. 요청 정보의 헤더에 content-type을 "application/json" 으로 해야함
클라이언트가 아무런 형식이 없는 데이터를 보내는게 아니라 JSON 형식의 데이터를 보내기 때문에 서버에서 클라이언트가 보낸 JSON 데이터를 인식하려면 요청 정보의 헤더에 content-type을 "application/json" 으로 설정해줘야함
ajax 로 보낼 때 요청 정보의 헤더에 content-type을 "application/json" 으로하는 방법은 위와 같이 contentType: "application/json" 으로 지정하면 됨
이때! 대소문자 정확하게 입력해야함
[ 위 ] 와 같이 ajax 로 요청을 하게 되면 [ 아래 ] 와 같이 요청 정보가 생성되 서버로 전달됨
이제 클라이언트가 보낸 JSON 데이터를 받을 서블릿을 만들자
chapter03 -> ReceiveJson 서블릿을 만들고 아래 코드를 입력하자
package chapter03;
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;
@WebServlet("/chapter03/receive_json")
public class ReceiveJson extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
String name = request.getParameter("name");
String age = request.getParameter("age");
String height = request.getParameter("height");
System.out.println("name = " + name);
System.out.println("age = " + age);
System.out.println("height = " + height);
}
}
클라이언트가 보낸 JSON 데이터 안에 한글 이름이 있으므로 request.setCharacterEncoding 을 빠트리면 안됨
그 후 request.getParameter 메서드를 사용해서 클라이언트가 보낸 JSON 데이터의 name, age, height 값을 꺼냈음
이제 서버를 시작하고 웹 페이지에서 [ 데이터 보내기 ] 버튼을 클릭해보자
그랬더니 콘솔에 보이는 결과는??
읭?
분명 클라이언트가 보낸 데이터가 꺼내져야하는데 꺼내지 못하고 있음
그 이유는 getParameter 메서드에 있음
getParameter는 form 태그가 보낸 데이터만 인식해서 꺼낼 수 있는 메서드임
정확하게 얘기하면 요청 정보 헤더의 content-type이 application/x-www-form-urlencoded 이어야하고 URL이나 몸통(body)에 데이터 형식이 그에 맞게 name=value&name=value&... 형식으로 담겨있어야지 getParameter 메서드로 꺼낼 수 있음
그러나 우리가 보낸 요청 정보를 다시 보면 이와 같음
그래서 우리가 JSON 으로 데이터를 보냈을 때 서블릿이 getParameter 메서드로 꺼낼 수 없는 것
그럼 JSON으로 보낸 데이터는 꺼내지 못한다는걸까?
아님 다른 방식으로 꺼내야함
이제 서블릿의 doPost 메서드 내 코드를 아래와 같이 바꾸자
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
BufferedReader br = request.getReader();
String line = br.readLine();
System.out.println(line);
}
JSON으로 보낸 데이터를 꺼낼 때는 먼저 요청 정보(HttpServletRequest)에 들어있는 BufferedRead 객체를 꺼내야함(1)
그 후 JSON으로 보낸 데이터를 꺼냄(2), 이때 사용하는 readLine 메서드는 클라이언트가 보낸 JSON 형식의 문자열을 반환함
우선은 꺼낸 JSON 형식의 문자열을 간단하게 출력해봤음
꺼낸 JSON 형식의 문자열을 서버에 맞게 짤라서 사용해야함
앞 뒤에 있는 괄호 { } 를 짜르고(1) , 를 기준으로 분리(2)하면 String 배열에 이름:값 이 들어있게됨
이제 doPost에 필요한 나머지 코드를 더 넣어서 클라이언트가 보낸 JSON 데이터를 서버에서 꺼내서 출력해보자
( 코드가 많이 추가 됐으니 더음부터 천천히 살펴보고 정확히 입력하자 )
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
String name = null;
String age = null;
String height = null;
BufferedReader br = request.getReader();
String line = br.readLine();
line = line.substring(1, line.length()-1);
String[] keyValueList = line.split(",");
for(int i=0; i<keyValueList.length; i++) {
String keyValue = keyValueList[i];
String[] keyValueSet = keyValue.split(",");
String key = keyValueSet[0].replace("\"", "");
String value = keyValueSet[1].replace("\"", "");
if(key.equals("name")) {
name = value;
} else if(key.equals("age")) {
age = value;
} else if(key.equals("height")) {
height = value;
}
}
System.out.println("name = " + name);
System.out.println("age = " + age);
System.out.println("height = " + height);
}
이제 서버를 재시작하고 다시 웹 페이지에서 [ 데이터 보내기 ] 버튼을 누르면 클라이언트가 보낸 데이터를 서버가 꺼내서 출력하고 있다는걸 알 수 있음
doPost 내 모든 코드를 반드시 이해할 필요는 없음
모든 코드를 이해하는게 당연히 좋겠지만 이해하지 못했다고 하더라도 "클라이언트가 보낸 JSON 데이터를 서버에서 꺼내려면 이렇게 복잡한 방식으로 꺼내야하는구나" 정도로만 이해하도됨
좀 더 쉽게 클라이언트가 보낸 JSON 데이터를 꺼내보자
클라이언트가 보낸 JSON을 쉽게 꺼내려면 별도의 라이브러리가 필요함
먼저 라이브러리를 다운 받아서 프로젝트에 추가하자
구글에 다음과 같이 maven repository 로 검색(1)
그 후 나오는 첫 번째 검색 결과로 이동
만약 검색 결과가 이와 다르다면 직접 이동 ( https://mvnrepository.com/ )
그 후 [ java json ] 이라고 검색(1) 하자
그러면 자바에서 사용할 수 있는 JSON 라이브러리들이 나옴
첫 번째 검색 결과로 이동(2)
검색 결과 페이지로 들어가면 JSON in Java 라이브러리의 설명과 현재 공개된 버전들이 나와있는데(1) 여기서 적당한 버전을 선택하자
최신 버전을 선택해도 되고 적당히 몇 년 전 버전을 선택해도 됨
적당한 버전을 선택해 들어왔으면 거기서 이제 다운로드 받을 페이지로 이동하자(1)
다운로드 페이지에서 다음과 같이 jar 로 끝나는 파일 눌러 다운 받자(1)
jar 란 자바에서 사용할 수 있는 압축 파일의 형식
라이브러리 안에는 굉장히 많은 자바 소스 파일이 들어있음
이 굉장히 많은 자바 소스 파일을 압축 없이 공개하면 다운 받는데 굉장히 오래 걸리고 사용하는것도 굉장히 복잡함
그래서 빨리 다운 받고 간편하게 사용하기 위해 jar 형식으로 압축 되어있는 것
이제 다운 받은 jar 압축 파일을 이클립스 -> 프로젝트 -> src -> main -> webapp -> WEB-INF -> lib 폴더로 드래그 & 드롭하자
이렇게 자바에서 JSON을 사용할 수 있게 라이브러리를 추가했음
자바에서 JSON을 사용하려면 왜 라이브러리를 추가해야할까?
JSON의 약자를 잘 생각해보기!
만약 생각 안나면 다시 이 글의 처음으로 올라가서 보고 오기!
이제 본격적으로 서버에서 클라이언트가 보낸 JSON 데이터를 받아서 꺼내보자
코드는 굉장히 간단함
import org.json.JSONObject;
// ...
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
BufferedReader br = request.getReader();
JSONObject jo = new JSONObject(br.readLine());
String name = jo.getString("name");
int age = jo.getInt("age");
double height = jo.getDouble("height");
System.out.println("name = " + name);
System.out.println("age = " + age);
System.out.println("height = " + height);
}
클라이언트가 보낸 JSON 데이터를 꺼내기 위해 우선 요청 정보(HttpServletRequest)의 BufferedReader 객체를 꺼냄(1)
클라이언트가 보낸 JSON 데이터를 꺼낸 후 JSONObject 클래스 생성자의 인스턴스로 넣어줌(2)
그러면 JSONObejct 클래스 생성자 안에서 여러 처리를 거쳐 jo 객체 안에 클라이언트가 보낸 JSON 데이터가 들어있게 됨
jo 객체가 가지고 있는 값을 꺼낼 때는 꺼낼 값의 형태를 잘 생각해야함
jo 객체가 가지고 있는 값을 문자열로 꺼낼 때는 getString 메서드를 사용함(1)
jo 객체가 가지고 있는 값을 정수로 꺼낼 때는 getInt 메서드를 사용함(2)
jo 객체가 가지고 있는 값을 실수값으로 꺼낼 때는 getDouble 메서드를 사용함(3)
여기까지 길고 길었던~!
클라이언트가 보낸 JSON 데이터를 서버가 꺼내는 방법을 배웠음
그러나 여기서 한가지 언급하자면 여러분이 취업 준비는 동안에는 클라이언트가 JSON 데이터를 보낼 일도 없을 것이고 그에 따라 서버에서도 클라이언트가 보낸 JSON 데이터를 꺼내는 일도 없을 것
취업을 하게 되면
1. 앱에서 보내는 데이터를 서버가 받아야하고
2. 웹에서 보내는 데이터를 서버가 받아야하고
3. 기타 여러 기기에서 보내는 데이터를 서버가 받아야하는
경우가 생김
이런 경우에 서버가 JSON 데이터를 받아야하는 경우가 생겨 알아야함
취업을 하기 전에는 보통 웹과 통신하는 서버만 만드니 "서버가 JSON 데이터를 받으려면 굉장히 복잡하구나" 정도로만 기억해두면 나중에 취업해서 이런 상황이 생기면 "아! 인터넷에서 찾아봐야겠다" 가 떠오를 것