首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用jackson-databind顺序反序列化多个对象

如何使用jackson-databind顺序反序列化多个对象
EN

Stack Overflow用户
提问于 2017-03-30 02:08:32
回答 3查看 1.7K关注 0票数 0

我正在使用msgpack来序列化数据。我有一些代码可以很好地序列化数据。

代码语言:javascript
复制
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?

}

但现在我不知道如何反序列化数据。我在任何地方都找不到解决办法。如果有人能帮上忙,那就太好了。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2017-03-30 05:34:26

问题所在

我尝试过许多readValue方法,但是我只能得到第一个字符串,大约是第二个和第三个值,我不知道。

问题是,杰克逊总是读取第一个数据,因为数据既没有从数据库中删除,也没有明确告诉杰克逊下一个数据是从A位置到B位置的

解决方案

此示例工作正常,与您的代码相似,但不太优雅。在这里,我明确地告诉Jackson我的数据在哪里,但我必须知道它是如何编写的,这是一种过于具体的解决方案。

代码语言:javascript
复制
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);

这个文件看上去像这样

代码语言:javascript
复制
"test data"10["list data1","list data1"]

如何正确地做好

更优雅的方法是将数据封装到一个可以转换为有效JSON字符串的对象中,这样杰克逊就不需要任何信息了

代码语言:javascript
复制
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);
  }
}

文件的内容如下所示

代码语言:javascript
复制
{"data1":"test data","data2":10,"data3":["list data1","list data1"]}
票数 0
EN

Stack Overflow用户

发布于 2017-03-30 04:52:32

您将希望使用来自readValueObjectMapper方法之一--可能是将读取器或InputStream作为第一个参数的方法。

票数 0
EN

Stack Overflow用户

发布于 2017-03-30 06:30:14

@Japu_D_Cret,谢谢你这么详细的回答!实际上,我想使用msgpack来传输数据,并且我使用msgpack实现了它,下面是我的代码

代码语言:javascript
复制
    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数据库,它也支持msgpack格式。我对这两者进行了一些测试,发现jackson的序列化性能优于msgpack,所以我想使用jackson而不是msgpack。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43107280

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档