参考:​​Jackson – Deserialization from json to Java enums​

问题描述

java中使用枚举时,如果涉及到restful调用,不可避免会涉及到枚举的序列化和反序列化工作;

如定义如下枚举

public enum ResType {
INSTANCE("虚拟机", "INSTANCE");

private String name;
private String type;

ResType(String name, String type) {
this.name = name;
this.type = type;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}


public String getType() {
return type;
}

public void setType(String type) {
this.type = type;
}
}

上面代码默认的序列化结果为:

{
"resType": "INSTANCE"
}

如果我们期望序列化的结果为:

{
"resType": {
"name": "虚拟机",
"type": "INSTANCE"
}
}

在需要修改上面的枚举类,最简单的方法是添加:​​@JsonFormat(shape = JsonFormat.Shape.OBJECT)​

添加之后,序列化结果变为:更多的序列化可参考:​​官方序列化示例​

{
"resType": {
"name": "虚拟机",
"type": "INSTANCE"
}
}

但此时若是使用上述结果进行​​反序列化​​操作,将会报错,解决方式可参考文章顶部链接:即添加如下代码

/**
* 用于保存所有的枚举值
*/
private static Map<String, ResType> RESOURCE_MAP = Stream
.of(ResType.values())
.collect(Collectors.toMap(s -> s.getType(), Function.identity()));


/**
* 枚举反序列话调用该方法
*
* @param jsonNode
* @return
*/
@JsonCreator //必须修饰static方法
public static ResType des(final JsonNode jsonNode) {
return Optional
.ofNullable(RESOURCE_MAP.get(jsonNode.get("type").asText()))
.orElseThrow(() -> new IllegalArgumentException(jsonNode.get("type").asText()));
}

【json】与【枚举】的序列化和反序列化_json

代码

controller

@RestController
@RequestMapping("v1")
public class MyController {

@Autowired
private MyService myService;

@GetMapping(value = "/my/model")
public Response<?> endFloatingIpRateTask() {
return Response.success(myService.getModel());
}

/**
* 请求示例:
* <pre>
* {
* "productId": "product01",
* "resType": {
* "name": "虚拟机",
* "type": "INSTANCE"
* }
* }
* </pre>
*
* @param taskResource
* @return
*/
@PostMapping(value = "/set/model")
public Response<?> xxx(@RequestBody MyTaskResource taskResource) {
System.out.println("xxxxxxxxxxxx");
System.out.println(taskResource);
System.out.println("xxxxxxxxxxxx");
return Response.success(taskResource);
}
}

service

@Service
public class MyService {

public MyTaskResource getModel() {
MyTaskResource m = new MyTaskResource();
m.setResType(ResType.INSTANCE);
m.setProductId("product01");
return m;
}
}

model

public class MyTaskResource {

private String productId;
private ResType resType;

public ResType getResType() {
return resType;
}

public void setResType(ResType resType) {
this.resType = resType;
}

public String getProductId() {
return productId;
}

public void setProductId(String productId) {
this.productId = productId;
}

@Override
public String toString() {
return MoreObjects.toStringHelper(this)
.add("productId", productId)
.add("resType", resType)
.toString();
}
}

枚举

@JsonFormat(shape = JsonFormat.Shape.OBJECT)
public enum ResType {
INSTANCE("虚拟机", "INSTANCE");

/**
* 用于保存所有的枚举值
*/
private static Map<String, ResType> RESOURCE_MAP = Stream
.of(ResType.values())
.collect(Collectors.toMap(s -> s.getType(), Function.identity()));
private String name;
private String type;

ResType(String name, String type) {
this.name = name;
this.type = type;
}

/**
* 枚举反序列话调用该方法
*
* @param jsonNode
* @return
*/
@JsonCreator
public static ResType des(final JsonNode jsonNode) {
return Optional
.ofNullable(RESOURCE_MAP.get(jsonNode.get("type").asText()))
.orElseThrow(() -> new IllegalArgumentException(jsonNode.get("type").asText()));
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}


public String getType() {
return type;
}

public void setType(String type) {
this.type = type;
}
}

测试结果

【json】与【枚举】的序列化和反序列化_反序列化_02