Datatables是一个jquery插件,用于显示表格信息–它可以增强简单的表或可以使用基于AJAX的数据并以表格形式显示信息。
数据表要求来自服务器的数据遵循特定的JSON格式才能在屏幕上显示。 考虑要显示成员实体列表的情况,那么对于成员而言,预期的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类,可以发现基类的type参数是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用我们的JCG合作伙伴 Biju Kunjummen的Jackson和Super类型令牌进行反序列化 。
翻译自: https://www.javacodegeeks.com/2013/01/json-deserialization-with-jackson-and-super-type-tokens.html