杰克逊顶部

开始使用Spring 5和Spring Boot 2,通过学习的春天课程:

>>查看课程

1.概述

在本文中,我们将探索各种可以控制的方法如果字段被Jackson序列化/反序列化与否。

2.一个公共领域

确保一个字段既可序列化又可反序列化的最简单方法是将其公开。

让我们向公众宣布一个简单的课程,包裹私人和私人

公共类MyDtoAccessLevel {私有字符串StringValue;INT INTVALUE;受保护的浮法浮动值;公共布尔布尔值;//没有安置者或吸毒者}

在班级的四个领域中,只有公共领域BooleanValue.将在默认情况下序列化为JSON:

@test public vivendifferentaccesslevels_whenpublic_thenserializable()抛出jsonprocessingexception {objectmapper mapper = new objectmapper();MyDtoAccessLevel dtoObject = new MyDtoAccessLevel();String dtoAsString = mapper.writeValueAsString(dtoObject);assertthat(dtoasstring,not(containstring(“stringvalue”))));为了(dtoAsString,而不是(containsString(“intValue”)));assertthat(dtoasstring,not(包含(“floatvalue”))));为了(dtoAsString containsString (booleanValue "));}

3.Getter使非公共字段可序列化和反序列化

现在,另一种使字段——尤其是非公共字段——可序列化的简单方法是为它添加一个getter:

公共类MyDtowithGetter {私有字符串StringValue;私人INT INTVALUE;public string getStringValue(){return stringValue;}}

我们现在期待stringValue字段是可序列化的,而另一个私有字段不是,因为它没有getter:

@Test public void givenDifferentAccessLevels_whenGetterAdded_thenSerializable() throws JsonProcessingException {ObjectMapper mapper = new ObjectMapper();mydtotter dtoObject = new mydtotter ();String dtoAsString = mapper.writeValueAsString(dtoObject);为了(dtoAsString containsString (stringValue "));为了(dtoAsString,而不是(containsString(“intValue”)));}

不太直观的是,getter还使私有字段反序列化——因为一旦它有了getter,该字段就被认为是一个属性。

让我们来看看那样的工作:

@Test public void givenDifferentAccessLevels_whenGetterAdded_thenDeserializable() throws JsonProcessingException, JsonMappingException, IOException {String jsonAsString = "{\"stringValue\":\"dtoString\"}";ObjectMapper = new ObjectMapper();MyDtoWithGetter dtoObject = mapper。readValue (jsonAsString MyDtoWithGetter.class);为了(dtoObject.getStringValue(),等于(dtoString "));}

4.Setter只使非公共字段可反序列化

我们看到了Getter如何使私人领域是可序列化的和偏转。另一方面,Setter只将非公共字段标记为deserializable:

public class MyDtoWithSetter {private int intValue;public void setIntValue(int intValue) {this.intValue = intValue;} public int accessIntValue(){返回intValue;}}

正如你所看到的,私人Intvalue.这个时间只有一个骗局。我们确实有一种方法来访问该价值,但这不是标准的吸气工。

未分组的过程Intvalue.应该正常工作:

@test public vivendifferentAccesslevels_whensetteradded_thendeserializable()抛出jsonprocessingexception,jsonmappingexception,ioException {String jsonasstring =“{\”Intvalue \“:1}”;ObjectMapper = new ObjectMapper();mydtosetter dtooobject = mapper.readvalue(jsonasstring,mydtosetter.class);assertthat(dtooobject.anothergettValue(),等于(1));}

正如我们提到的,setter应该只使字段可反序列化,而不是可序列化:

@Test public void givenDifferentAccessLevels_whenSetterAdded_thenStillNotSerializable() throws JsonProcessingException {ObjectMapper mapper = new ObjectMapper();MyDtoSetter dtoObject =新的MyDtoSetter();String dtoAsString = mapper.writeValueAsString(dtoObject);为了(dtoAsString,而不是(containsString(“intValue”)));}

5.使全局序列化的所有字段

在例如,在某些情况下,例如,您实际上不能直接修改源代码 - 我们需要将Jackson处理的方式配置为来自外部的非公共字段。

通过开启,可以在ObjectMapper级别完成那种全局配置自动侦测函数可以使用上市字段或getter/setter方法用于序列化,或者可能对所有字段开启序列化:

ObjectMapper = new ObjectMapper();mapper.setVisibility (PropertyAccessor。所有,Visibility.NONE);mapper.setVisibility (PropertyAccessor。场,Visibility.ANY);

以下测试用例验证所有成员字段(包括非公共)mydtoaccesslevel.是可序列化的:

@Test public void givenDifferentAccessLevels_whenSetVisibility_thenSerializable() throws JsonProcessingException {ObjectMapper mapper = new ObjectMapper();mapper.setVisibility (PropertyAccessor。场,Visibility.ANY);MyDtoAccessLevel dtoObject = new MyDtoAccessLevel();String dtoAsString = mapper.writeValueAsString(dtoObject);为了(dtoAsString containsString (stringValue "));为了(dtoAsString containsString (intValue "));为了(dtoAsString containsString (booleanValue "));}

6.在序列化/反序列化中更改属性的名称

超越控制哪个字段被序列化或反序列化,您也可以可以控制一个字段映射到JSON和返回的方式吗。我讨论了这个配置

7.忽略序列化或反序列化上的字段

本教程,我们有一个指南如何在序列化和反序列化上完全忽略一个字段。

但是,有时我们只需要忽略这些领域,但不需要忽略这两者。杰克逊对这种有趣的useCase感到灵活。

以下示例显示了一个用户对象,其中包含不应该被序列化为JSON的敏感密码信息。

要做到这一点,我们只需添加@JsonIgnore控件的getter上的密码,并通过应用@JsonPropertysetter上的注释:

@JsonIgnore public String getPassword(){返回密码;} @JsonProperty public void setPassword(String password) {this。密码=密码;}

现在密码信息不会被序列化为JSON:

@test public void givefieldypeisignoredonlyatserialization_whenuserisserialized_thenignored()抛出jsonprocessingexception {objectmapper mapper = new objectmapper();用户userObject = new user();UserObject.setPassword(“Hassword”);string userasstring = mapper.writevalueastring(UserObject);assertthat(userasstring,不是(包含(“密码”))));asserthat(userasstring,not(包含(“password”))));}

但是,包含密码的JSON将成功偏转到用户目的:

@test public void givefieldtypeisignoredonlyatserialization_whenuserisdeserialized_thencorrect()抛出jsonparseexception,jsonmappingexception,ioException {string jsonasstring =“{\”password \“:\”thepassword \“}”;ObjectMapper = new ObjectMapper();user userobject = mapper.readvalue(jsonasstring,user.class);asserthat(UserObject.getPassword(),等于(“屏蔽”));}

8.结论

本教程介绍了Jackson如何选择的基本知识哪个字段是序列化/反序列化的,忽略它在这个过程中,当然还有如何完全控制它。

您也可以通过潜水更深入地了解杰克逊2的下一步忽视一个字段,将JSON数组反序列化为Java数组或集合

中可以找到所有这些示例和代码片段的实现我的github项目-这是一个基于Eclipse的项目,所以它应该很容易导入和运行。

杰克逊底部

开始使用Spring 5和Spring Boot 2,通过学习的春天课程:

>>查看课程
3.注释
最老的
最新
内联反馈
查看所有评论
评论在本文上关闭!