Jackson เป็นไลบรารียอดนิยมสำหรับการทำซีเรียลไลซ์/ดีซีเรียลไลซ์อ็อบเจ็กต์ Java ให้เป็นรูปแบบข้อความต่างๆ คลาส ObjectMapper เป็นวิธีหลักของไลบรารีในการทำงานกับรูปแบบJSON สำหรับรูปแบบอื่นๆ เรามีส่วนสืบทอด ( XmlMapper , YAMLMapper ) ต้องขอบคุณการสืบทอด เราจึงสามารถทำงานกับรูปแบบทั้งหมดได้อย่างสอดคล้องกันผ่านอินเทอร์เฟซเดียว

ดาวน์โหลดไฟล์ jar

ก่อนศึกษาตัวอย่าง เราจำเป็นต้องดาวน์โหลดไฟล์ Jackson jar และเชื่อมต่อกับโครงการใน IntelliJ IDEA ลองมาดูตัวอย่างjackson-databindเพื่อดูวิธีค้นหาไฟล์ที่ต้องการ:

  1. ไปที่เว็บไซต์Maven Repository

  2. ป้อน " jackson-databind " ในช่องค้นหา คุณจะได้รับสิ่งต่อไปนี้:

  3. ผลการค้นหาแรกคือสิ่งที่เราสนใจตามลิงค์

  4. บางครั้งอาจจำเป็นต้องใช้ไลบรารีเวอร์ชันหนึ่งๆ เพื่อให้แน่ใจว่าเข้ากันได้กับคอมโพเนนต์อื่นๆ ในโครงการ เวอร์ชันล่าสุดควรใช้งานได้ (ในขณะที่เขียนบทเรียนนี้คือ 2.13.2.2) ตามลิงค์

  5. ในหน้าที่เปิดขึ้น คุณต้องการลิงค์ "มัด":

  6. ดาวน์โหลดไฟล์ jar โดยใช้ลิงค์นี้

ทำตามขั้นตอนที่คล้ายกัน คุณสามารถค้นหาและดาวน์โหลดไฟล์ jar ที่จำเป็นที่เหลือ:

หลังจากดาวน์โหลดไฟล์ที่จำเป็นทั้งหมดแล้ว ให้เชื่อมต่อกับโครงการใน IntelliJ IDEA:

  1. เปิดการตั้งค่าโปรเจ็กต์ (คุณสามารถทำได้โดยใช้ คีย์ผสม Ctrl+Alt+Shift+S )

  2. ไปที่ห้องสมุด

  3. กด+แล้วตามด้วย "Java" เลือกไฟล์ที่ดาวน์โหลดทั้งหมด นี่คือสิ่งที่เราควรลงเอยด้วย:

  4. สรุปงานเตรียมการของเรา ตอนนี้เราสามารถทดลองใช้งานObjectMapper ได้แล้ว

การทำให้เป็นอันดับเป็น JSON

ก่อนอื่น มาทำให้วัตถุบางตัวเป็น JSON:


import com.fasterxml.jackson.databind.ObjectMapper;
 
class Book {
	public String title;
	public String author;
	public int pages;
}
 
public class Solution {
	public static void main(String[] args) throws Exception {
    	Book book = new Book();
    	book.title = "Good Omens";
    	book.author = "Pratchett T., Gaiman N.";
    	book.pages = 383;
 
    	ObjectMapper mapper = new ObjectMapper();
    	String jsonBook = mapper.writeValueAsString(book);
    	System.out.println(jsonBook);
	}
}

การรันmainจะให้ผลลัพธ์นี้แก่คุณ:

{"title":"ลางดี","author":"Pratchett T., Gaiman N","pages":383}

ObjectMapper มีการตั้ง ค่าขั้นสูงมากมาย ลองใช้หนึ่งในนั้นเพื่อทำให้สตริง JSON อ่านง่ายขึ้น หลังจากสร้างObjectMapperวัตถุ ดำเนินการคำสั่งนี้:

mapper.enable (SerializationFeature.INDENT_OUTPUT);

ข้อมูลในเอาต์พุตยังคงเหมือนเดิม แต่ตอนนี้มีการเยื้องและตัวแบ่งบรรทัด:

{
  "ชื่อ" : "ลางดี",
  "ผู้เขียน" : "Pratchett T., Gaiman N. ",
 "หน้า" : 383
}

การดีซีเรียลไลเซชันจาก JSON

ตอนนี้ มาทำสิ่งที่ตรงกันข้ามกัน: เราจะแยกซีเรียลไลซ์สตริงออกเป็นอ็อบเจกต์ เพื่อดูว่าโปรแกรมกำลังทำอะไรอยู่ ลองแทนที่เมธอดtoStringใน คลาส Book :


@Override
public String toString() {
	return "Book{" +
        	"title='" + title + '\'' +
        	", author='" + author + '\'' +
        	", pages=" + pages +
        	'}';
}

และเราจะดำเนินการต่อไปนี้ใน วิธีการ หลัก :


public static void main(String[] args) throws Exception {
	String jsonString = "{\"title\":\"Good Omens\",\"author\":\"Pratchett T., Gaiman N.\",\"pages\":383}";
	Book book = new ObjectMapper().readValue(jsonString, Book.class);
	System.out.println(book);
}

เอาท์พุต:

หนังสือ{title='Good Omens', ผู้แต่ง='Pratchett T., Gaiman N.', หน้า=383}

เมธอดreadValueโอเวอร์โหลด — มีรูปแบบต่างๆ มากมายที่ใช้ไฟล์ ลิงก์ สตรีมอินพุตต่างๆ ฯลฯ เพื่อความง่าย ตัวอย่างของเราใช้ตัวแปรที่ยอมรับสตริง JSON

ตามที่กล่าวไว้ข้างต้นObjectMapperมีการตั้งค่ามากมาย ลองดูที่บางส่วนของพวกเขา

ละเว้นคุณสมบัติที่ไม่รู้จัก

พิจารณาสถานการณ์ที่สตริง JSON มีคุณสมบัติที่ไม่มีอยู่ใน คลาส Book :


public static void main(String[] args) throws Exception {
	String jsonString = """
        	{
          	"title" : "Good Omens",
          	"author" : "Pratchett T., Gaiman N.",
          	"pages" : 383,
          	"unknown property" : 42
        	}""";
	ObjectMapper mapper = new ObjectMapper();
	Book book = mapper.readValue(jsonString, Book.class);
	System.out.println(book);
}

การดำเนินการโค้ดนี้ทำให้เราได้รับUnrecognizedPropertyException นี่เป็นลักษณะการทำงานเริ่มต้น แต่เราสามารถเปลี่ยนได้:


ObjectMapper mapper =
new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

เมื่อสร้างObjectMapperวัตถุ เราใช้ วิธี กำหนดค่าเพื่อตั้งค่าที่เกี่ยวข้องเป็นเท็จ เมธอดconfigurationจะแก้ไขอ็อบเจกต์ที่ถูกเรียก จากนั้นส่งคืนอ็อบเจกต์เดียวกัน ดังนั้นเราจึงสามารถเรียกด้วยวิธีอื่นได้:


ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

ในแง่ของการทำงาน สัญกรณ์นี้ก็เหมือนกับก่อนหน้านี้

หากเราเรียกใช้ เมธอด หลักการดีซีเรียลไลเซชันจะสำเร็จและคุณสมบัติที่ไม่รู้จักจะถูกละเว้น

คำอธิบายประกอบที่สะดวก

Jackson ให้คำอธิบายประกอบหลายรายการแก่เรา ซึ่งช่วยให้เราปรับแต่งกระบวนการออกหมายเลขกำกับได้ทุกรูปแบบ ลองมาดูสิ่งที่มีประโยชน์มากที่สุด:

@JsonIgnore — คำอธิบายประกอบนี้วางอยู่เหนือองค์ประกอบที่ควรละเว้นระหว่างการทำให้เป็นอนุกรม/ดีซีเรียลไลเซชัน:


class Book {
	public String title;
	@JsonIgnore
	public String author;
	public int pages;
}

ที่นี่ผู้เขียนฟิลด์จะไม่รวมอยู่ใน JSON ที่เป็นผลลัพธ์ในระหว่างการทำให้เป็นอนุกรม เมื่อ deserialization, theผู้เขียนฟิลด์จะได้รับค่าเริ่มต้น (null) แม้ว่า JSON จะมีค่าอื่นก็ตาม

@JsonFormat — คำอธิบายประกอบนี้ให้คุณกำหนดรูปแบบของข้อมูลที่ทำให้เป็นอนุกรมได้ มาเพิ่มฟิลด์อีกหนึ่งฟิลด์Dateให้กับ คลาส Book :


class Book {
	public String title;
	public String author;
	public int pages;
	public Date createdDate = new Date();
}

หลังจากการทำให้เป็นอันดับ เราได้รับ JSON ต่อไปนี้:

 {
  "title" : "ลางดี",
  "author" : "Pratchett T., Gaiman N.",
  "pages" : 383,
  "createdDate" : 1649330880788
}

อย่างที่คุณเห็น วันที่ถูกกำหนดเป็นตัวเลข เราจะเพิ่มคำอธิบายประกอบและกำหนดรูปแบบ:


class Book {
	public String title;
	public String author;
	public int pages;
	@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd")
	public Date createdDate = new Date();
}

ตอนนี้ผลลัพธ์ของการทำให้เป็นอนุกรมคือ:

{
  "title" : "ลางดี",
  "author" : "Pratchett T., Gaiman N.",
  "pages" : 383,
  "createdDate" : "2022-04-07"
}

@JsonProperty — คำอธิบายประกอบนี้ให้คุณเปลี่ยนชื่อของคุณสมบัติที่แสดงฟิลด์ซีเรียลไลซ์ คุณยังสามารถทำเครื่องหมายวิธีการด้วยคำอธิบายประกอบนี้ หากคุณทำเช่นนั้น ค่าที่ส่งคืนจะถูกแปลงเป็นคุณสมบัติ JSON ในระหว่างการทำให้เป็นอนุกรม:


class Book {
	@JsonProperty("name")
	public String title;
	public String author;
	public int pages;
 
	@JsonProperty("quotedTitle")
	public String getQuotedTitle() {
    	    return "\"" + title + "\"";
	}
}

ผลลัพธ์ของการทำให้เป็นอนุกรม:

{
  "ผู้เขียน" : "Pratchett T., Gaiman N.",
  "หน้า" : 383,
  "ชื่อ" : "ลางดี",
  "quotedTitle" : "\"ลางดี\""
}

@JsonIncluded — เมื่อใช้คำอธิบายประกอบนี้ คุณสามารถระบุเงื่อนไขที่ต้องปฏิบัติตามสำหรับฟิลด์ที่จะซีเรียลไลซ์ คุณจะนำไปใช้กับแต่ละช่องหรือทั้งชั้นเรียนก็ได้ ขั้นแรก ลองทำให้วัตถุเป็นอนุกรมด้วยฟิลด์ที่ไม่ได้กำหนดค่าเริ่มต้น:


public class Solution {
	public static void main(String[] args) throws Exception {
    		Book book = new Book();

    		ObjectMapper mapper = new ObjectMapper();
    		mapper.enable(SerializationFeature.INDENT_OUTPUT);
    		String jsonBook = mapper.writeValueAsString(book);
    		System.out.println(jsonBook);
	}
}

ผลลัพธ์ของการทำให้เป็นอนุกรม:

{
  "title" : null,
  "author" : null,
  "pages" : 0
}

และถ้าคุณเพิ่มคำอธิบายประกอบ:


@JsonInclude(JsonInclude.Include.NON_NULL)
class Book {
	public String title;
	public String author;
	public int pages;
}

จากนั้นเราจะได้ผลลัพธ์นี้:

{
  "หน้า" : 0
}

ตอนนี้ฟิลด์ที่เป็นโมฆะจะไม่ทำให้เป็นอนุกรม

@JsonPropertyOrder — คำอธิบายประกอบนี้ให้คุณกำหนดลำดับที่ฟิลด์จะถูกทำให้เป็นอนุกรม:


@JsonPropertyOrder({"author", "title", "pages"})
class Book {
	public String title;
	public String author;
	public int pages;
}

ผลลัพธ์ของการทำให้เป็นอนุกรม:

{
  "ผู้เขียน" : "Pratchett T., Gaiman N.",
  "ชื่อ" : "ลางดี",
  "หน้า" : 383
}

สำหรับตอนนี้ เพียงจำวิธีใช้คำอธิบายประกอบ ในตอนท้ายของโมดูลนี้ เราจะได้รู้จักพวกเขามากขึ้นและสร้างคำอธิบายประกอบของเราเอง

การทำให้เป็นซีเรียลไลเซชันและดีซีเรียลไลเซชันใน XML

หากเราต้องการทำให้เป็นอนุกรมใน XML เราสามารถใช้การตั้งค่าและคำอธิบายประกอบเดียวกันทั้งหมดได้ ข้อแตกต่างเพียงอย่างเดียวคือการดำเนินการของวัตถุผู้ทำแผนที่:


public static void main(String[] args) throws Exception {
	Book book = new Book();
	book.title = "Good Omens";
	book.author = "Pratchett T., Gaiman N.";
	book.pages = 383;
 
	ObjectMapper mapper = new XmlMapper();
	mapper.enable(SerializationFeature.INDENT_OUTPUT);
	String xmlBook = mapper.writeValueAsString(book);
	System.out.println(xmlBook);
}

เอาท์พุต:

 <หนังสือ
  > <ชื่อ>ลางดี</title>
  <ผู้แต่ง>แพรเชตต์ ที., ไกแมน เอ็น.</ ผู้แต่ง>
  <หน้า>383</pages> <
/หนังสือ>

การดีซีเรียลไลเซชันของ XML:


public static void main(String[] args) throws Exception {
   String xmlString = """
            <Book>
             <title>Good Omens</title>
             <author>Pratchett T., Gaiman N.</author>
             <pages>383</pages>
           </Book>""";
   ObjectMapper mapper = new XmlMapper();
   Book book = mapper.readValue(xmlString, Book.class);
   System.out.println(book);
}

การทำให้เป็นซีเรียลไลเซชันและดีซีเรียลไลเซชันใน YAML

เราจัดการ YAML แบบเดียวกับที่เราจัดการกับ XML:


public static void main(String[] args) throws Exception {
	Book book = new Book();
	book.title = "Good Omens";
	book.author = "Pratchett T., Gaiman N.";
	book.pages = 383;
 
	ObjectMapper mapper = new YAMLMapper();
	mapper.enable(SerializationFeature.INDENT_OUTPUT);
	String yamlBook = mapper.writeValueAsString(book);
	System.out.println(yamlBook);
}

เอาท์พุต:

---
ชื่อเรื่อง: "ลางดี"
ผู้แต่ง: "แพรเชตต์ ที., ไกแมน เอ็น"
หน้า: 383

การดีซีเรียลไลเซชันของ YAML:


public static void main(String[] args) throws Exception {
   String yamlString = """
           ---
           title: "Good Omens"
           author: "Pratchett T., Gaiman N."
           pages: 383""";
   ObjectMapper mapper = new YAMLMapper();
   Book book = mapper.readValue(yamlString, Book.class);
   System.out.println(book);
}