杰克逊前

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

>>查看课程

1.概述

这个快速教程将展示如何控制这种方式Java枚举使用Jackson 2进行序列化和反序列化

更深入地挖掘和学习我们还可以做其他很酷的事情-往前走主要的Jackson教程

2.控制枚举表示

让我们定义以下枚举:

公共枚举距离{公里(“km”,1000),英里(“Miles”,1609.34),仪表(“米”,1),英寸(“英寸”,0.0254),厘米(“CM”,0.01),毫米(“mm”,0.001);私有弦单位;私人最终的双米;私人距离(弦单位,双米){this.unit =单位;这=米。} //标准getters和setter}

3.将枚举序列化为JSON

3.1。默认的枚举表示

默认情况下,Jackson将表示Java枚举作为简单字符串 - 例如:

new objectmapper()。writevalueastring(距离);

将导致:

“英里”

在编组这个时我们想要得到的东西枚举到一个JSON对象就是给予如下的东西:

{“单位”:“千米万”,“米”:1609.34}

3.2。枚举作为JSON对象

从Jackson 2.1.2开始,现在存在一个可以处理这种表示的配置选项。这可以通过@JsonFormat类级别的注释:

@JsonFormat(shape = JsonFormat.Shape.OBJECT) public enum距离{…}

这将导致在序列化时所期望的结果枚举距离。公里:

{“单位”:“千米万”,“米”:1609.34}

3.3。枚举和@jsonvalue.

控件控制枚举封送输出的另一种简单方法是使用@jsonvalue.getter上的注释:

public enum距离{…@JsonValue public String getMeters(){返回米;}}

我们在这里表达的是那个GetMeters()是该枚举的实际表示。因此,序列化的结果将是:

1609.34

3.4。用于枚举的自定义序列化器

在Jackson 2.1.2之前,或者如果枚举需要更多的定制,我们可以使用定制的杰克逊序列化器。首先,我们需要定义它:

public class DistanceSerializer extends StdSerializer {public DistanceSerializer() {super(Distance.class);} public DistanceSerializer(Class t) {super(t);} public void serialize(Distance Distance, JsonGenerator generator, SerializerProvider provider) throws IOException, JsonProcessingException {generator. writestartobject ();generator.writeFieldName(“名字”);generator.writeString (distance.name ());generator.writeFieldName(“单位”);generator.writeString (distance.getUnit ());generator.writeFieldName(“米”);generator.writeNumber (distance.getMeters ());generator.writeEndObject (); } }

我们现在将序列化器应用于将序列化的类:

@jsonserialize(使用= extandserializer.class)public enum typeenum {...}

哪些结果:

{“姓名”:“英里”,“单位”:“Miles”,“米”:1609.34}

4.将JSON反序列化为枚举

首先,我们定义a城市类,该类具有距离成员:

公共类城市{私人距离距离;…}

接下来,我们将讨论将JSON字符串反序列化为Enum的不同方法。

4.1。默认行为

默认情况下,Jackson将使用Enum名称从JSON反序列化

例如,它将反序列化JSON:

{“距离”:“公里”}

到一个距离.Kileom目的:

城市=新objectMapper()。ReadValue(Json,City.class);assertequals(距离。kilometer,city.getdistance());

4.2。使用@jsonvalue.

我们学会了如何使用@jsonvalue.序列化枚举。我们也可以使用相同的注释进行反序列化。这是可能的,因为枚举值是常量。

首先,让我们使用@jsonvalue.与其中一个吸气方法 -GetMeters():

公共枚举距离{... @jsonvalue public double getmeters(){返回米;}}

的返回值GetMeters()方法表示枚举对象。因此,当反序列化样本JSON时:

{“距离”:“0.0254”}

Jackson将查找具有GetMeters()返回值为0.0254。在这个例子中,对象是距离。英寸:

assertequal(距离。寸,city.getDistance ());

4.3。使用@jsonproperty.

@jsonproperty.注释用于枚举实例:

@JsonProperty(" Distance -in-miles") MILE("miles", 1609.34);…}

通过使用这个注释,我们只是告诉杰克逊来绘制的价值@jsonproperty.对具有此值注释的对象

作为上述声明的结果,示例JSON字符串:

{“距离”:“距离KM”}

将被映射到距离.Kileom目的:

assertequals(距离。kilometer,city.getdistance());

4.4。使用@jsoncreator.

杰克逊调用了注释的方法@jsoncreator.获取外围类的实例。

考虑JSON表示:

{“距离”:{“单位”:“Mills”,“米”:1609.34}}

现在,我们来定义看中()工厂方法@jsoncreator.注释:

@JsonCreator public static Distance forValues(@JsonProperty("unit") String unit, @JsonProperty("meters") double meters) {for (Distance Distance: Distance.values()) {if (Distance .unit.equals(unit) && double .compare(Distance. meters, meters) == 0) {return Distance;}}返回null;}……}

注意使用@jsonproperty.注释将JSON字段与方法参数绑定。

然后,当我们将JSON样本进行反序列化时,我们将获得结果:

assertequal(距离。英里,city.getDistance ());

4.5。使用自定义反序列化器

如果所描述的技术都不可用,则可以使用自定义反序列化器。例如,我们可能无法访问Enum源代码,或者使用一个较老的Jackson版本,该版本不支持到目前为止介绍的一个或多个注释。

根据我们的自定义反序列化文章,为了反驳上一节中提供的JSON,我们将首先创建Deserialization类:

公共类CustomEnumDeserializer扩展了StdDeserializer <距离> {@Override公共距离Deserialize(JONSParser JSONParser,DeserializationContext CTXT)抛出IoException,JsonProcessingException {JSONnode节点= JSONParser.getCodec()。ReadTree(JSONParser);字符串单元= node.get(“单位”)。astext();双米= node.get(“米”)。aswouble();for(距离距离:textent.values()){if(teasty.getUnit()。等于(单位)&& double.comPare(距离.getmeters(),米)== 0){返回距离;}}返回null;}}

接下来,我们使用@JsonDeserialize注释枚举来指定我们的自定义反序列化器:

@JsonDeserialize(using = CustomEnumDeserializer.class) public enum距离{…}

我们的结果是:

assertequal(距离。英里,city.getDistance ());

结论

本文说明了如何获得更好的控制Java枚举的序列化和反序列化进程和格式

可以找到所有这些示例和代码片段的实现在GitHub

杰克逊底部

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

>>查看课程
对这篇文章的评论关闭!