zoukankan      html  css  js  c++  java
  • 【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;
      }
    }
    

    测试结果

  • 相关阅读:
    洛谷【P1109 学生分组】 题解
    卡特兰数
    并查集
    深度优先搜索DFS;递归
    【71】序列模型和注意力机制
    c/c++ 常用的几个安全函数
    win32 Ui 编程 收集
    vc获取特殊路径(SpecialFolder)
    std::map 自定义排序
    16-----BBS论坛
  • 原文地址:https://www.cnblogs.com/ssslinppp/p/10307801.html
Copyright © 2011-2022 走看看