ברוכים הבאים למדריך לדוגמת Java JSON. JSON (JavaScript Object Notation) הוא טכנולוגיה קלה במבנה המבוססת טקסט, המיועדת ליצירת נתונים מסודרים שניתן לקרוא בקלות על ידי בני אדם. JSON מייצג נתונים בצורת זוגות מפתח-ערך. בנוסף, ניתן להשתמש באובייקטים מקוננים ב-JSON והוא מספק דרך פשוטה לייצג מערכים גם.
Java JSON
JSON משמש בצורה רחבה ביישומי אינטרנט או כתגובת שרת מכיוון שהוא קל וקומפקטי יותר מ-XML. אובייקטים ב-JSON קלים לקריאה ולכתיבה ורוב הטכנולוגיות מספקות תמיכה באובייקטים מסוג JSON. לכן, JSON בשירותי Java web הם פופולריים מאוד. סוף סוף, הכלל JSR353 הוסף את תהליך הטקסט ב-Java EE 7 וזו היא חבילת ה-Java JSON Processing API. jsonp היא ביצוע הפניה ל-Java JSON Processing API. ניתן להשתמש בזה בפרויקט Maven על ידי הוספת תלות הבאה.
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.json</artifactId>
<version>1.0.2</version>
</dependency>
אם אתה משתמש ב-GlassFish 4.0, ניתן להשאיר את הסוג כ-Provided מאחר והוא כבר מוכל בשרת. JSON API מספק שני דרכים לעיבוד JSON:
- Object Model API – זה דומה ל- DOM Parser ומתאים לאובייקטים קטנים.
- Streaming API – זה דומה ל־מפענח StaX ושימושי לאובייקטים גדולים שברצונך להישמר בזיכרון רק חלק מהם.
ממשקים חשובים ב-Java JSON API הם:
- javax.json.JsonReader: ניתן להשתמש בזה כדי לקרוא אובייקט JSON או מערך לתוך JsonObject. ניתן לקבל JsonReader מתוך המחלקה Json או JsonReaderFactory.
- javax.json.JsonWriter: ניתן להשתמש בזה כדי לכתוב אובייקט JSON לזרם הפלט.
- javax.json.stream.JsonParser: עובד כ־pull parser ומספק תמיכה בזרימה לקריאת אובייקטי JSON.
- javax.json.stream.JsonGenerator: ניתן להשתמש בזה כדי לכתוב אובייקט JSON למקור הפלט בדרך של זרימה.
- javax.json.Json: זוהי מחלקת מפענח עבור יצירת אובייקטי עיבוד JSON. מחלקה זו מספקת את השיטות הנפוצות ביותר ליצירת אלו וליצירת המפענחים המתאימים. מחלקות המפענח מספקות את כל הדרכים השונות ליצירת אלו.
- javax.json.JsonObject: JsonObject מייצג ערך אובייקט JSON בלתי ניתן לשנות.
בואו נסתכל על שימוש ב-Java JSON API עם תוכנית פשוטה, יש לנו אובייקט JSON מאוחסן בקובץ employee.txt כמו שנראה בתיקייה הבאה;
{
"id":123,
"name":"Pankaj Kumar",
"permanent":true,
"address":{
"street":"El Camino Real",
"city":"San Jose",
"zipcode":95014
},
"phoneNumbers":[9988664422, 1234567890],
"role":"Developer"
}
יש לנו מחלקות Java Bean שמייצגות את התבנית JSON לעיל.
package com.journaldev.model;
import java.util.Arrays;
public class Employee {
private int id;
private String name;
private boolean permanent;
private Address address;
private long[] phoneNumbers;
private String role;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public boolean isPermanent() {
return permanent;
}
public void setPermanent(boolean permanent) {
this.permanent = permanent;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
public long[] getPhoneNumbers() {
return phoneNumbers;
}
public void setPhoneNumbers(long[] phoneNumbers) {
this.phoneNumbers = phoneNumbers;
}
public String getRole() {
return role;
}
public void setRole(String role) {
this.role = role;
}
@Override
public String toString(){
StringBuilder sb = new StringBuilder();
sb.append("***** Employee Details *****\n");
sb.append("ID="+getId()+"\n");
sb.append("Name="+getName()+"\n");
sb.append("Permanent="+isPermanent()+"\n");
sb.append("Role="+getRole()+"\n");
sb.append("Phone Numbers="+Arrays.toString(getPhoneNumbers())+"\n");
sb.append("Address="+getAddress());
sb.append("\n*****************************");
return sb.toString();
}
}
package com.journaldev.model;
public class Address {
private String street;
private String city;
private int zipcode;
public String getStreet() {
return street;
}
public void setStreet(String street) {
this.street = street;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public int getZipcode() {
return zipcode;
}
public void setZipcode(int zipcode) {
this.zipcode = zipcode;
}
@Override
public String toString(){
return getStreet() + ", "+getCity()+", "+getZipcode();
}
}
I have overridden the toString() method to return human readable String representation that we will use in our JSON implementation classes.
דוגמת קריאה ל־JSON ב־Java
package com.journaldev.json;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import javax.json.Json;
import javax.json.JsonArray;
import javax.json.JsonObject;
import javax.json.JsonReader;
import javax.json.JsonValue;
import com.journaldev.model.Address;
import com.journaldev.model.Employee;
public class EmployeeJSONReader {
public static final String JSON_FILE="employee.txt";
public static void main(String[] args) throws IOException {
InputStream fis = new FileInputStream(JSON_FILE);
// יצירת אובייקט JsonReader
JsonReader jsonReader = Json.createReader(fis);
/**
* We can create JsonReader from Factory also
JsonReaderFactory factory = Json.createReaderFactory(null);
jsonReader = factory.createReader(fis);
*/
// קבלת JsonObject מ־JsonReader
JsonObject jsonObject = jsonReader.readObject();
// ניתן לסגור משאבי IO ו־JsonReader כעת
jsonReader.close();
fis.close();
// אחזור נתונים מתוך JsonObject ויצירת אובייקט Employee
Employee emp = new Employee();
emp.setId(jsonObject.getInt("id"));
emp.setName(jsonObject.getString("name"));
emp.setPermanent(jsonObject.getBoolean("permanent"));
emp.setRole(jsonObject.getString("role"));
// קריאת מערכים מתוך json
JsonArray jsonArray = jsonObject.getJsonArray("phoneNumbers");
long[] numbers = new long[jsonArray.size()];
int index = 0;
for(JsonValue value : jsonArray){
numbers[index++] = Long.parseLong(value.toString());
}
emp.setPhoneNumbers(numbers);
// קריאת אובייקט פנימי מתוך אובייקט json
JsonObject innerJsonObject = jsonObject.getJsonObject("address");
Address address = new Address();
address.setStreet(innerJsonObject.getString("street"));
address.setCity(innerJsonObject.getString("city"));
address.setZipcode(innerJsonObject.getInt("zipcode"));
emp.setAddress(address);
// הדפסת מידע על אובייקט העובד
System.out.println(emp);
}
}
היישום ישיר ונרגש דומה לקבלת פרמטרים מ־HashMap. JsonReaderFactory מיישם תבנית עיצוב של מפעיל. בעת ביצוע התוכנית לעיל, נקבל את הפלט הבא.
***** Employee Details *****
ID=123
Name=Pankaj Kumar
Permanent=true
Role=Developer
Phone Numbers=[9988664422, 1234567890]
Address=El Camino Real, San Jose, 95014
*****************************
דוגמת כתיבה ל־JSON ב־Java
package com.journaldev.json;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.OutputStream;
import javax.json.Json;
import javax.json.JsonArrayBuilder;
import javax.json.JsonObject;
import javax.json.JsonObjectBuilder;
import javax.json.JsonWriter;
import com.journaldev.model.Address;
import com.journaldev.model.Employee;
public class EmployeeJSONWriter {
public static void main(String[] args) throws FileNotFoundException {
Employee emp = createEmployee();
JsonObjectBuilder empBuilder = Json.createObjectBuilder();
JsonObjectBuilder addressBuilder = Json.createObjectBuilder();
JsonArrayBuilder phoneNumBuilder = Json.createArrayBuilder();
for (long phone : emp.getPhoneNumbers()) {
phoneNumBuilder.add(phone);
}
addressBuilder.add("street", emp.getAddress().getStreet())
.add("city", emp.getAddress().getCity())
.add("zipcode", emp.getAddress().getZipcode());
empBuilder.add("id", emp.getId())
.add("name", emp.getName())
.add("permanent", emp.isPermanent())
.add("role", emp.getRole());
empBuilder.add("phoneNumbers", phoneNumBuilder);
empBuilder.add("address", addressBuilder);
JsonObject empJsonObject = empBuilder.build();
System.out.println("Employee JSON String\n"+empJsonObject);
// כתיבה לקובץ
OutputStream os = new FileOutputStream("emp.txt");
JsonWriter jsonWriter = Json.createWriter(os);
/**
* We can get JsonWriter from JsonWriterFactory also
JsonWriterFactory factory = Json.createWriterFactory(null);
jsonWriter = factory.createWriter(os);
*/
jsonWriter.writeObject(empJsonObject);
jsonWriter.close();
}
public static Employee createEmployee() {
Employee emp = new Employee();
emp.setId(100);
emp.setName("David");
emp.setPermanent(false);
emp.setPhoneNumbers(new long[] { 123456, 987654 });
emp.setRole("Manager");
Address add = new Address();
add.setCity("Bangalore");
add.setStreet("BTM 1st Stage");
add.setZipcode(560100);
emp.setAddress(add);
return emp;
}
}
בעת הרצת היישום לעיל, נקבל את התגובה הבאה:
Employee JSON String
{"id":100,"name":"David","permanent":false,"role":"Manager","phoneNumbers":[123456,987654],"address":{"street":"BTM 1st Stage","city":"Bangalore","zipcode":560100}}
האובייקט JSON גם נשמר בקובץ emp.txt. JsonObjectBuilder מיישם תבנית בניה שהופכת אותו לקל מאוד לשימוש.
דוגמה לפענוח Java JSON
JsonParser ב-Java הוא pull parser ואנו קוראים את האיבר הבא באמצעות השיטה next() שמחזירה אובייקט אירוע. javax.json.stream.JsonParser.Event
הוא Enum שהופך את השימוש בו לבטוח וקל. אנו יכולים להשתמש בתוך switch case כדי להגדיר את מאפייני גוש ה-Java שלנו.
package com.journaldev.json;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import javax.json.Json;
import javax.json.stream.JsonParser;
import javax.json.stream.JsonParser.Event;
import com.journaldev.model.Address;
import com.journaldev.model.Employee;
public class EmployeeJSONParser {
public static final String FILE_NAME = "employee.txt";
public static void main(String[] args) throws IOException {
InputStream fis = new FileInputStream(FILE_NAME);
JsonParser jsonParser = Json.createParser(fis);
/**
* We can create JsonParser from JsonParserFactory also with below code
* JsonParserFactory factory = Json.createParserFactory(null);
* jsonParser = factory.createParser(fis);
*/
Employee emp = new Employee();
Address address = new Address();
String keyName = null;
List phoneNums = new ArrayList();
while (jsonParser.hasNext()) {
Event event = jsonParser.next();
switch (event) {
case KEY_NAME:
keyName = jsonParser.getString();
break;
case VALUE_STRING:
setStringValues(emp, address, keyName, jsonParser.getString());
break;
case VALUE_NUMBER:
setNumberValues(emp, address, keyName, jsonParser.getLong(), phoneNums);
break;
case VALUE_FALSE:
setBooleanValues(emp, address, keyName, false);
break;
case VALUE_TRUE:
setBooleanValues(emp, address, keyName, true);
break;
case VALUE_NULL:
// אל תגדיר כלום
break;
default:
// אנו לא מחפשים אחר אירועים אחרים
}
}
emp.setAddress(address);
long[] nums = new long[phoneNums.size()];
int index = 0;
for(Long l :phoneNums){
nums[index++] = l;
}
emp.setPhoneNumbers(nums);
System.out.println(emp);
// סגור משאבים
fis.close();
jsonParser.close();
}
private static void setNumberValues(Employee emp, Address address,
String keyName, long value, List phoneNums) {
switch(keyName){
case "zipcode":
address.setZipcode((int)value);
break;
case "id":
emp.setId((int) value);
break;
case "phoneNumbers":
phoneNums.add(value);
break;
default:
System.out.println("Unknown element with key="+keyName);
}
}
private static void setBooleanValues(Employee emp, Address address,
String key, boolean value) {
if("permanent".equals(key)){
emp.setPermanent(value);
}else{
System.out.println("Unknown element with key="+key);
}
}
private static void setStringValues(Employee emp, Address address,
String key, String value) {
switch(key){
case "name":
emp.setName(value);
break;
case "role":
emp.setRole(value);
break;
case "city":
address.setCity(value);
break;
case "street":
address.setStreet(value);
break;
default:
System.out.println("Unknown Key="+key);
}
}
}
המורכבות המרכזית מתגלה כאשר אנו צריכים לכתוב את הלוגיקה לפענוח הנתונים, ולפעמים זה יכול להסתבך. מכיוון שאנו קוראים את אותו קובץ כמו JsonReader, הפלט זהה לתוכנית EmployeeJsonReader.
דוגמה ליצירת JSON ב-Java
package com.journaldev.json;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import javax.json.Json;
import javax.json.stream.JsonGenerator;
import com.journaldev.model.Employee;
public class EmployeeJSONGenerator {
public static void main(String[] args) throws IOException {
OutputStream fos = new FileOutputStream("emp_stream.txt");
JsonGenerator jsonGenerator = Json.createGenerator(fos);
/**
* We can get JsonGenerator from Factory class also
* JsonGeneratorFactory factory = Json.createGeneratorFactory(null);
* jsonGenerator = factory.createGenerator(fos);
*/
Employee emp = EmployeeJSONWriter.createEmployee();
jsonGenerator.writeStartObject(); // {
jsonGenerator.write("id", emp.getId()); // "id":123
jsonGenerator.write("name", emp.getName());
jsonGenerator.write("role", emp.getRole());
jsonGenerator.write("permanent", emp.isPermanent());
jsonGenerator.writeStartObject("address") //start of address object
.write("street", emp.getAddress().getStreet())
.write("city",emp.getAddress().getCity())
.write("zipcode",emp.getAddress().getZipcode())
.writeEnd(); //end of address object
jsonGenerator.writeStartArray("phoneNumbers"); //start of phone num array
for(long num : emp.getPhoneNumbers()){
jsonGenerator.write(num);
}
jsonGenerator.writeEnd(); // end of phone num array
jsonGenerator.writeEnd(); // }
jsonGenerator.close();
}
}
JsonGenerator הוא קל לשימוש מאוד ומספק ביצועים טובים למידע גדול. זהו כל מה שיש לנו לשתף פעולה עם Java JSON Processing API. למדנו על פענוח וכתיבה ב-Java JSON. ניתן להוריד את פרויקט ה-Java מהקישור למטה ולשחק איתו.
הפניות: JSONLint – כלי אינטרנט מצוין לאימות נתוני JSON מימוש התיקול של JSON עמוד JSR353 של JCP
Source:
https://www.digitalocean.com/community/tutorials/java-json-example