定制key-field的關(guān)系
- name的映射定制:
@JsonProperty
,其value指定是序列化后的key名稱夺鲜。比如:一些系統(tǒng)的產(chǎn)生的id格式為'_id'。
設(shè)置忽略
- 直接對(duì)屬性設(shè)置:
@JsonIgnore public int internalValue;
- 對(duì)類進(jìn)行設(shè)置:
@JsonIgnoreProperties({ "age" })
,此設(shè)置可以完成兩個(gè)目標(biāo):序列化時(shí)忽略age,反序列化時(shí)出現(xiàn)age不會(huì)拋出異常炼七。 - 針對(duì)反序列化時(shí)陶舞,出現(xiàn)的未知key,可以使用
@JsonIgnoreProperties(ignoreUnknown=true)
,避免異常的出現(xiàn)。 - 針對(duì)某一個(gè)類蓖康,讓其成為被忽略的類(是被組合的類),可以該類上使用
@JsonIgnoreType
- 當(dāng)對(duì)象的屬性為“空”時(shí)垒手,如果不希望在序列化時(shí)出現(xiàn)null,0,[]的情況蒜焊,可以使用
@JsonInclude
,它的典型取值:JsonInclude.Include.NON_NULL
表示null,@JsonInclude(JsonInclude.Include.NON_EMPTY)
,表示null和集合為空,@JsonInclude(JsonInclude.Include.NON_DEFAULT)
,表示為賦初值的情況(null,0,0.0,空集合科贬,false)泳梆;可以將此注解應(yīng)用于Field
格式的設(shè)置
- 日期時(shí)間格式:默認(rèn)會(huì)將java.util.Date轉(zhuǎn)化成為GMT的整型數(shù)值,可以使用
@JsonFormat(pattern = "yyyy-MM-dd hh:mm:ss",timezone = "GMT+8")
,作用于序列化及反序列化榜掌。 - 當(dāng)需要更加高級(jí)的格式設(shè)置時(shí)优妙,可以使用
JsonSerializer,JsonDeserializer
,詳細(xì)案例:
//pojo Customer.class中
@JsonSerialize(using = CurrencySerializer.class)
@JsonDeserialize(using = CurrencyDeSerializer.class)
private double salary;
//序列化時(shí)使用
public class CurrencySerializer extends JsonSerializer<Double> {
@Override
public void serialize(Double value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
NumberFormat nf=NumberFormat.getCurrencyInstance();
gen.writeString(nf.format(value));
}
}
//反序列化時(shí)使用
public class CurrencyDeSerializer extends JsonDeserializer<Double> {
@Override
public Double deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
NumberFormat nf=NumberFormat.getCurrencyInstance();
double m=0.0;
try {
m=nf.parse(p.getText()).doubleValue();
} catch (ParseException e) {
e.printStackTrace();
}
return m;
}
}
循環(huán)引用所帶來(lái)的問(wèn)題:
- StackOverFlow:在雙方分別使用:
@JsonManagedReference, @JsonBackReferenc
- 相同對(duì)象的識(shí)別需求:多個(gè)對(duì)象都有著相同的引用時(shí),都面臨著以下問(wèn)題:
- 序列化時(shí)憎账,會(huì)生成冗余的數(shù)據(jù)
[city:"bj",customer:{id:1},city:"sh",customer:{id:1}]
- 反序列化時(shí)套硼,會(huì)產(chǎn)生兩個(gè)內(nèi)容相同的對(duì)象。
- 序列化時(shí)憎账,會(huì)生成冗余的數(shù)據(jù)
此時(shí)可以使用@JsonIdentityInfo
,解決此問(wèn)題胞皱,方法如下:
@JsonIdentityInfo(generator =ObjectIdGenerators.IntSequenceGenerator.class
,property = "@id")
public class Customer {}
此時(shí)序列化后的對(duì)象邪意,格式如下:
[{"city":"bj","customer":{"@id":1,"id":1,"cname":"john"},{"city":"sh","customer":1}]
對(duì)序列化后,customer對(duì)象為同一個(gè)朴恳。
反序列化陷阱:型別擦除
- jackson會(huì)把json集合中的數(shù)據(jù)抄罕,看作是HashMap看待(實(shí)際類型被擦除)
- 此時(shí)需要在解析時(shí),重新鑄型于颖,方法如下:
ObjectMapper mapper = new ObjectMapper();
JavaType listAddressType= mapper.getTypeFactory() .constructCollectionType(List.class,Address.class);
List<Address> list=mapper.readValue(new File("data.txt"), listAddressType);
- 型別不會(huì)擦除的情況:
public class Album {
private String title;
private Set<Music> musics = new HashSet<>();
}
此情況下,無(wú)需要鑄型嚷兔,可以直接反序列化成功:
Album album=mapper.readValue(new File("album1.json"),Album.class);
- 當(dāng)你使用了泛型類的設(shè)計(jì)情況:
public class Album<T> {
private String title;
private Set<T> musics = new HashSet<>();
}
面對(duì)以下的數(shù)據(jù):
{"title":"resolved","musics":[{"name":"rocking"},{"name":"goodBye"}]}
jackson將無(wú)法知道森渐,name是哪個(gè)類型數(shù)據(jù)中的field,可以采用以下形式,對(duì)其進(jìn)行指引:
//錯(cuò)誤的方式冒晰,型別擦除
//Album<Music> album=mapper.readValue(file,Album.class);
//可以使用TypeReference進(jìn)行重新鑄型
Album<Music> album=mapper.readValue(file,new TypeReference<Album<Music>>(){});
“運(yùn)行時(shí)”類型同衣,還是“聲明”類型
- 在序列化一個(gè)Filed時(shí),默認(rèn)會(huì)“根據(jù)它的runtime類型”進(jìn)行壶运,但如果我們只想要其某個(gè)父類的類型耐齐,或者其“聲明時(shí)類型”,此時(shí)可以:
//@JsonSerialize(as=Music.class) 默認(rèn)是實(shí)際類型
@JsonSerialize(typing = JsonSerialize.Typing.STATIC)
private Music music;//music可能會(huì)是子類Song
此時(shí),只會(huì)將Music中的成員進(jìn)行序列化埠况,而忽略子類型的成員耸携。
- 在“反序列”時(shí),默認(rèn)只會(huì)按照“聲明類型”進(jìn)行辕翰。
private Music music;//music可能會(huì)是子類Song
此時(shí)進(jìn)行解析夺衍,music中多余的key-value會(huì)導(dǎo)致異常(也可進(jìn)行Ignore)。如果想按照子類型進(jìn)行解析喜命,此時(shí)可以:
@JsonDeserialize(as = Song.class)
private Music music;//music可能會(huì)是子類Song