【json】與【枚舉】的序列化和反序列化

參考:Jackson – Deserialization from json to Java enums

問題描述

java中使用枚舉時,若是涉及到restful調用,不可避免會涉及到枚舉的序列化和反序列化工做;java

如定義以下枚舉git

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

上面代碼默認的序列化結果爲:github

{
        "resType": "INSTANCE"
}

若是咱們指望序列化的結果爲:json

{
        "resType": {
            "name": "虛擬機",
            "type": "INSTANCE"
        }
 }

在須要修改上面的枚舉類,最簡單的方法是添加:@JsonFormat(shape = JsonFormat.Shape.OBJECT)
添加以後,序列化結果變爲:更多的序列化可參考:官方序列化示例restful

{
        "resType": {
            "name": "虛擬機",
            "type": "INSTANCE"
        }
 }

但此時如果使用上述結果進行反序列化操做,將會報錯,解決方式可參考文章頂部連接:即添加以下代碼app

/**
   * 用於保存全部的枚舉值
   */
  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()));
  }

代碼

controlleride

@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;
  }
}

modelthis

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

枚舉rest

@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;
  }
}

測試結果

相關文章
相關標籤/搜索