为了账号安全,请及时绑定邮箱和手机立即绑定

除了 Jackson 之外,还有其他东西可以用 Java 处理复杂的对象吗?

除了 Jackson 之外,还有其他东西可以用 Java 处理复杂的对象吗?

炎炎设计 2022-06-15 16:27:15
我必须能够在后端接收/发送一个JSON结构,如下面的那个。{     "firstObject":{        "type":"string",      "value":"productValue"   },   "secondObject":{        "type":"string",      "value":"statusValue"   },   "thirdObject":{        "type":"map",      "value":{           "customerName":{              "type":"string",            "value":"customerValue"         }      }   },   "fourthObject":{        "type":"map",      "value":{           "firstObject":{              "type":"map",            "value":{                 "anotherObj1":{                    "type":"string",                  "value":"TEST"               },               "anotherObj2":{                    "type":"date",                  "value":"01/12/2018"               },               "anotherObj3":{                    "type":"date",                  "value":"31/01/2018"               }            }         }      }   }}让这有点棘手的问题是,对于每个对象,我必须知道它的类型是什么。可能有4种类型:整数细绳布尔值地图如果一个对象的值是map(由客户选择的),例如,在前端会出现另一个键/值结构,所以我在后端会收到一个动态结构。我需要对此结构进行验证,以检查它是否符合我期望收到的内容。如果我应该只使用一个Java类来制作我需要的对象,或者除此之外使用Jackson来JSON验证并将所有这些对象映射到JSON.如果我要使用 Jackson,我将不得不制作一个自定义的序列化器和反序列化器。
查看完整描述

2 回答

?
眼眸繁星

TA贡献1873条经验 获得超9个赞

您可以从Jackson库中使用JsonTypeInfoJsonSubTypes注释。它们是句柄多态类型处理:

  • @JsonTypeInfo用于指示序列化中包含哪些类型信息的详细信息

  • @JsonSubTypes用于表示注解类型的子类型

  • @JsonTypeName用于定义用于注释类的逻辑类型名称

您的示例适合此解决方案,除了看起来更像简单POJO类的根对象。在您的情况下,我们应该创建有助于使用以下 3 种类型的类型结构:stringdatemap:

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type")

@JsonSubTypes({

    @JsonSubTypes.Type(value = StringValue.class, name = "string"),

    @JsonSubTypes.Type(value = DateValue.class, name = "date"),

    @JsonSubTypes.Type(value = MapValue.class, name = "map")

})

abstract class HasValue<T> {


    protected T value;


    public HasValue() {

        this(null);

    }


    public HasValue(T value) {

        this.value = value;

    }


    public T getValue() {

        return value;

    }


    public void setValue(T value) {

        this.value = value;

    }


    @Override

    public String toString() {

        return getClass().getSimpleName() + "{" +

            "value=" + value +

            "}";

    }

}


class StringValue extends HasValue<String> {


    public StringValue() {

        this(null);

    }


    public StringValue(String value) {

        super(value);

    }

}


class DateValue extends HasValue<String> {


    public DateValue(String value) {

        super(value);

    }


    public DateValue() {

        this(null);

    }

}


class MapValue extends HasValue<Map<String, HasValue>> {


    public MapValue(Map<String, HasValue> value) {

        super(value);

    }


    public MapValue() {

        this(new LinkedHashMap<>());

    }


    public void put(String key, HasValue hasValue) {

        this.value.put(key, hasValue);

    }

}

现在,我们需要引入POJO根值。它可能如下所示,但您可以根据需要添加 getter/setter。对于这个例子,下面的代码就足够了:


class Root {


    public HasValue firstObject;

    public HasValue secondObject;

    public HasValue thirdObject;

    public HasValue fourthObject;


    @Override

    public String toString() {

        return "Root{" +

            "firstObject=" + firstObject +

            ", secondObject=" + secondObject +

            ", thirdObject=" + thirdObject +

            ", fourthObject=" + fourthObject +

            '}';

    }

}

现在,我们终于可以尝试序列化和反序列化这些对象了:


MapValue customerName = new MapValue();

customerName.put("customerName", new StringValue("customerValue"));


MapValue innerMap = new MapValue();

innerMap.put("anotherObj1", new StringValue("TEST"));

innerMap.put("anotherObj2", new DateValue("01/12/2018"));

innerMap.put("anotherObj3", new DateValue("31/01/2018"));


MapValue fourthObject = new MapValue();

fourthObject.put("firstObject", innerMap);


Root root = new Root();

root.firstObject = new StringValue("productValue");

root.secondObject = new StringValue("statusValue");

root.thirdObject = customerName;

root.fourthObject = fourthObject;


ObjectMapper mapper = new ObjectMapper();

String json = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(root);

System.out.println(json);

System.out.println(mapper.readValue(json, Root.class));

Aboce 代码打印JSON:


{

  "firstObject" : {

    "type" : "string",

    "value" : "productValue"

  },

  "secondObject" : {

    "type" : "string",

    "value" : "statusValue"

  },

  "thirdObject" : {

    "type" : "map",

    "value" : {

      "customerName" : {

        "type" : "string",

        "value" : "customerValue"

      }

    }

  },

  "fourthObject" : {

    "type" : "map",

    "value" : {

      "firstObject" : {

        "type" : "map",

        "value" : {

          "anotherObj1" : {

            "type" : "string",

            "value" : "TEST"

          },

          "anotherObj2" : {

            "type" : "date",

            "value" : "01/12/2018"

          },

          "anotherObj3" : {

            "type" : "date",

            "value" : "31/01/2018"

          }

        }

      }

    }

  }

}

和toString表示:


Root{firstObject=StringValue{value=productValue}, secondObject=StringValue{value=statusValue}, thirdObject=MapValue{value={customerName=StringValue{value=customerValue}}}, fourthObject=MapValue{value={firstObject=MapValue{value={anotherObj1=StringValue{value=TEST}, anotherObj2=DateValue{value=01/12/2018}, anotherObj3=DateValue{value=31/01/2018}}}}}}

您可以通过添加/删除任何类型的HasValue实例轻松地操作输出。


查看完整回答
反对 回复 2022-06-15
?
MMMHUHU

TA贡献1834条经验 获得超8个赞

从这里下载 JSON jar 。从客户端使用 json.stringify 将您的 JSON 转换为字符串(因为 JSONObject 的构造函数只接受字符串)。收到客户端的请求后,执行以下操作:


public void doPost(request,response) throws ParseException, JSONException {

        parseMapFromJSON(request.getParameter("JSONFromClient"));

}

private void parseMapFromJSON(String JSONParam) throws JSONException

{

    JSONObject requestJSON = new JSONObject(JSONParam);

    for(int i=0; i<requestJSON.length();i++)

    {

         String key = (String) requestJSON.names().get(i);             

         if(key.endsWith("Object"))

         {

            parseMapFromJSON(requestJSON.get(key).toString());

         }

         else if(key.startsWith("type") && (requestJSON.get(key).equals("date") || requestJSON.get(key).equals("string")))

         {

            System.out.println(requestJSON.get("value"));

            break;

         }

         else if(key.startsWith("type") && requestJSON.get(key).equals("map"))

         {

            parseMapFromJSON(requestJSON.get("value").toString());

         }

         else if(!key.equals("value"))

         {

            parseMapFromJSON(requestJSON.get(key).toString());

         }

    }

}


查看完整回答
反对 回复 2022-06-15
  • 2 回答
  • 0 关注
  • 88 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信