简体   繁体   English

Jersey / Jackson-类对象序列化

[英]Jersey / Jackson - class Object serialization

I've found a lot of suggestions how to serialize Date correctly, but there is nothing that applicable for the next case: 我发现了很多有关如何正确序列化Date的建议,但没有适用于下一种情况的建议:

public class CustomFilter {
    private String filterName;
    private List<Filter> filters;
    //getters and setters
}

public class Filter {
    private String propertyName;
    private String comparison;
    private Object value;
    //getters and setters
}

The issue is that value property in Filter can be a String, Number or Date. 问题是筛选器中的value属性可以是字符串,数字或日期。 So instance of CustomFilter is serialized/desrialized properly (between Client and Resource), but if Filter value is Date it represents as long, if it is Joda-based Date the one represents as LinkedHashMap of elements (when deserialized). 因此,CustomFilter的实例已正确地序列化/反序列化(在客户端和资源之间),但是如果Filter值为Date,则它表示的时间就长,如果它是基于Joda的Date,则它表示为元素的LinkedHashMap(反序列化时)。 If anyone has idea how to handle this case (when object property is a type of Object but can be any of types described above) - please leave a comment 如果有人知道如何处理这种情况(当object属性是Object的一种类型,但可以是上述类型的任何一种时)-请发表评论

One option would be to create a container object which holds one of the three types 一种选择是创建一个容器对象,其中包含三种类型之一

public class ValueHolder {
    private Date date;
    private JodatDate jodaDate;
    private Number number;
    private String string;
    // getters and setters omitted
    // maybe add additional logic to ensure only one value is set.
}

Then you should be able to deserialize/serialize it without any problems. 然后,您应该可以对其进行反序列化/序列化,而不会出现任何问题。 If you want to do it with a custom serializer without the container object, you need to write the type of object in the json output and use that information to deserialize it on the receiving side. 如果要使用不带容器对象的自定义序列化程序来执行此操作,则需要在json输出中写入对象的类型,并使用该信息在接收端反序列化它。

If my understanding is correct, it doesn't matter if you deserialize keeping the "value" as an Object variable. 如果我的理解是正确的,那么您是否反序列化将“值”保留为Object变量也没关系。 How you handle the Object variable after deserializing is what you should be thinking about. 反序列化后如何处理Object变量是您应该考虑的问题。

I tried the below with Jackson. 我与杰克逊尝试了以下方法。

Create a class Address. 创建一个类地址。

public class Address {
    private String street;
    private String city; 
    private Object zip;
    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 Object getZip() {
        return zip;
    }
    public void setZip(Object zip) {
        this.zip = zip;
    }
}

Create a class Id. 创建一个类别ID。

 public class Id {
    private String fname;
    private String lname;
    private Address addr;
    public String getFname() {
        return fname;
    }
    public void setFname(String fname) {
        this.fname = fname;
    }
    public String getLname() {
        return lname;
    }
    public void setLname(String lname) {
        this.lname = lname;
    }
    public Address getAddr() {
        return addr;
    }
    public void setAddr(Address addr) {
        this.addr = addr;
    }
}

Main method: 主要方法:

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

public class Test {
    public static void main(String[] args) {
        long zip = 12345;

        Address addressObj = new Address();
        addressObj.setCity("Chicago");
        addressObj.setStreet("Some Street");
        addressObj.setZip(12345);

        Id idObj = new Id();
        idObj.setAddr(addressObj);
        idObj.setFname("Test");
        idObj.setLname("Tester");

        ObjectMapper mapper = new ObjectMapper();

        //Object to JSON in String
        try {
            String jsonInString = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(idObj);
            System.out.println(jsonInString);
        } catch (JsonProcessingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }       
    }
}

Output: 输出:

{
  "fname" : "Test",
  "lname" : "Tester",
  "addr" : {
    "street" : "Some Street",
    "city" : "Chicago",
    "zip" : 12345
  }
}

If in the main method, I change the zip to DateTime zip = new DateTime(DateTimeZone.UTC); 如果在主要方法中,我将zip更改为DateTime zip = new DateTime(DateTimeZone.UTC); result is as below: 结果如下:

{
  "fname" : "Test",
  "lname" : "Tester",
  "addr" : {
    "street" : "Some Street",
    "city" : "Chicago",
    "zip" : {
      "weekOfWeekyear" : 40,
      "dayOfWeek" : 1,
      "dayOfMonth" : 3,
      "dayOfYear" : 277,
      "weekyear" : 2016,
      "monthOfYear" : 10,
      "year" : 2016,
      "yearOfEra" : 2016,
      "yearOfCentury" : 16,
      "centuryOfEra" : 20,
      "era" : 1,
      "millisOfDay" : 83656626,
      "millisOfSecond" : 626,
      "secondOfMinute" : 16,
      "secondOfDay" : 83656,
      "minuteOfHour" : 14,
      "minuteOfDay" : 1394,
      "hourOfDay" : 23,
      "chronology" : {
        "zone" : {
          "fixed" : true,
          "id" : "UTC"
        }
      },
      "zone" : {
        "fixed" : true,
        "id" : "UTC"
      },
      "millis" : 1475536456626,
      "afterNow" : false,
      "beforeNow" : true,
      "equalNow" : false
    }
  }
}

The point here is that what you do with the Object variable is what matters 这里的重点是,您使用Object变量所做的事情很重要

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM