參考: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()));
}

代碼
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;
}
}
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;
}
}