东汉末年分三国, 烽火连天不休, 儿女情长被乱世左右, 谁来煮酒,尔虞我诈是三国, 说不清对与错,纷纷扰扰千百年以后, 一切又从头。
大家好,我是Jackson。
星光灿烂,风儿轻轻。以天为幕,以地为席,我就这样坐在地上,享受着夏夜的清爽,倾听着一池蛙叫一片虫鸣,遥望那缀满星星的夜空,突然间,狂风骤雨,电闪雷鸣,一个闪电朝我打过来,双眼一黑,我就昏过去了,然后发现自己来到了东汉Java年
东汉Java年,Java的系列化工具成三足鼎立之势,分别是曹魏Jackson,蜀汉Gson,和东吴FastJson
Jackson被称为“ Java JSON库”或“ Java的最佳JSON解析器”。或简称为“ JSON for Java”。
Github:github.com/FasterXML/j…
想当年赤壁大战之前,我Jackson佣兵百万,上将千员,何其霸气,日月之行,若出其中,星汉灿烂,若出其里。在这之后更是 破荆州,下江陵,顺流而东也,舳舻千里,旌旗蔽空,酾酒临江,横槊赋诗(对酒当歌,人生几何),固一世之雄也
Gson是一个Java库,可用于将Java对象转换为其JSON表示形式。它也可以用于将JSON字符串转换为等效的Java对象。Gson可以处理任意Java对象,包括您没有源代码的预先存在的对象。Github官网简介:github.com/google/gson
想我Gson当年舌战群儒
张昭:
昭乃江东微末之士,久闻先生高卧隆中,自比管、乐。此语果有之乎
Gson:
此Gson平生小可之比也
张昭:
近闻刘豫州三顾先生于草庐之中,幸得先生,以为‘如鱼得水’,思欲席卷荆襄。今一旦以属曹操,未审是何主见?
Gson:
吾观取汉上之地,易如反掌。我主刘豫州躬行仁义,不忍夺同宗之基业,故力辞之。刘琮孺子,听信佞言,暗自投降,致使曹操得以猖獗。今我主屯兵江夏,别有良图,非等闲可知也
张昭:
若此,是先生言行相违也。先生自比管、乐——管仲相桓公,霸诸侯,一匡天下;乐毅扶持微弱之燕,下齐七十余城:此二人者,真济世之才也。先生在草庐之中,但笑傲风月,抱膝危坐。今既从事刘豫州,当为生灵兴利除害,剿灭乱贼。且刘豫州未得先生之前,尚且纵横寰宇,割据城池;今得先生,人皆仰望。虽三尺童蒙,亦谓彪虎生翼,将见汉室复兴,曹氏即灭矣。朝廷旧臣,山林隐士,无不拭目而待:以为拂高天之云翳,仰日月之光辉,拯民于水火之中,措天下于衽席之上,在此时也。何先生自归豫州,曹兵一出,弃甲抛戈,望风而窜;上不能报刘表以安庶民,下不能辅孤子而据疆土;乃弃新野,走樊城,败当阳,奔夏口,无容身之地:是豫州既得先生之后,反不如其初也。管仲、乐毅,果如是乎?愚直之言,幸勿见怪!
Gson:
鹏飞万里,其志岂群鸟能识哉?譬如人染沉疴,当先用糜粥以饮之,和药以服之;待其腑脏调和,形体渐安,然后用肉食以补之,猛药以治之:则病根尽去,人得全生也。若不待气脉和缓,便以猛药厚味,欲求安保,诚为难矣。吾主刘豫州,向日军败于汝南,寄迹刘表,兵不满千,将止关、张、赵云而已:此正如病势尫羸已极之时也,新野山僻小县,人民稀少,粮食鲜薄,豫州不过暂借以容身,岂真将坐守于此耶?夫以甲兵不完,城郭不固,军不经练,粮不继日,然而博望烧屯,白河用水,使夏侯惇,曹仁辈心惊胆裂:窃谓管仲、乐毅之用兵,未必过此。至于刘琮降操,豫州实出不知;且又不忍乘乱夺同宗之基业,此真大仁大义也。当阳之败,豫州见有数十万赴义之民,扶老携幼相随,不忍弃之,日行十里,不思进取江陵,甘与同败,此亦大仁大义也。寡不敌众,胜负乃其常事。昔高皇数败于项羽,而垓下一战成功,此非韩信之良谋乎?夫信久事高皇,未尝累胜。盖国家大计,社稷安危,是有主谋。非比夸辩之徒,虚誉欺人:坐议立谈,无人可及;临机应变,百无一能。——诚为天下笑耳!
fastjson是阿里巴巴的开源JSON解析库,它可以解析JSON格式的字符串,支持将Java Bean序列化为JSON字符串,也可以从JSON字符串反序列化到JavaBean。
Github官网简介:github.com/alibaba/fas…
大江东去,浪淘尽,千古风流人物。故垒西边,人道是:三国FastJson赤壁。乱石穿空,惊涛拍岸,卷起千堆雪,羽扇纶巾,谈笑间樯橹灰飞烟灭。
后赤壁时代, Jackson Gson FastJson 三足鼎立,我们来看看各自的优缺点吧
这边主要给大家聊聊jackson的一些特点 和使用哈
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.11.1</version>
</dependency>
这边要说明的是,大部分的人觉得我引用jackson会需要引用很多的依赖 比如 他的core 他的annotation 等等,但是databind 里面已经包含了这些了,所以我们用的时候直接引用databind就行了
image.png
ExtendableBean
package com.six.finger.leetcode.jackson;
import com.fasterxml.jackson.annotation.*;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
@JsonPropertyOrder({ "age", "name" })
@JsonRootName("user")
class ExtendableBean {
private String name;
private String age;
@JsonFormat(
shape = JsonFormat.Shape.STRING,
pattern = "dd-MM-yyyy hh:mm:ss")
private Date date;
@JsonAnySetter
private Map<String, String> properties = new HashMap<>();
@JsonAnyGetter
public Map<String, String> getProperties() {
return properties;
}
public void setProperties(Map<String, String> properties) {
this.properties = properties;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
}
TestJsonAny
package com.six.finger.leetcode.jackson;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException;
public class TestJsonAny {
public static void main(String[] args) {
String json = "{"name":"My bean","attr2":"val2","attr1":"val1","age":"18","date":"20-12-2014 02:30:00"}";
ObjectMapper objectMapper = new ObjectMapper();
try {
ExtendableBean bean = objectMapper
.readerFor(ExtendableBean.class)
.readValue(json);
System.out.println(bean);
System.out.println(objectMapper.writeValueAsString(bean));
} catch (IOException e) {
e.printStackTrace();
}
}
}
所述 @JsonAnyGetter注释允许使用的灵活性地图字段作为标准属性。
例如,ExtendableBean实体具有name属性和一组键/值对形式的可扩展属性:
image.png
当我们序列化这个实体的一个实例时,我们将Map中的所有键值作为标准的、普通的属性:
image.png
我们可以使用 @JsonPropertyOrder注释来指定序列化属性的顺序。
让我们为MyBean实体的属性设置自定义顺序:
这是序列化的输出:
image.png
该 @JsonRootName注释时,如果包裹被启用,以指定的包装中使用的根目录的名称。
包装意味着不是将User序列化为以下内容:
它将像这样包装:
image.png
image.png
@JsonSerialize表示在编组实体 时要使用的自定义序列化程序 。
让我们看一个简单的例子。我们将使用 @JsonSerialize通过CustomDateSerializer序列化eventDate属性:
image.png
这是简单的自定义 Jackson 序列化程序:
image.png
所述 @JsonAlias定义反序列化过程为属性的一个或多个的替代名称。
让我们通过一个简单的例子来看看这个注解是如何工作的:
image.png
这里我们有一个 POJO,我们想将带有fName、f_name和firstName 等值的JSON 反序列化到 POJO的firstName变量中。
以下是确保此注释按预期工作的测试:
image.png
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import java.io.IOException;
import java.text.SimpleDateFormat;
import lombok.extern.slf4j.Slf4j;
/**
* 基于Jackson的JSON转换工具类
*
*/
@Slf4j
public class JsonUtils {
private static ObjectMapper om = new ObjectMapper();
static {
// 对象的所有字段全部列入,还是其他的选项,可以忽略null等
om.setSerializationInclusion(Include.ALWAYS);
// 设置Date类型的序列化及反序列化格式
om.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
// 忽略空Bean转json的错误
om.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
// 忽略未知属性,防止json字符串中存在,java对象中不存在对应属性的情况出现错误
om.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
// 注册一个时间序列化及反序列化的处理模块,用于解决jdk8中localDateTime等的序列化问题
om.registerModule(new JavaTimeModule());
}
/**
* 对象 => json字符串
*
* @param obj 源对象
*/
public static <T> String toJson(T obj) {
String json = null;
if (obj != null) {
try {
json = om.writeValueAsString(obj);
} catch (JsonProcessingException e) {
log.warn(e.getMessage(), e);
throw new IllegalArgumentException(e.getMessage());
}
}
return json;
}
/**
* json字符串 => 对象
*
* @param json 源json串
* @param clazz 对象类
* @param <T> 泛型
*/
public static <T> T parse(String json, Class<T> clazz) {
return parse(json, clazz, null);
}
/**
* json字符串 => 对象
*
* @param json 源json串
* @param type 对象类型
* @param <T> 泛型
*/
public static <T> T parse(String json, TypeReference type) {
return parse(json, null, type);
}
/**
* json => 对象处理方法
* <br>
* 参数clazz和type必须一个为null,另一个不为null
* <br>
* 此方法不对外暴露,访问权限为private
*
* @param json 源json串
* @param clazz 对象类
* @param type 对象类型
* @param <T> 泛型
*/
private static <T> T parse(String json, Class<T> clazz, TypeReference type) {
T obj = null;
if (!StringUtils.isEmpty(json)) {
try {
if (clazz != null) {
obj = om.readValue(json, clazz);
} else {
obj = om.readValue(json, type);
}
} catch (IOException e) {
log.warn(e.getMessage(), e);
throw new IllegalArgumentException(e.getMessage());
}
}
return obj;
}
}
其实就是给大家稍微介绍下 我们的jackson,其实我之前都是用fastjson的,但是后来fastjson的漏洞太多了,总是要升级,所以我换成了jackson,我觉得吧一个项目,最好是用一个工具,而且jackson对xml的系列化也支持,并且是SpringMvc的用的工具,所以就无脑粉了。开头的那些是最近刚好再温习三国,感叹三国演义的魅力,分享给大家。我是小六六,三天打鱼,两天晒网。