Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/367.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
除了Jackson之外,在Java中complexe对象还需要处理其他东西吗?_Java_Json_Spring_Validation_Jackson - Fatal编程技术网

除了Jackson之外,在Java中complexe对象还需要处理其他东西吗?

除了Jackson之外,在Java中complexe对象还需要处理其他东西吗?,java,json,spring,validation,jackson,Java,Json,Spring,Validation,Jackson,在后端,我必须能够接收/发送JSON结构,如下所示 { "firstObject":{ "type":"string", "value":"productValue" }, "secondObject":{ "type":"string", "value":"statusValue" }, "thirdObject":{ "type":"map", "value":{

在后端,我必须能够接收/发送
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种类型:

  • int
  • 布尔值
  • 地图
例如,如果对象的值是
map
(由客户选择),则在前端会出现另一个键/值结构,因此我在后端会收到一个动态结构。我需要对这个结构进行验证,以检查它是否符合我期望得到的结果

如果我只使用一个
Java
类来制作我需要的对象,或者除此之外用于
JSON
验证并将所有对象映射到
JSON
中,我将非常感谢您的意见


如果我要使用Jackson,我必须定制一个序列化程序和反序列化程序。

从下载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());
         }
    }
}
public void doPost(请求、响应)抛出ParseException、jsoneexception{
parseMapFromJSON(request.getParameter(“JSONFromClient”);
}
私有void parseMapFromJSON(字符串JSONParam)抛出JSONException
{
JSONObject requestJSON=新的JSONObject(JSONParam);

对于(int i=0;i来自
Jackson
库,您可以使用
JsonTypeInfo
JsonSubTypes
注释。它们是句柄多态类型处理:

  • @JsonTypeInfo
    用于指示序列化中包含的类型信息的详细信息
  • @JsonSubTypes
    用于指示注释类型的子类型
  • @JsonTypeName
    用于定义用于注释类的逻辑类型名
您的示例适用于此解决方案,但根对象看起来更像简单的
POJO
类。在您的示例中,我们应该使用有助于处理这3种类型的类型结构:
string
date
map

@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);
    }
}
现在,我们终于可以尝试序列化和反序列化这些对象了:

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
实例,可以轻松地操作输出

有关更多信息,请参阅:


  • 谢谢!你认为ASM的操作会更适合这个吗?我不这么认为。你的java类中不需要任何操作。当你只解析JSON时,为什么需要这样做?
    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}}}}}}