JSON با Jackson، (بخش اول-معرفی)

JSON و XML دو ساختار رایج تبادل دادههای متنی هستند. بین این دو، JSON به دلیل توانایی سازماندهی مقدار برابری از داده در کاراکترهای کمتر، خوشخوان بودن برای انسان و سازگاری بیشتر با Java Script محبوبیت زیادی پیدا کرده است. در این مقاله بسته نرمافزاری محبوب کار با JSON در جاوا به نام Jackson معرفی میشود.
این نوشتار از سه بخش تشکیل شده است. در قسمت اول به نکاتی در مورد JSON اشاره میکنیم. بخش دوم، مثال ساده ای از کاربرد Jackson است و در انتها ماژولهای این بسته نرمافزاری را معرفی خواهیم کرد تا آماده ی طی بقیهی مسیر باشیم.
JSON
کامپیوترها نیازمند ارتباط با یکدیگرند. استفاده از پیامهای سادهی متنی اولین روش ارتباط بود اما به تدریج موجب بروز مشکلاتی شد که ناشی از وجود نداشتن هیچ استانداردی در تنظیم شکل پیامها بود. زبان گسترش پذیر XML که به خوبی سازمان یافته، برای انتقال اشکال مختلف داده معرفی شد. این زبان به حدی ساختیافته است که برخی، وجود این حد از قیود را محدودکننده میبینند. JSON جایگزین محبوب XML است که قواعد سبکتر و منعطفتری بر سازماندهی داده در قالب متنی وضع کرده است. این فرمت مستقل از زبانهای برنامهنویسی است. JSON در دنیای امروز، برای تبادل پیام در حجم بالا، برقرار ی ارتباط با وب سرویس های REST و ارتباطات AJAXای مورد استفاده قرار میگیرد. همچنین این فرمت توسط پایگاه دادههای NoSQL مانند MongoDB و Oracle NoSQL Database برای ذخیرهی رکوردهای JSONای به کار برده میشود. پایگاه دادههای رابطهای سنتی مانند PostgreSQL نیز امکانات بیشتری برای کار با JSON عرضه میکنند [DZone].
در دنیای جاوا به کرات مجبور به خواندن دادههای JSON ای یا تولید آنها خواهیم شد. پیش از این که دست به کار شده و شروع به نوشتن متدهایی برای تبدیل 1POJO ها به JSON و یا پردازش متن های JSON ای و تبدیل به POJO کنیم، باید ویژگیهایی که توسط Jackson عرضه شدهاند را بررسی کنیم. این کتابخانه یکی از کتابخانههای پر استفاده و برتر جاوا به شمار میرود که بر اساس مقالهی «صد کتابخانه برتر جاوا در سال 2016» در ردیف چهاردهمین کتابخانه پر استفاده در GitHub قرار گرفته است.
کاربرد Jackson
در این مثال یک شی POJO را به متن در قالب JSON تبدیل خواهیم کرد. برای این کار از کلاس ObjectMapper استفاده میکنیم. برای آن که بتوانیم در مرحلهی بعد، از متنی که تولید شده بود استفاده کنیم، آن را در یک فایل خواهیم نوشت. برای ساختن POJO از JSON، متنی که در مرحلهی قبل ساختهایم را به کار خواهیم گرفت.
تبدیل POJO به JSON
کلاس که شیای از آن را استفاده خواهیم کرد کلاس Employee است:
import java.util.List; public class Employee { private int id; private String firstName; private String lastName; private List<String> phoneNumbers; private Address address; // getters and setters @Override public String toString() { return "Employee:"+"\n"+"[id=" + id + "\n firstName=" + firstName + "\n lastName=" + lastName + "\n phoneNumbers=" + phoneNumbers + " \n address=" + address + "]"; } }
این کلاس دارای Property های متفاوتی است. id به نمایندگی از متغیر های primitive، متغیرهای firstName و lastName به نمایندگی از کلاس های موجود در API، متغیر phoneNumbers به نمایندگی از Collection ها و address به نمایندگی از کلاسهایی که توسط برنامهنویس تعریف میشوند، آورده شدهاند. کلاس Address به این صورت تعریف میشود:
public class Address { private String city; private String street; private int zipCode; //getters and setters @Override public String toString() { return "Address [city=" + city + ", street=" + street + ", zipCode=" + zipCode + "]"; } }
در ادامه توسط تابع زیر شیای از این کلاس را میسازیم:
import java.util.ArrayList; private static Employee createEmployee() { Employee employee = new Employee(); employee.setId(1); employee.setFirstName("John"); employee.setLastName("Smith"); ArrayList<String> phoneNumbers = new ArrayList<>(); phoneNumbers.add("09111111111"); phoneNumbers.add("09222222222"); employee.setPhoneNumbers(phoneNumbers); Address address = new Address(); address.setCity("Tehran"); address.setStreet("Enghelab"); address.setZipCode(12345); employee.setAddress(address); return employee; }
تبدیل به سادگی توسط Jackson تنها در یک سطر انجام می شود:
import java.io.File; import java.io.IOException; import com.fasterxml.jackson.databind.ObjectMapper; private static void pojo2Json(Employee emp) throws IOException { ObjectMapper objMapper = new ObjectMapper(); objMapper.writeValue(new File("Database.json"), emp); }
رشتهی نوشته شده در فایل Database.json به شکل زیر است:
{"id":1,"firstName":"John","lastName":"Smith","phoneNumbers":["09111111111","09222222222"],"address":{"city":"Tehran","street":"Enghelab","zipCode":12345}}
تبدیل JSON به POJO
تابع زیر وظیفهی تبدیل JSON به POJO و بازگرداندن آن را بر عهده دارد:
import com.fasterxml.jackson.core.JsonParseException; import com.fasterxml.jackson.databind.JsonMappingException; import java.io.IOException; import com.fasterxml.jackson.databind.ObjectMapper; private static Employee json2Pojo() throws JsonParseException, JsonMappingException, IOException { ObjectMapper objMapper = new ObjectMapper(); return objMapper.readValue(new File("Database.json"), Employee.class); }
خروجی زیر در Console از اجرای toString روی شیای از کلاس Empoyee تولید میشود.
Employee: [id=1 firstName=John lastName=Smith phoneNumbers=[09111111111, 09222222222] address=Address [city=Tehran, street=Enghelab, zipCode=12345]]
که نشان میدهد تبدیل با موفقیت انجام گرفته است.
ماژولها و نامگذاری Packageهای Jackson
بر اساس فایل README ماژول jackson-databind در گیت هاب، نامگذاری Packageها در ورژن اول و دوم تفاوت اساسی دارد. در نسخهی دوم نام پکیج com.fasterxml.jackson.databind است در حالی که در نسخهی یک org.codehaus.jackson.map بوده است.
از نسخهی دوم به بعد، این بستهی نرمافزاری به ماژولهای مجزایی تقسیم شده و با groupId و artifactId های متفاوتی نسبت به نسخهی اول در مخازن Maven عرضه میشود. نامگذاری این ماژولها در نگاه اول چندان قابل فهم نیستند. به همین دلیل آنها را در این قسمت بررسی میکنیم. مهمترین آنها به این شرحاند [منبع]:
Description | artifactId | groupId |
The core, which includes Streaming API, shared low-level abstractions (but NOT data-binding) | jackson-core | com.fasterxml.jackson.core |
Just the annotations | jackson-annotations | com.fasterxml.jackson.core |
Databinding; ObjectMapper, JsonNode and related classes are here | jackson-databind | com.fasterxml.jackson.core |
smile (binary JSON); Other artifacts in this group do other formats | jackson-dataformat-smile | com.fasterxml.jackson.dataformat |
JAX-RS provider | jackson-jaxrs-json-provider | com.fasterxml.jackson.jaxrs |
JAX-B annotations as additional configuration | jackson-module-jaxb-annotations | com.fasterxml.jackson.module |
در مقالههای بعدی با اصطلاحاتی مانند Streaming API که هستهی مرکزی این بسته نرمافزاری است بیشتر آشنا خواهیم شد. همچنین دو روش تسهیل شدهی کار با JSON که عبارتند از Tree Model و Data Binding؛ معرفی خواهیم کرد، یک مقالهی دو بخشی به شرح روش Data Binding اختصاص داده و در نهایت، در مقالهی پنجم، کاربرد Jackson در وب-سرویس بررسی خواهیم کرد.
منابع:
در نوشتن مجموعه مقالات حاضر، از منابع زیر استفاده شده است:
https://dzone.com/articles/processing-json-with-jackson
https://github.com/FasterXML/jackson-databind
https://github.com/FasterXML/jackson-docs
http://www.studytrails.com/java/json/java-jackson-introduction
http://www.cowtowncoder.com/blog/archives/cat_json.html
1- POJO: Plain Old Java Object
.
.
.
آدرس کانال تلگرام: JavaCupIR@
آدرس اکانت توییتر: JavaCupIR@
آدرس صفحه اینستاگرام: javacup.ir
آدرس گروه لینکدین: Iranian Java Developers
خیلی عالی
ممنون از نگارش خوانا و مفیدتان
منتظر ادامه مقالات هستیم