簡體   English   中英

如何使用Jackson-Databind順序反序列化多個對象

[英]How to deserialize multiple objects sequentially using jackson-databind

我正在使用msgpack序列化數據。 我有一些代碼可以很好地序列化數據。

public void testJackson() throws Exception {
    ByteArrayOutputStream out = new ByteArrayOutputStream();

    String data1 = "test data";
    int data2 = 10;
    List<String> data3 = new ArrayList<String>();
    data3.add("list data1");
    data3.add("list data1");

    ObjectMapper mapper = new ObjectMapper();
    mapper.writeValue(out, data1);
    mapper.writeValue(out, data2);
    mapper.writeValue(out, data3);

    // TODO: How to deserialize?

}

但是現在我不知道如何反序列化數據。 我在任何地方都找不到任何解決方案。 如果有人可以幫助您進行下去,那將是很好。

您將要使用ObjectMapperreadValue方法之一-可能是將Reader或InputStream作為第一個參數的方法。

問題

我已經嘗試了許多readValue方法,但是我只能得到第一個String,而我不知道第二個和第三個值

事實是,Jackson總是讀取第一個數據,因為該數據既不會從中刪除,也沒有明確告訴Jackson,下一個數據是從位置A到位置B。

解決方案

該示例可以正常工作,並且與您的代碼相似,但不是很好。 在這里,我明確告訴傑克遜我的數據在哪里,但是我必須知道它是如何寫入的,這是一種過於具體的解決方案

File dataFile = new File("jackson.txt");
if(!dataFile.exists())
  dataFile.createNewFile();
FileOutputStream fileOut = new FileOutputStream(dataFile);
ByteArrayOutputStream out = new ByteArrayOutputStream();
FileInputStream fileIn = new FileInputStream(dataFile);

String writeData1 = "test data";
int writeData2 = 10;
List<String> writeData3 = new ArrayList<String>();
writeData3.add("list data1");
writeData3.add("list data1");

ObjectMapper mapper = new ObjectMapper();
byte[] writeData1Bytes = mapper.writeValueAsBytes(writeData1);
out.write(writeData1Bytes);
byte[] writeData2Bytes = mapper.writeValueAsBytes(writeData2);
out.write(writeData2Bytes);
byte[] writeData3Bytes = mapper.writeValueAsBytes(writeData3);
out.write(writeData3Bytes);
out.writeTo(fileOut);

// TODO: How to deserialize?
int pos = 0;
byte[] readData = new byte[1000];
fileIn.read(readData);
String readData1 = mapper.readValue(readData, pos, writeData1Bytes.length, String.class);
pos += writeData1Bytes.length;
Integer readData2 = mapper.readValue(readData, pos, writeData2Bytes.length, Integer.class);
pos += writeData2Bytes.length;
ArrayList readData3 = mapper.readValue(readData, pos, writeData3Bytes.length, ArrayList.class);
pos += writeData3Bytes.length;

System.out.printf("readData1 = %s%n", readData1);
System.out.printf("readData2 = %s%n", readData2);
System.out.printf("readData3 = %s%n", readData3);

該文件看起來像這樣

"test data"10["list data1","list data1"]

如何正確做

一種更優雅的方式是將數據封裝在一個對象中,該對象可以轉換為有效的JSON字符串,並且Jackson不需要任何更多信息

public class JacksonTest {
  public static class DataNode {
    @JsonProperty("data1")
    private String data1;
    @JsonProperty("data2")
    private int data2;
    @JsonProperty("data3")
    private List<String> data3;

    //needed for Jackson
    public DataNode() {
    }

    public DataNode(String data1, int data2, List<String> data3) {
      this.data1 = data1;
      this.data2 = data2;
      this.data3 = data3;
    }
  }

  public static void main(String[] args) throws Exception {
    File dataFile = new File("jackson.txt");
    if(!dataFile.exists())
      dataFile.createNewFile();
    FileOutputStream fileOut = new FileOutputStream(dataFile);
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    FileInputStream fileIn = new FileInputStream(dataFile);

    String writeData1 = "test data";
    int writeData2 = 10;
    List<String> writeData3 = new ArrayList<String>();
    writeData3.add("list data1");
    writeData3.add("list data1");

    DataNode writeData = new DataNode(writeData1, writeData2, writeData3);

    ObjectMapper mapper = new ObjectMapper();
    mapper.writeValue(out, writeData);
    out.writeTo(fileOut);

    // TODO: How to deserialize?
    DataNode readData = mapper.readValue(fileIn, DataNode.class);

    System.out.printf("readData1 = %s%n", readData.data1);
    System.out.printf("readData2 = %s%n", readData.data2);
    System.out.printf("readData3 = %s%n", readData.data3);
  }
}

文件的內容如下所示

{"data1":"test data","data2":10,"data3":["list data1","list data1"]}

@Japu_D_Cret感謝您提供如此詳細的答案! 實際上我想使用msgpack傳輸數據,並且通過使用msgpack使它工作,這是我的代碼

    ByteArrayOutputStream out = new ByteArrayOutputStream();

    String data1 = "test data";
    int data2 = 10;
    List<String> data3 = new ArrayList<String>();
    data3.add("list data1");
    data3.add("list data1");

    MessagePack packer = new MessagePack();

    packer.write(out, data1);
    packer.write(out, data2);
    packer.write(out, data3);

    // TODO: How to deserialize?

    BufferUnpacker unpacker = packer.createBufferUnpacker(out.toByteArray());
    System.out.println(unpacker.readString());
    System.out.println(unpacker.readInt());
    System.out.println(unpacker.read(Templates.tList(Templates.TString)));

然后我在msgpack網站上找到了jackson-databind,它也支持msgpack格式。 我對這兩個進行了一些測試,發現傑克遜的序列化性能優於msgpack,因此我想使用傑克遜代替msgpack。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM