enum json convert

java里,enum类型跟json的互相转换,以及利用orm库doma2时的转换

enum和实用类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@RequiredArgsConstructor
@Getter
public enum ReportType {
OPPORTUNITY("01", "合同"),
PARKING_LOT("02", "车库"),
COMPANY("03", "公司");

private final String value;
private final String name;
}
@Data
@AllArgsConstructor
public class Report{
private Integer reportId;
private ReprortType reprortType;
}

enum->json

使用@JsonValue,可以在转换为json时输出赋予的字段

1
2
3
4
5
6
7
8
9
10
11
@RequiredArgsConstructor
@Getter
public enum ReportType {
OPPORTUNITY("01", "合同"),
PARKING_LOT("02", "车库"),
COMPANY("03", "公司");

@JsonValue
private final String value;
private final String name;
}

下面这个实例

1
new Reprot(1, ReportType.PARKING_LOT);

输出为

1
{"reportId":1, "reprortType":"02"}

使用@JsonFormat,可以把enum作为整体输出

1
2
3
4
5
6
7
8
9
10
11
@RequiredArgsConstructor
@Getter
@JsonFormat(shape = JsonFormat.Shape.OBJECT)
public enum ReportType {
OPPORTUNITY("01", "合同"),
PARKING_LOT("02", "车库"),
COMPANY("03", "公司");

private final String value;
private final String name;
}

下面这个实例

1
new Reprot(1, ReportType.PARKING_LOT);

输出为

1
{"reportId":1, "reprortType":{"value":"02", "name":"车库"}}

自定义Serializer

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class ReportSerializer extends StdSerializer<ReportType> {
public ReportSerializer() {
super(ReportType.class);
}

@Override
public void serialize(ReportType reportType, JsonGenerator gen, SerializerProvider provider) throws IOException {
gen.writeStartObject();
gen.writeFieldName("value");
gen.writeString(reportType.getValue());
gen.writeFieldName("name");
gen.writeString(reportType.getName());
gen.writeEndObject();
}
}

制定一个Module

如果类似的enum比较多,可以定义一个interface

1
2
3
4
public interface Enumerator {
String getValue();
String getName;
}

1
2
3
4
5
6
7
8
9
10
@RequiredArgsConstructor
@Getter
public enum ReportType implements Enumerator{
OPPORTUNITY("01", "合同"),
PARKING_LOT("02", "车库"),
COMPANY("03", "公司");

private final String value;
private final String name;
}

然后制定一个Module,注册到spring里

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Bean
public Jackson2ObjectMapperBuilderCustomizer enumCustomizer(){
return jacksonObjectMapperBuilder -> jacksonObjectMapperBuilder.serializerByType(Enumerator.class, new JsonSerializer<Enumerator>() {
@Override
public void serialize(Enumerator value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
gen.writeStartObject();
gen.writeStringField("code",value.getValue());
gen.writeStringField("description",value.getName());
gen.writeEndObject();


}
});
}

json->enum

使用@JsonValue,使用指定字段构建enum

1
{"reportId":1, "reprortType":"02"}

转换为

1
new Reprot(1, ReportType.PARKING_LOT);

使用JsonCreator,自定义创建发方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@RequiredArgsConstructor
@Getter
public enum ReportType {
OPPORTUNITY("01", "合同"),
PARKING_LOT("02", "车库"),
COMPANY("03", "公司");

private final String value;
private final String name;

@JsonCreator(mode = JsonCreator.Mode.DELEGATING)
public static ReportType of(String value) {
for (ReportType reportType : ReportType.values()) {
if (reportType.value.equals(value)) {
return reportType;
}
}
throw new IllegalArgumentException(value);
}
}

根据需求自由组合

一般项目会根据前端用关键字段进行json<->enum的转换,所以使用@JsonValue最为方便。
另外如果在输出的时候,有特殊要求,可以用自定义Serializer的形式进行注解
结合doma2的使用,最终的形式为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
@Domain(valueType = String.class, factoryMethod = "of")
@RequiredArgsConstructor
@Getter
public enum ReportType {
OPPORTUNITY("01", "合同"),
PARKING_LOT("02", "车库"),
COMPANY("03", "公司");

@JsonValue
private final String value;
private final String name;

public static ReportType of(String value) {
for (ReportType reportType : ReportType.values()) {
if (reportType.value.equals(value)) {
return reportType;
}
}
throw new IllegalArgumentException(value);
}

public static List<ReportType> getAll() {
return List.of(ReportType.values());
}
}

public class ReportSerializer extends StdSerializer<ReportType> {
public ReportSerializer() {
super(ReportType.class);
}

@Override
public void serialize(ReportType reportType, JsonGenerator gen, SerializerProvider provider) throws IOException {
gen.writeStartObject();
gen.writeFieldName("value");
gen.writeString(reportType.getValue());
gen.writeFieldName("name");
gen.writeString(reportType.getName());
gen.writeEndObject();
}
}

使用

1
2
3
4
5
6
7
8
9
10
11
@Data
public class Report{
private Integer reportId;
private ReprortType reprortType;
}

@Data
public class ReportDefinition{
@JsonSerialize(contentUsing = ReportSerializer.class)
private List<ReprortType> reprortType;
}