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

参考: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;
  }
}

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

测试结果

原文地址:https://www.cnblogs.com/ssslinppp/p/10307801.html