jsonproperty注解_Jackson注解详解
1. 概述
在本文中,我们将深入研究Jackson注解。
我们将看到如何使用现有的注释,如何创建自定义的注释,最后—如何禁用它们。
2. Jackson序列化注解
首先,我们将查看序列化注释。
2.1. @JsonAnyGetter
@JsonAnyGetter注释允许灵活地使用映射字段作为标准属性。
下面是一个快速的例子——ExtendableBean实体拥有name属性和一组可扩展属性,它们以键/值对的形式存在:
public class ExtendableBean { public String name; private Map properties; @JsonAnyGetter public Map getProperties() { return properties; }}
当我们序列化这个实体的一个实例时,我们会得到Map中所有的键值作为标准的普通属性:
{ "name":"My bean", "attr2":"val2", "attr1":"val1"}
这里是如何序列化这个实体看起来像在实践:
@Testpublic void whenSerializingUsingJsonAnyGetter_thenCorrect() throws JsonProcessingException { ExtendableBean bean = new ExtendableBean("My bean"); bean.add("attr1", "val1"); bean.add("attr2", "val2"); String result = new ObjectMapper().writeValueAsString(bean); assertThat(result, containsString("attr1")); assertThat(result, containsString("val1"));}
我们还可以使用可选参数enabled为false来禁用@JsonAnyGetter()。在本例中,映射将被转换为JSON,并在序列化之后出现在properties变量下。
2.2. @JsonGetter
@JsonGetter注释是@JsonProperty注释的替代品,它将方法标记为getter方法。
在下面的例子中-我们指定getTheName()方法作为MyBean实体的name属性的getter方法:
public class MyBean { public int id; private String name; @JsonGetter("name") public String getTheName() { return name; }}
这是如何在实践中运作的:
@Testpublic void whenSerializingUsingJsonGetter_thenCorrect() throws JsonProcessingException { MyBean bean = new MyBean(1, "My bean"); String result = new ObjectMapper().writeValueAsString(bean); assertThat(result, containsString("My bean")); assertThat(result, containsString("1"));}
2.3. @JsonPropertyOrder
我们可以使用@JsonPropertyOrder注释来指定序列化时属性的顺序。
让我们为MyBean实体的属性设置一个自定义顺序:
@JsonPropertyOrder({ "name", "id" })public class MyBean { public int id; public String name;}
这是序列化的输出:
{ "name":"My bean", "id":1}
还有一个简单的测试:
@Testpublic void whenSerializingUsingJsonPropertyOrder_thenCorrect() throws JsonProcessingException { MyBean bean = new MyBean(1, "My bean"); String result = new ObjectMapper().writeValueAsString(bean); assertThat(result, containsString("My bean")); assertThat(result, containsString("1"));}
我们还可以使用@JsonPropertyOrder(alphabetic=true)按字母顺序排列属性。在这种情况下,序列化的输出将是:
{ "id":1, "name":"My bean"}
2.4. @JsonRawValue
@JsonRawValue注释可以指示Jackson按原样序列化属性。
在下面的例子中,我们使用@JsonRawValue嵌入一些定制的JSON作为一个实体的值:
public class RawBean { public String name; @JsonRawValue public String json;}
序列化实体的输出为:
{ "name":"My bean", "json":{ "attr":false }}
还有一个简单的测试:
@Testpublic void whenSerializingUsingJsonRawValue_thenCorrect() throws JsonProcessingException { RawBean bean = new RawBean("My bean", "{"attr":false}"); String result = new ObjectMapper().writeValueAsString(bean); assertThat(result, containsString("My bean")); assertThat(result, containsString("{"attr":false}"));}
我们还可以使用可选的布尔参数值来定义这个注释是否是活动的。
2.5. @JsonValue
@JsonValue表示库将使用一个方法来序列化整个实例。
例如,在枚举中,我们用@JsonValue注释getName,这样任何这样的实体都可以通过其名称序列化:
public enum TypeEnumWithValue { TYPE1(1, "Type A"), TYPE2(2, "Type 2"); private Integer id; private String name; // standard constructors @JsonValue public String getName() { return name; }}
我们的测试:
@Testpublic void whenSerializingUsingJsonValue_thenCorrect() throws JsonParseException, IOException { String enumAsString = new ObjectMapper() .writeValueAsString(TypeEnumWithValue.TYPE1); assertThat(enumAsString, is(""Type A""));}
2.6. @JsonRootName
如果启用了包装,则使用@JsonRootName注释来指定要使用的根包装器的名称。
包装意味着不将用户序列化为以下内容:
它会像这样包装:
{ "User": { "id": 1, "name": "John" }}
那么,让我们来看一个例子——我们将使用@JsonRootName注释来表示这个潜在的包装实体的名称:
@JsonRootName(value = "user")public class UserWithRoot { public int id; public String name;}
默认情况下,包装器的名称将是类的名称- UserWithRoot。通过使用注释,我们得到了看起来更干净的用户:
@Testpublic void whenSerializingUsingJsonRootName_thenCorrect() throws JsonProcessingException { UserWithRoot user = new User(1, "John"); ObjectMapper mapper = new ObjectMapper(); mapper.enable(SerializationFeature.WRAP_ROOT_VALUE); String result = mapper.writeValueAsString(user); assertThat(result, containsString("John")); assertThat(result, containsString("user"));}
这是序列化的输出:
{ "user":{ "id":1, "name":"John" }}
自Jackson 2.4以来,一个新的可选参数名称空间可用于XML等数据格式。如果我们添加它,它将成为完全限定名的一部分:
@JsonRootName(value = "user", namespace="users")public class UserWithRootNamespace { public int id; public String name; // ...}
如果我们用XmlMapper序列化它,输出将是:
1John
2.7. @JsonSerialize
让我们看一个简单的例子。我们将使用@JsonSerialize用CustomDateSerializer来序列化eventDate属性:
public class EventWithSerializer { public String name; @JsonSerialize(using = CustomDateSerializer.class) public Date eventDate;}
下面是简单的自定义Jackson序列化器:
public class CustomDateSerializer extends StdSerializer { private static SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yyyy hh:mm:ss"); public CustomDateSerializer() { this(null); } public CustomDateSerializer(Class t) { super(t); } @Override public void serialize( Date value, JsonGenerator gen, SerializerProvider arg2) throws IOException, JsonProcessingException { gen.writeString(formatter.format(value)); }}
让我们在测试中使用这些:
@Testpublic void whenSerializingUsingJsonSerialize_thenCorrect() throws JsonProcessingException, ParseException { SimpleDateFormat df = new SimpleDateFormat("dd-MM-yyyy hh:mm:ss"); String toParse = "20-12-2014 02:30:00"; Date date = df.parse(toParse); EventWithSerializer event = new EventWithSerializer("party", date); String result = new ObjectMapper().writeValueAsString(event); assertThat(result, containsString(toParse));}
Jackson反序列化注解
接下来——让我们研究Jackson反序列化注解。
3.1. @JsonCreator
我们可以使用@JsonCreator注释来调优反序列化中使用的构造器/工厂。
当我们需要反序列化一些与我们需要获取的目标实体不完全匹配的JSON时,它非常有用。
我们来看一个例子;说我们需要反序列化以下JSON:
{ "id":1, "theName":"My bean"}
但是,在我们的目标实体中没有theName字段—只有name字段。现在,我们不想改变实体本身—我们只需要对数据编出过程进行更多的控制—通过使用@JsonCreator和@JsonProperty注释来注释构造函数:
public class BeanWithCreator { public int id; public String name; @JsonCreator public BeanWithCreator( @JsonProperty("id") int id, @JsonProperty("theName") String name) { this.id = id; this.name = name; }}
让我们来看看这是怎么回事:
@Testpublic void whenDeserializingUsingJsonCreator_thenCorrect() throws IOException { String json = "{"id":1,"theName":"My bean"}"; BeanWithCreator bean = new ObjectMapper() .readerFor(BeanWithCreator.class) .readValue(json); assertEquals("My bean", bean.name);}
3.2. @JacksonInject
@JacksonInject表示属性将从注入中获得其值,而不是从JSON数据中。
在下面的例子中,我们使用@JacksonInject注入属性id:
public class BeanWithInject { @JacksonInject public int id; public String name;}
它是这样工作的:
@Testpublic void whenDeserializingUsingJsonInject_thenCorrect() throws IOException { String json = "{"name":"My bean"}"; InjectableValues inject = new InjectableValues.Std() .addValue(int.class, 1); BeanWithInject bean = new ObjectMapper().reader(inject) .forType(BeanWithInject.class) .readValue(json); assertEquals("My bean", bean.name); assertEquals(1, bean.id);}
3.3. @JsonAnySetter
@JsonAnySetter允许我们灵活地使用映射作为标准属性。在反序列化时,JSON的属性将被添加到映射中。
让我们看看这是如何工作的-我们将使用@JsonAnySetter来反序列化实体ExtendableBean:
public class ExtendableBean { public String name; private Map properties; @JsonAnySetter public void add(String key, String value) { properties.put(key, value); }}
这是我们需要反序列化的JSON:
{ "name":"My bean", "attr2":"val2", "attr1":"val1"}
而这一切是如何联系在一起的:
@Testpublic void whenDeserializingUsingJsonAnySetter_thenCorrect() throws IOException { String json = "{"name":"My bean","attr2":"val2","attr1":"val1"}"; ExtendableBean bean = new ObjectMapper() .readerFor(ExtendableBean.class) .readValue(json); assertEquals("My bean", bean.name); assertEquals("val2", bean.getProperties().get("attr2"));}
3.4. @JsonSetter
@JsonSetter是@JsonProperty的替代方法—它将方法标记为setter方法。
当我们需要读取一些JSON数据,但目标实体类与该数据不完全匹配时,这非常有用,因此我们需要调优流程以使其适合该数据。
在下面的例子中,我们将指定方法setTheName()作为MyBean实体中name属性的setter:
public class MyBean { public int id; private String name; @JsonSetter("name") public void setTheName(String name) { this.name = name; }}
现在,当我们需要unmarshall一些JSON数据-这是完美的工作:
@Testpublic void whenDeserializingUsingJsonSetter_thenCorrect() throws IOException { String json = "{"id":1,"name":"My bean"}"; MyBean bean = new ObjectMapper() .readerFor(MyBean.class) .readValue(json); assertEquals("My bean", bean.getTheName());}
3.5. @JsonDeserialize
@JsonDeserialize表示使用自定义反序列化器。
让我们看看这是如何实现的-我们将使用@JsonDeserialize来反序列化eventDate属性与CustomDateDeserializer:
public class EventWithSerializer { public String name; @JsonDeserialize(using = CustomDateDeserializer.class) public Date eventDate;}
这是自定义反序列化器:
public class CustomDateDeserializer extends StdDeserializer { private static SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yyyy hh:mm:ss"); public CustomDateDeserializer() { this(null); } public CustomDateDeserializer(Class> vc) { super(vc); } @Override public Date deserialize( JsonParser jsonparser, DeserializationContext context) throws IOException { String date = jsonparser.getText(); try { return formatter.parse(date); } catch (ParseException e) { throw new RuntimeException(e); } }}
这是背靠背的测试:
@Testpublic void whenDeserializingUsingJsonDeserialize_thenCorrect() throws IOException { String json = "{"name":"party","eventDate":"20-12-2014 02:30:00"}"; SimpleDateFormat df = new SimpleDateFormat("dd-MM-yyyy hh:mm:ss"); EventWithSerializer event = new ObjectMapper() .readerFor(EventWithSerializer.class) .readValue(json); assertEquals( "20-12-2014 02:30:00", df.format(event.eventDate));}
3.6 @JsonAlias
@JsonAlias在反序列化期间为属性定义一个或多个替代名称。
让我们通过一个简单的例子来看看这个注释是如何工作的:
public class AliasBean { @JsonAlias({ "fName", "f_name" }) private String firstName; private String lastName;}
在这里,我们有一个POJO,我们想用fName、f_name和firstName等值反序列化JSON到POJO的firstName变量中。
这里有一个测试,确保这个注释像expecte一样工作:
@Testpublic void whenDeserializingUsingJsonAlias_thenCorrect() throws IOException { String json = "{"fName": "John", "lastName": "Green"}"; AliasBean aliasBean = new ObjectMapper().readerFor(AliasBean.class).readValue(json); assertEquals("John", aliasBean.getFirstName());}
4. Jackson属性包含注释
4.1. @JsonIgnoreProperties
@JsonIgnoreProperties是一个类级注释,它标记Jackson将忽略的一个属性或一列属性。
让我们来看一个忽略属性id的例子:
@JsonIgnoreProperties({ "id" })public class BeanWithIgnore { public int id; public String name;}
下面是确保忽略发生的测试:
@Testpublic void whenSerializingUsingJsonIgnoreProperties_thenCorrect() throws JsonProcessingException { BeanWithIgnore bean = new BeanWithIgnore(1, "My bean"); String result = new ObjectMapper() .writeValueAsString(bean); assertThat(result, containsString("My bean")); assertThat(result, not(containsString("id")));}
为了毫无例外地忽略JSON输入中的任何未知属性,我们可以对@JsonIgnoreProperties注释设置ignoreUnknown=true。
4.2. @JsonIgnore
@JsonIgnore注释用于在字段级别标记要忽略的属性。
让我们使用@JsonIgnore来忽略序列化中的属性id:
public class BeanWithIgnore { @JsonIgnore public int id; public String name;}
确保id被成功忽略的测试:
@Testpublic void whenSerializingUsingJsonIgnore_thenCorrect() throws JsonProcessingException { BeanWithIgnore bean = new BeanWithIgnore(1, "My bean"); String result = new ObjectMapper() .writeValueAsString(bean); assertThat(result, containsString("My bean")); assertThat(result, not(containsString("id")));}
4.3. @JsonIgnoreType
@JsonIgnoreType将注释类型的所有属性标记为忽略。
让我们使用注释来标记所有类型名称的属性被忽略:
public class User { public int id; public Name name; @JsonIgnoreType public static class Name { public String firstName; public String lastName; }}
这里有一个简单的测试,确保忽略工作正确:
@Testpublic void whenSerializingUsingJsonIgnoreType_thenCorrect() throws JsonProcessingException, ParseException { User.Name name = new User.Name("John", "Doe"); User user = new User(1, name); String result = new ObjectMapper() .writeValueAsString(user); assertThat(result, containsString("1")); assertThat(result, not(containsString("name"))); assertThat(result, not(containsString("John")));}
4.4. @JsonInclude
我们可以使用@JsonInclude来排除具有空/空/默认值的属性。
让我们看一个例子-排除null从序列化:
@JsonInclude(Include.NON_NULL)public class MyBean { public int id; public String name;}
下面是完整的测试:
public void whenSerializingUsingJsonInclude_thenCorrect() throws JsonProcessingException { MyBean bean = new MyBean(1, null); String result = new ObjectMapper() .writeValueAsString(bean); assertThat(result, containsString("1")); assertThat(result, not(containsString("name")));}
4.5. @JsonAutoDetect
@JsonAutoDetect可以覆盖哪些属性可见,哪些不可见的默认语义。
让我们通过一个简单的例子来看看这个注释是如何非常有用的——让我们启用序列化私有属性:
@JsonAutoDetect(fieldVisibility = Visibility.ANY)public class PrivateBean { private int id; private String name;}
测试:
@Testpublic void whenSerializingUsingJsonAutoDetect_thenCorrect() throws JsonProcessingException { PrivateBean bean = new PrivateBean(1, "My bean"); String result = new ObjectMapper() .writeValueAsString(bean); assertThat(result, containsString("1")); assertThat(result, containsString("My bean"));}
5. Jackson多态类型处理注释
接下来,让我们看看Jackson多态类型处理注释:
- @JsonTypeInfo——指示要在序列化中包含什么类型信息的详细信息
- @JsonSubTypes——指示注释类型的子类型
- @JsonTypeName—定义了一个用于注释类的逻辑类型名
让我们看一个更复杂的例子,使用所有这三个——@JsonTypeInfo, @JsonSubTypes,和@JsonTypeName——来序列化/反序列化实体Zoo:
public class Zoo { public Animal animal; @JsonTypeInfo( use = JsonTypeInfo.Id.NAME, include = As.PROPERTY, property = "type") @JsonSubTypes({ @JsonSubTypes.Type(value = Dog.class, name = "dog"), @JsonSubTypes.Type(value = Cat.class, name = "cat") }) public static class Animal { public String name; } @JsonTypeName("dog") public static class Dog extends Animal { public double barkVolume; } @JsonTypeName("cat") public static class Cat extends Animal { boolean likesCream; public int lives; }}
当我们进行序列化时:
@Testpublic void whenSerializingPolymorphic_thenCorrect() throws JsonProcessingException { Zoo.Dog dog = new Zoo.Dog("lacy"); Zoo zoo = new Zoo(dog); String result = new ObjectMapper() .writeValueAsString(zoo); assertThat(result, containsString("type")); assertThat(result, containsString("dog"));}
下面是将动物园实例与狗序列化将得到的结果:
{ "animal": { "type": "dog", "name": "lacy", "barkVolume": 0 }}
现在反序列化-让我们从以下JSON输入开始:
{ "animal":{ "name":"lacy", "type":"cat" }}
让我们看看它是如何被分解到一个动物园实例的:
@Testpublic void whenDeserializingPolymorphic_thenCorrect()throws IOException { String json = "{"animal":{"name":"lacy","type":"cat"}}"; Zoo zoo = new ObjectMapper() .readerFor(Zoo.class) .readValue(json); assertEquals("lacy", zoo.animal.name); assertEquals(Zoo.Cat.class, zoo.animal.getClass());}
6. Jackson通用注解
接下来——让我们讨论Jackson的一些更通用的注释。
6.1. @JsonProperty
我们可以添加@JsonProperty注释来表示JSON中的属性名。
当我们处理非标准的getter和setter时,让我们使用@JsonProperty来序列化/反序列化属性名:
public class MyBean { public int id; private String name; @JsonProperty("name") public void setTheName(String name) { this.name = name; } @JsonProperty("name") public String getTheName() { return name; }}
我们的测试:
@Testpublic void whenUsingJsonProperty_thenCorrect() throws IOException { MyBean bean = new MyBean(1, "My bean"); String result = new ObjectMapper().writeValueAsString(bean); assertThat(result, containsString("My bean")); assertThat(result, containsString("1")); MyBean resultBean = new ObjectMapper() .readerFor(MyBean.class) .readValue(result); assertEquals("My bean", resultBean.getTheName());}
6.2. @JsonFormat
@JsonFormat注释在序列化日期/时间值时指定一种格式。
在下面的例子中,我们使用@JsonFormat来控制属性eventDate的格式:
public class EventWithFormat { public String name; @JsonFormat( shape = JsonFormat.Shape.STRING, pattern = "dd-MM-yyyy hh:mm:ss") public Date eventDate;}
下面是测试:
@Testpublic void whenSerializingUsingJsonFormat_thenCorrect() throws JsonProcessingException, ParseException { SimpleDateFormat df = new SimpleDateFormat("dd-MM-yyyy hh:mm:ss"); df.setTimeZone(TimeZone.getTimeZone("UTC")); String toParse = "20-12-2014 02:30:00"; Date date = df.parse(toParse); EventWithFormat event = new EventWithFormat("party", date); String result = new ObjectMapper().writeValueAsString(event); assertThat(result, containsString(toParse));}
6.3. @JsonUnwrapped
@JsonUnwrapped定义了在序列化/反序列化时应该被解包装/扁平化的值。
我们来看看它是如何工作的;我们将使用注释来展开属性名:
public class UnwrappedUser { public int id; @JsonUnwrapped public Name name; public static class Name { public String firstName; public String lastName; }}
现在让我们序列化这个类的一个实例:
@Testpublic void whenSerializingUsingJsonUnwrapped_thenCorrect() throws JsonProcessingException, ParseException { UnwrappedUser.Name name = new UnwrappedUser.Name("John", "Doe"); UnwrappedUser user = new UnwrappedUser(1, name); String result = new ObjectMapper().writeValueAsString(user); assertThat(result, containsString("John")); assertThat(result, not(containsString("name")));}
下面是输出的样子-静态嵌套类的字段与其他字段一起展开:
{ "id":1, "firstName":"John", "lastName":"Doe"}
6.4. @JsonView
@JsonView表示将包含该属性进行序列化/反序列化的视图。
我们将使用@JsonView来序列化项目实体的实例。
让我们从视图开始:
public class Views { public static class Public {} public static class Internal extends Public {}}
现在这是Item实体,使用视图:
public class Item { @JsonView(Views.Public.class) public int id; @JsonView(Views.Public.class) public String itemName; @JsonView(Views.Internal.class) public String ownerName;}
最后-完整测试:
@Testpublic void whenSerializingUsingJsonView_thenCorrect() throws JsonProcessingException { Item item = new Item(2, "book", "John"); String result = new ObjectMapper() .writerWithView(Views.Public.class) .writeValueAsString(item); assertThat(result, containsString("book")); assertThat(result, containsString("2")); assertThat(result, not(containsString("John")));}
6.5. @JsonManagedReference, @JsonBackReference
@JsonManagedReference和@JsonBackReference注释可以处理父/子关系并在循环中工作。
在下面的例子中-我们使用@JsonManagedReference和@JsonBackReference来序列化我们的ItemWithRef实体:
public class ItemWithRef { public int id; public String itemName; @JsonManagedReference public UserWithRef owner;}
我们的UserWithRef实体:
public class UserWithRef { public int id; public String name; @JsonBackReference public List userItems;}
测试:
@Testpublic void whenSerializingUsingJacksonReferenceAnnotation_thenCorrect() throws JsonProcessingException { UserWithRef user = new UserWithRef(1, "John"); ItemWithRef item = new ItemWithRef(2, "book", user); user.addItem(item); String result = new ObjectMapper().writeValueAsString(item); assertThat(result, containsString("book")); assertThat(result, containsString("John")); assertThat(result, not(containsString("userItems")));}
6.6. @JsonIdentityInfo
@JsonIdentityInfo表示在序列化/反序列化值时应该使用对象标识—例如,用于处理无限递归类型的问题。
在下面的例子中-我们有一个ItemWithIdentity实体,它与UserWithIdentity实体具有双向关系:
@JsonIdentityInfo( generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")public class ItemWithIdentity { public int id; public String itemName; public UserWithIdentity owner;}
和UserWithIdentity实体:
@JsonIdentityInfo( generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")public class UserWithIdentity { public int id; public String name; public List userItems;}
现在,让我们看看无限递归问题是如何处理的:
@Testpublic void whenSerializingUsingJsonIdentityInfo_thenCorrect() throws JsonProcessingException { UserWithIdentity user = new UserWithIdentity(1, "John"); ItemWithIdentity item = new ItemWithIdentity(2, "book", user); user.addItem(item); String result = new ObjectMapper().writeValueAsString(item); assertThat(result, containsString("book")); assertThat(result, containsString("John")); assertThat(result, containsString("userItems"));}
下面是序列化的项目和用户的完整输出:
{ "id": 2, "itemName": "book", "owner": { "id": 1, "name": "John", "userItems": [ 2 ] }}
6.7. @JsonFilter
@JsonFilter注释指定要在序列化期间使用的过滤器。
让我们看一个例子;首先,我们定义实体,并指向过滤器:
@JsonFilter("myFilter")public class BeanWithFilter { public int id; public String name;}
现在,在完整的测试中,我们定义了过滤器——它排除了序列化中除了name之外的所有其他属性:
@Testpublic void whenSerializingUsingJsonFilter_thenCorrect() throws JsonProcessingException { BeanWithFilter bean = new BeanWithFilter(1, "My bean"); FilterProvider filters = new SimpleFilterProvider().addFilter( "myFilter", SimpleBeanPropertyFilter.filterOutAllExcept("name")); String result = new ObjectMapper() .writer(filters) .writeValueAsString(bean); assertThat(result, containsString("My bean")); assertThat(result, not(containsString("id")));}
7. Jackson自定义注释
接下来,让我们看看如何创建自定义Jackson注释。我们可以使用@JacksonAnnotationsInside注释:
@Retention(RetentionPolicy.RUNTIME) @JacksonAnnotationsInside @JsonInclude(Include.NON_NULL) @JsonPropertyOrder({ "name", "id", "dateCreated" }) public @interface CustomAnnotation {}
现在,如果我们对一个实体使用新的注释:
@CustomAnnotationpublic class BeanWithCustomAnnotation { public int id; public String name; public Date dateCreated;}
我们可以看到它是如何将现有的注解组合成一个更简单的、自定义的注解,我们可以使用它作为速记:
@Testpublic void whenSerializingUsingCustomAnnotation_thenCorrect() throws JsonProcessingException { BeanWithCustomAnnotation bean = new BeanWithCustomAnnotation(1, "My bean", null); String result = new ObjectMapper().writeValueAsString(bean); assertThat(result, containsString("My bean")); assertThat(result, containsString("1")); assertThat(result, not(containsString("dateCreated")));}
序列化过程的输出:
{ "name":"My bean", "id":1}
8. Jackson MixIn 注解
接下来——让我们看看如何使用Jackson MixIn注释。
让我们使用MixIn注释——例如——忽略类型User的属性:
public class Item { public int id; public String itemName; public User owner;}@JsonIgnoreTypepublic class MyMixInForIgnoreType {}
让我们来看看这是怎么回事:
@Testpublic void whenSerializingUsingMixInAnnotation_thenCorrect() throws JsonProcessingException { Item item = new Item(1, "book", null); String result = new ObjectMapper().writeValueAsString(item); assertThat(result, containsString("owner")); ObjectMapper mapper = new ObjectMapper(); mapper.addMixIn(User.class, MyMixInForIgnoreType.class); result = mapper.writeValueAsString(item); assertThat(result, not(containsString("owner")));}
9. 禁用Jackson注解
最后,让我们看看如何禁用所有Jackson注释。我们可以通过禁用MapperFeature来做到这一点。如下例所示:
@JsonInclude(Include.NON_NULL)@JsonPropertyOrder({ "name", "id" })public class MyBean { public int id; public String name;}
现在,禁用注释后,这些应该没有效果,库的默认值应该适用:
@Testpublic void whenDisablingAllAnnotations_thenAllDisabled() throws IOException { MyBean bean = new MyBean(1, null); ObjectMapper mapper = new ObjectMapper(); mapper.disable(MapperFeature.USE_ANNOTATIONS); String result = mapper.writeValueAsString(bean); assertThat(result, containsString("1")); assertThat(result, containsString("name"));
禁用注释之前序列化的结果:
{"id":1}
禁用注释后序列化的结果:
{ "id":1, "name":null}
{ "id":1, "name":null}
10. 结论
本教程对Jackson注释进行了深入的研究,只触及了正确使用它们所能获得的灵活性的表面。
jsonproperty注解_Jackson注解详解相关推荐
- 源代码下载 第六章 注解式控制器详解
2019独角兽企业重金招聘Python工程师标准>>> 源代码请到附件中下载. 其他下载: 跟着开涛学SpringMVC 第一章源代码下载 第二章 Spring MVC入门 源代码下 ...
- SpringBoot注解最全详解(整合超详细版本)
今日推荐强制双休!腾讯调整加班机制,21 点前必须离开工位 使用雪花id或uuid作为Mysql主键,被老板怼了一顿! 盘点 12 个 GitHub 上的高仿项目 CTO 说了,用错 @Autowir ...
- java的注解方式_详解Java注解的实现与使用方法
详解Java注解的实现与使用方法 Java注解是java5版本发布的,其作用就是节省配置文件,增强代码可读性.在如今各种框架及开发中非常常见,特此说明一下. 如何创建一个注解 每一个自定义的注解都由四 ...
- @Column注解及属性详解
@Column注解 用来标识实体类中属性与数据表中字段的对应关系 (1)源码: /** Copyright (c) 2008, 2009, 2011 Oracle, Inc. All rights r ...
- Android -- Annotation(注解)原理详解及常见框架应用
1,我们在上一篇讲到了EventBus源码及3.0版本的简单使用,知道了我们3.0版本是使用注解方式标记事件响应方法的,这里我们就有一个疑问了,为什么在一个方法加上类似于"@Subscrib ...
- JavaWeb-Spring中注解大全与详解
常用的spring注解有如下几种: @Controller @Service @Autowired @RequestMapping @RequestParam @ModelAttribute @Cac ...
- Java注解处理器使用详解
文章转自:http://www.race604.com/annotation-processing/ 在这篇文章中,我将阐述怎样写一个注解处理器(Annotation Processor).在这篇教程 ...
- Spring注解之@GetMapping详解
params 参数详解 例如:@GetMapping(value = "/service", params = "serviceName=CREATE_PROJECT&q ...
- Java注解解读-ElementType详解
文章目录 注解须知前言 @Target @Retention @Inherited @Documented @Repeatable 注解须知前言 Java注解使用是相当频繁,特别是在在框架源码使用,用 ...
- Spring注解之Service详解
目录 @[TOC](目录) Service注解 Service用法及示例 传统方式是怎么做的呢? @Service注解是怎么体现业务逻辑复用的? 总结 Service注解 @Service 注解是 S ...
最新文章
- MFC消息处理学习总结
- mysql聚集索引和二级索引_mysql8 参考手册--聚集索引和二级索引
- python开启新代码块_20课零基础快速学python完成简单邮件完整邮件代码块
- android 微信设置圆角边框代码,Android编程实现圆角边框的方法
- Cocos2dx ParticleEditor粒子编辑器
- m126a linux驱动下载,【惠普m126a驱动】惠普m126a驱动下载 v15.0 官方版-开心电玩
- 国外大神在GitHub上发布的打包成APP的Win95
- 网易秋招编程题——优雅的点
- 融云对接php,谈谈微信小程序中首次对接融云WebIM SDK经验
- 一个故事带你看透HTTPS(上)
- 光学载波网络(SONET OC)的网络带宽
- unity找到指定名称的一个物体的子物体,多个子物体有相同的名称
- 【CCM-SLAM论文阅读笔记】
- w10计算机怎么恢复出厂设置路由器,技术编辑为你解决win10系统打不开192.168.1.1设置界面的还原步骤...
- 微信小程序键盘弹起后页面上推问题
- 试题 算法训练 黑色星期五
- ###好好好####深度学习---多标签分类问题
- *1 计算机基础和操作系统基础及几大协议
- 关闭iframe中弹窗,视频也关闭播放
- rabbit mq Consumer Acknowledgements and Publisher Confirms 翻译
热门文章
- 求助matlab分解质因数,Matlab
- android log4,GitHub - oronno/log4android: Log4Android - Simple Logging Wrapper Library for Android
- python入门之控制结构-循环结构_(一)Python入门-4控制语句:05while循环结构-死循环处理...
- unix 存储空间不足 无法处理此命令_大数据分析命令行使用教程
- 一行代码快速搞定Flowable断点下载(下)
- 无线基站侧的信令风暴根因——频繁的释放和连接RRC产生大量信令、设备移动导致小区重选信令增加、寻呼信令多...
- VoltDB介绍——本质:数据保存在内存,充分利用CPU,单线程去锁,底层数据结构未知...
- 在CentOS上安装Python
- notepad++取消语法检测
- Grinder搭建小记与Nduja(这次不待续了)