Есть что-то еще, кроме Джексона, для сложных объектов для обработки в Java? - PullRequest
0 голосов
/ 11 февраля 2019

Я должен иметь возможность на внутренней стороне получать / отправлять структуру 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
  • string
  • boolean
  • map

Если значение дляобъект map (выбранный клиентом), например, на стороне внешнего интерфейса появится еще одна структура ключ / значение, поэтому то, что я получу на стороне сервера, - это динамическая структура.Мне нужно будет проверить эту структуру, чтобы проверить, соответствует ли она тому, что я ожидаю получить.

Буду признателен за мнение, если я буду использовать просто класс Java, чтобыобъекты, которые мне нужны, или чтобы использовать их, Джексон для JSON проверки и сопоставления всех этих объектов в JSON.

Если я буду использовать Джексона, ядолжны сделать нестандартный сериализатор и десериализатор.

Ответы [ 2 ]

0 голосов
/ 11 февраля 2019

Из библиотеки 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);
    }
}

Теперь нам нужно ввести POJO для корневого значения.Это может выглядеть как показано ниже, но вы можете добавить геттеры / сеттеры, если хотите.Для приведенного ниже примера будет достаточно кода:

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 экземпляра.

Для получения дополнительной информации см .:

  1. аннотации Джексона
  2. Джексон Мавен
0 голосов
/ 11 февраля 2019

Загрузите JSON jar из здесь .Со стороны клиента преобразуйте JSON в строку, используя json.stringify (потому что конструктор 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());
         }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...