天天看点

反序列化 jackson_使用Jackson和Super类型令牌的Json反序列化

反序列化 jackson

Datatables是一个jquery插件,用于显示表格信息–它可以增强简单的表或可以使用基于AJAX的数据并以表格形式显示信息。

数据表要​​求来自服务器的数据遵循特定的JSON格式才能在屏幕上显示。 考虑要显示Member实体列表的情况,那么Member的预期json结构必须遵循以下几行:

{
   'aaData':[
      {
         'id':1,
         'first':'one',
         'last':'one',
         'addresses':[

         ],
         'version':0
      },
      {
         'id':2,
         'first':'two',
         'last':'two',
         'addresses':[

         ],
         'version':0
      }
   ],
   'iTotalRecords':100,
   'iTotalDisplayRecords':10,
   'success':true
}
           

可以定义一个通用的Java类型, Jackson可以使用它来生成上述类型的json,请考虑以下Java通用类型:

package mvcsample.types;
import java.util.List;

public class ListWrapper<T> {
    private List<T> aaData;
    private int iTotalRecords;
    private int iTotalDisplayRecords;
    private  Boolean success;

    public List<T> getAaData() {
  return aaData;
 }
 public void setAaData(List<T> aaData) {
  this.aaData = aaData;
 }
 public int getiTotalRecords() {
  return iTotalRecords;
 }
 public void setiTotalRecords(int iTotalRecords) {
  this.iTotalRecords = iTotalRecords;
 }
 public int getiTotalDisplayRecords() {
  return iTotalDisplayRecords;
 }
 public void setiTotalDisplayRecords(int iTotalDisplayRecords) {
  this.iTotalDisplayRecords = iTotalDisplayRecords;
 }
 public Boolean getSuccess() {
  return success;
 }
 public void setSuccess(Boolean success) {
  this.success = success;
 }   
}
           

因此,使用此泛型类型,要生成成员列表,我将具有如本测试中定义的参数化类型:

List<Member> members = new ArrayList<>();
members.add(new Member('one', 'one'));
members.add(new Member('two', 'two'));
ListWrapper<Member> membersWrapper = new ListWrapper<>();
membersWrapper.setAaData(members);
membersWrapper.setiTotalDisplayRecords(10);
membersWrapper.setiTotalRecords(100);
ObjectMapper objectMapper = new ObjectMapper();

StringWriter w = new StringWriter();
objectMapper.writeValue(w, membersWrapper);
String json = w.toString();
System.out.println(json);
           

同样,可以生成任何其他类型的json。

但是, 相反,生成给定json的Java类型呢?

再次考虑一下将开头给出的json转换为ListWrapper <Member>的情况,我可以这样尝试反序列化:

ObjectMapper objectMapper = new ObjectMapper();  
ListWrapper<Member> membersUpdated = objectMapper.readValue(json, ListWrapper.class);
           

请注意,以上我无法将类类型称为ListWrapper <Member> .class,而只能将其称为ListWrapper.class。

但是,这将不起作用,并且结果类型也不会成为Member类的包装器,因为在运行时Jackson并不知道必须生成ListWrapper <Member>。

解决方法是以某种方式将有关ListWrapper类型的信息传递给Jackson,这就是Super类型标记所适合的地方。 本文详细说明了它的工作原理,其实质是,尽管类型擦除确实从参数化实例的类型实例中删除了类型信息。泛型类型,但是类型保留在泛型类的子类中。

例如。 考虑以下从ArrayList <String>派生的StringList类,可以发现基类的类型参数是String,如下面的测试所示:

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;

public class StringList extends ArrayList<String>{

 public static void main(String[] args) {
  StringList list = new StringList();
  Type superClassType = list.getClass().getGenericSuperclass();
  ParameterizedType parameterizedType = (ParameterizedType)superClassType;
  System.out.println(parameterizedType.getActualTypeArguments()[0]);
 }
}
           

这同样适用于子类也被定义为匿名类的情况:

ArrayList<String> list = new ArrayList<String>(){};
Type superClassType = list.getClass().getGenericSuperclass();
ParameterizedType parameterizedType = (ParameterizedType)superClassType;
System.out.println(parameterizedType.getActualTypeArguments()[0]);
           

这是Super Type令牌模式在内部使用的功能,用于查找参数化类型的类型。 Jackson的com.fasterxml.jackson.core.type.TypeReference抽象类实现了此功能,使用此功能,Jackson反序列化将以这种方式工作:

import com.fasterxml.jackson.core.type.TypeReference;

....
ListWrapper<Member> membersWrapper = objectMapper.readValue(json, new TypeReference<ListWrapper<Member>>() {});

ListWrapper<Address> addressWrapper = objectMapper.readValue(json, new TypeReference<ListWrapper<Address>>() {});
           

这样,可以在给定通用类型和json表示的情况下反序列化两个不同的参数化类型。

资源:

  • 反映泛型 :http://www.artima.com/weblogs/viewpost.jsp? thread = 208860
  • 尼尔·古夫特(Neal Gafter)的超级类型令牌 :http://gafter.blogspot.com/2006/12/super-type-tokens.html

参考: all和杂物博客上的Json 合作伙伴 Biju Kunjummen的Jackson和Super类型代币对Json的反序列化 。

翻译自: https://www.javacodegeeks.com/2013/01/json-deserialization-with-jackson-and-super-type-tokens.html

反序列化 jackson