Jackson 框架 用例详解
目录
一、 基本介绍.............................2
二、 准备工作............... ............2
三、 一些常用的示例............... 4
1.Object转Json..............................5
2.Json转Object..............................6
3.日期格式设置............................6
1)普通的方式..............................6
2)注解方式..................................7
4.解决hibernate延时加载设置.... 8
5.设置循环策略............................8
1)父子关系引用........................ 9
2)@JsonIgnore注解....................9
6.属性过滤................................. 10
1)使用@JsonFilter注解.......... 10
2)添加混合式注解................ 10
7.其它annotation(注解)..............10
一、基本介绍
Jackson的功能好处就不介绍
具体见:http://bbs.jee-soft.cn:8086/showtopic-155.aspx
官方介绍:http://www.cowtowncoder.com/blog/archives/2010/11/entry_434.html
Concrete Java types that Jackson will use for simple data binding are:
JSON Type |
Java Type |
object |
LinkedHashMap<String,Object> |
array |
ArrayList<Object> |
string |
String |
number (no fraction) |
Integer, Long or BigInteger (smallest applicable) |
number (fraction) |
Double (configurable to use BigDecimal) |
true|false |
Boolean |
null |
null |
二、准备工作
1、下载依赖库jar包
Jackson的 maven 目前有2.0暂时使用1.9.8比较稳定
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-core-asl</artifactId>
<version>1.9.8</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-core-lgpl</artifactId>
<version>1.9.8</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
官方示例:http://wiki.fasterxml.com/JacksonInFiveMinutes
因为下面的程序是用junit测试用例运行的,所以还得添加junit的jar包。
版本是junit-4.2.8
2.测试的项目
目前要进行hibernate的懒加载等其它功能,我直接使用joffice项目的工程,避免要配置hibernate等测试环境。
Department.java
- /**
- * @description 部门管理
- * @class Department
- * @author 宏天软件
- * @company www.jee-soft.cn
- * @createtime 2011-1-18AM
- *
- */
- public class Department extends BaseModel {
- public final static long serialVersionUID = 1L;
- /**集团*/
- public final static Short ORG_TYPE_GROUP=0;
- /**公司*/
- public final static Short ORG_TYPE_COMPANY=1;
- /**部门*/
- public final static Short ORG_TYPE_DEPARTMENT=2;
- protected Long depId;
- protected String depName;
- protected String depDesc;
- protected Integer depLevel;
- protected Long parentId;
- protected String path;
- protected Short orgType;
- protected Long creatorId;
- protected java.util.Date createtime;
- protected Long updateId;
- protected java.util.Date updatetime;
- protected Integer sn;
- protected com.htsoft.oa.model.system.Demension demension;
- protected Set appUsers = new java.util.HashSet();
- protected Set userOrgs = new java.util.HashSet();
- protected String chargeIds;
- protected String chargeNames;
- //====get和set 省略
- }
Demension.java
- /**
- * @description 维度管理
- * @class Department
- * @author 宏天软件
- * @company www.jee-soft.cn
- * @createtime 2011-1-18AM
- */
- public class Demension extends com.htsoft.core.model.BaseModel {
- /**
- * 行政维度的id
- */
- public final static Long ADMIN_DEMENSION_ID=1l;
- protected Long demId;
- protected String demName;
- protected String demDesc;
- protected Long demType;
- protected java.util.Set organizations = newjava.util.HashSet();
- //====get和set 省略
- }
三、一些常用的示例
具体的帮助类请参考 ——》
1.Object转Json
Object可以是String,Integer,Long,List ,pojo(实体) 等对象
通过调用方法如下:
输出结果:
- {"version":null,"orgId":null,"orgPath":null,"depId":1,"depName":"宏天软件","depDesc":"宏天软件","depLevel":1,"parentId":0,"path":"0.1.","orgType":1,"creatorId":1,"createtime":1314547200000,"updateId":1,"updatetime":"1314547200000","sn":null,"chargeIds":"","chargeNames":"","demension":{"version":null,"orgId":null,"orgPath":null,"demId":1,"demName":"行政维度","demDesc":"行政维度","demType":1,"organizations":[]}}
2.Json转Object
测试类:
输出结果:
- 宏天软件
- Mon Aug 29 08:00:00 CST 2011
- 行政维度
3.日期格式设置
你看上面的例子 object转Json日期输入的是时间戳(数字)的格式,那我们需要把它转换成我们需要的日期格式比如:yyyy-MM-dd HH:mm:ss ,有2种方式解决这个问题:
1)普通的方式
默认是转成timestamps形式的,通过下面方式可以取消timestamps。
objectMapper.configure(Feature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT,false);
这样将使时间生成使用所谓的使用 [ISO-8601 ]-compliant notation, 输出类似如下格式的时间: "1970-01-01T00:00:00.000+0000".
当然也可以自定义输出格式:
2)注解方式
可以支持序列化(@JsonSerialize(using=CustomDateTimeSerializer.class))
和反序列化(@JsonDeserialize(using=CustomDateTimeDeserializer.class))
然后在你的POJO上找到日期的属性上加上:
4.解决hibernate延时加载设置
因为jsonplugin用的是java的内审机制.hibernate会给被管理的pojo加入一个 hibernateLazyInitializer属性,jsonplugin会把hibernateLazyInitializer也拿出来操作,并读取里面一个不能被反射操作的属性就产生了这个异常.
1)不过我用的是jackson来转json,所以想到了用annotation来排除hibernateLazyInitializer这个属性
在你的pojo类声明加上
2)采用别人写的相关插件 我用是hibernate3
import com.fasterxml.jackson.datatype.hibernate3.Hibernate3Module;
/**
* 带是否懒加载 的构造方法
* @param forceLazyLoading 是否懒加载 true为懒加载,否则false
*/
public JacksonMapper(boolean forceLazyLoading){
Hibernate3Module mod = new Hibernate3Module();
mod.configure(Hibernate3Module.Feature.FORCE_LAZY_LOADING, forceLazyLoading);
registerModule(mod);
}
5.设置循环策略 :解决json最头疼的问题死循环
能够干净地处理循环类型的某些子集,成为父/子链接。 这些都是互相紧密耦合的引用,其中两个对象以层次结构的方式交叉引用,如父/子树节点的关联,或更常见的,ORM采用的表间连接(join)的描述。
对引用问题(或更普遍的,循环引用),JSON没有处理它们的自然方法。,不像Java对象,没有标识信息可用。
常用的解决方法是只标记一个被忽略的引用(Jackson可通过使用@ JsonIgnore注解实现),但其缺点是反序列化时会丢失实际的耦合目标。
Jackson 有简单的基于注解的解决该问题的方案:两个引用需要一个注解(对“子”连接作@JsonManagedReference 注解,对“父”或“返回”连接作@JsonBackReference注解),并在此基础,Jackson知道要省略反向引用的序列化,但反序列化对象时要恢复它。此方式适用于典型的ORM用例。
1)父子关系引用
直接输出肯定是报循环错误,Jackson 提供了两个注解
@JsonManagedReference 和@JsonBackReference
@JsonManagedReference
protected com.htsoft.oa.model.system.Demension demension;
@JsonBackReference
protected Set appUsers = new java.util.HashSet();
参考这:http://wiki.fasterxml.com/JacksonFeatureBiDirReferences
把官网的例子拿下来分析:New annotations
Annotations are:
@JsonManagedReference is the "forward" part of reference: one that gets serialized normally, and handling of which triggers back-linkage for the other reference
Annotated property can be a bean, array, Collection (List, Set) or Map type, and it must be a bean property (handled by a property of type serialized using BeanSerializer
@JsonBackReference is the "back" part of reference: it will be omitted from serialization, and re-constructed during deserialization of forward reference.
翻译器翻译:(
新的注解
注解是:
@ JsonManagedReference是“前进”的部分关联:一,通常被序列化,并处理其中触发后面的其他参考联动
注释的属性可以是一个Bean,数组,集合(List,Set)或Map类型,它必须是一个bean的属性(使用的BeanSerializer序列类型的属性处理
@ JsonBackReference是“反向的”关联:从序列,它会被省略,向前引用的反序列化过程中重新构建。
)
Example
Here is a simple example of a double-linked linked list, where references are both in same class
(这里是一个简单的例子,双联链表,引用都在同一类)
- public class Node
- {
- public String name; // simple property
- // reference with default name
- @JsonManagedReference public SimpleTreeNode child; // forward reference, serialized
- @JsonBackReference public Node parent; // backward reference, not serialized
- public SimpleTreeNode() { this(null); }
- public SimpleTreeNode(String n) { name = n; }
Linkage also works for structured types (arrays, Collections, Maps), as long as only forward reference is of such type. For example:
- public class NodeList
- {
- @JsonManagedReference
- public List<NodeForList> nodes;
- }
- public class NodeForList
- {
- public String name;
- @JsonBackReference public NodeList parent;
- public NodeForList() { this(null); }
- public NodeForList(String n) { name = n; }
- }
and it is possible to use multiple references, by specifying distinct names:(通过指定不同的名称,可以使用多个引用:)
- public class FullTreeNode
- {
- public String name;
- // parent-child links
- @JsonBackReference("parent")
- public FullTreeNode parent;
- @JsonManagedReference("parent")
- public FullTreeNode firstChild;
- // sibling-links
- @JsonManagedReference("sibling")
- public FullTreeNode next;
- @JsonBackReference("sibling")
- protected FullTreeNode prev;
- public FullTreeNode() { this(null); }
- public FullTreeNode(String name) {
- this.name = name;
- }
- }
One final note: if using getter and setter methods instead of fields, you will may to add reference annotations on both methods (you will always need them in setters which are used for deserialization; getters for forward references are handled correctly without annotations, but getters for serializing back links do need to be annotated).
2)@JsonIgnore注解
只说父子引用关系的。父子两边都加@JsonIgnore打印字符串为:
{"name":"chris","createDate":"2012-04-18"},{"title":"title"}
单向User加该注解
@JsonIgnore
public Set<Article> getArticles() {
return articles;
}
打印结果为:
{"name":"chris","createDate":"2012-04-18"}
{"title":"title","user":{"name":"chris","createDate":"2012-04-18"}}
单向Article 加该注解
@JsonIgnore
public User getUser() {
return user;
}
打印结果:
{"name":"chris","createDate":"2012-04-18","articles":[{"title":"title"}]}
{"title":"title"}
6.属性过滤
@JsonIgnoreProperties
这个加在类级别上, 用法很简单@JsonIgnoreProperties({"property1", "property2"})
动态过滤属性,这个比较麻烦。
有两种方法:
1)使用@JsonFilter注解
使用方法为先给ObjectMapper添加一个filter,然后还要在需要过滤的类上加@JsonFilter("filterName")
注解。
比如说要过滤User 上的name属性,先
Jacksons.me().filter("myFilter", "name").readAsString(user),具体看Jacksons代码。并在User类上加@JsonFilter("myFilter")。
有点不爽的是如果用另外一个没有添加该filter的ObjectMapper解析的话会报错。
如果这个User类已经添加了@JsonFilter("myFilter")注解,但在另外一个地方又要解析它并不想过滤name 属性,那只能是Jacksons.me().filter("myFilter", ""),然后在读出来。
2)添加混合式注解(暂时这么翻译)
定义一个接口或类先, 在该类上添加@JsonIgnoreProperties("name"), 然后在ObjectMapper的配置项上添加混入注解
输出为:
String mixInUser = Jacksons.me().addMixInAnnotations(User.class, MixInUser.class).readAsString(user);
System.out.println(mixInUser);
可以参考:http://www.cowtowncoder.com/blog/archives/2009/08/entry_305.html
7.其它annotation(注解)
① @JsonAutoDetect (class)这是作用于类的annotation,主要用于指明该类使用annotation,并且可以自动侦测getter,setter,构造方法,以便生成json对象
② @JsonIgnore (method/field):作用于方法或字段,用来表明,当生成json的时候忽略有该annotation的方法或字段
③ @JsonIgnoreProperties (value = { "hibernateLazyInitializer" , "password" }) ,主要用于过滤掉一些不需要的属性
④ @JsonPropertyOrder({ "id", "name" }) // ensure that 'id' and 'name' are always serialized before other properties(确保'id'和'name'的被序列总是在其他属性之前)
可以用来指示明确(但可以是部分的)序列化属性的顺序。
⑤ @ JsonFilter(class):表示这BeanPropertyFilter使用注解的类的属性的动态过滤。此外,一个有定义PropertyFilterProvider ObjectWriter(要么在使用ObjectMapper.filteredWriter(),或ObjectWriter.withFilters()),当序列化用于动态解决实际使用中的过滤器。
⑥ @ JsonIgnoreType(class):indicates that properties with annotated type are never to be serialized; this is useful for ignoring metadata accessors used by proxy types or generated classes.
指示,注释类型的物业从来没有被序列化,忽略代理类型或生成的类所使用的元数据存取,这是有用的。
还有些注解,那你就要参考官方的文档了,就看官方文档:
相关推荐
TestNG是Java语言中的一种测试框架,提供了许多有用的功能,例如测试用例的执行、断言、报告等。我们可以使用TestNG来实现自动化测试,并且可以使用断言来验证测试结果。 六、设计Get请求方法 设计Get请求方法的...
**Spring Redis 集成详解** 在现代的Java开发中,Spring框架因其强大的功能和灵活性而备受青睐。随着数据存储技术的发展,Redis作为一款高性能的键值存储系统,被广泛应用于缓存、消息队列等多个场景。Spring为...
《SpringMVC4与Hibernate5整合详解》 在现代企业级应用开发中,SpringMVC和Hibernate是两个不可或缺的重要框架。SpringMVC作为Spring框架的一部分,主要负责处理Web请求,而Hibernate则是主流的对象关系映射(ORM)...
《基于Spring Boot的停车场管理系统详解》 在当前的城市生活中,停车场管理系统已经成为不可或缺的一部分,它能够有效地管理和调度车辆的停放,提高停车场的运营效率。本文将深入探讨一款基于Spring Boot技术构建的...
13. **测试支持**:Spring MVC Test框架提供了对Spring MVC应用的单元测试和集成测试支持,可以便捷地编写和执行测试用例。 在实际项目中,直接将jar包导入到`WebContent/WEB-INF/lib`目录,然后进行相应的配置,就...
10. **单元测试与集成测试**:为了保证代码质量,项目可能包含了JUnit和Espresso等测试框架的用例。 11. **版本控制**:使用Git进行版本控制,便于团队协作和代码维护。 通过学习这个项目源码,开发者可以深入理解...
json4s是Scala社区中一个流行的json库,它提供了多种风格(JValue、Jackson、Circe等)来处理JSON数据,具有丰富的API和高度的灵活性。通过Akka HTTP与json4s的集成,我们可以直接在路由处理函数中处理JSON请求和...
以下是相关的知识点详解: 1. **Java编程语言**:Java是一种面向对象的、跨平台的编程语言,因其安全性、可移植性和高效性而被广泛应用于服务器端开发。在本项目中,Java将作为主要的开发工具,用于构建与微博API...
### Android高仿拉手网项目实战视频教程知识点详解 #### 一、项目概述与环境搭建 **1.1 项目背景** 随着移动互联网的发展,本地生活服务类应用日益受到人们的欢迎。拉手网作为国内知名的团购网站之一,在移动...
【Android开发-TestAirPlus项目详解】 在Android开发领域,TestAirPlus是一个可能的项目名称,它涵盖了多个关键知识点,包括应用架构设计、用户界面(UI)设计、数据存储、网络通信、性能优化等方面。让我们深入探讨...
《Android网上商城系统详解》 在移动互联网时代,Android平台上的网上商城应用已经成为电商领域不可或缺的一部分。本项目“android网上商城.zip”提供了一个完整的Android客户端和服务器程序,旨在帮助开发者或者...
4. **序列化与反序列化**:CMPP协议的报文是以二进制形式传输的,因此开发者需要熟悉Java的序列化接口或第三方库(如protobuf、Jackson、Fastjson等)进行数据的序列化与反序列化。 5. **异常处理**:在处理网络...
《Android 简单的机票预订系统源码详解》 在移动互联网时代,Android平台上的应用开发成为开发者的重要战场,而构建一个机票预订系统是众多应用程序中的常见需求。本篇文章将详细解读“Android简单的机票预订系统...
5. 测试代码:JUnit或其他测试框架的测试类,用于验证代码功能。 6. 配置文件:如数据库连接配置、应用设置等。 【知识点详解】 1. **Java编程基础**:涉及Java语言的关键概念,如类、对象、继承、多态、异常处理、...
【Android问答类软件Demo详解】 在移动应用开发领域,Android平台因其开源性和广泛的应用而备受开发者青睐。本项目“一个问答类Android软件Demo”旨在提供一个基础的问答平台框架,帮助开发者快速理解如何构建类似...
【Spring Boot博客应用详解】 Spring Boot是Java领域中一个非常流行的微服务开发框架,它简化了新Spring应用程序的初始设置和配置。在这个"spring boot blog"项目中,我们将深入探讨如何利用Spring Boot来构建一个...
6. **JSON数据格式**:JSON作为网络通信的常用数据格式,开发者需要熟悉JSON的结构和解析,例如使用Jackson或Gson库进行JSON序列化和反序列化。 7. **插件体系结构**:理解插件的加载、初始化、注册、生命周期管理...
JUnit 和 Mockito 是常用的 Java 测试框架,可以帮助开发者编写测试用例。同时,使用像 Postman 这样的工具可以方便地进行 API 调试。 7. **性能优化**: BFF 应考虑性能问题,例如缓存策略,减少不必要的数据库...
8. **JSON或XML解析**:数据交换格式如JSON或XML可能被用来存储和传输地理位置信息,因此需要了解如何使用如Jackson或JAXB等库来解析这些格式。 9. **单元测试**:为了确保代码的质量,项目可能包含了JUnit测试用例...