Как правило, создавать Map
вот так - плохая идея.JSON Object
можно преобразовать в Java
Map
, где key
- это String
, а value
- это любое Object
: может быть другой Map
, array
, POJO
или простой тип.Итак, обычно ваш JSON
должен выглядеть следующим образом:
{
"key" : { .. complex nested object .. }
}
Theres другой вариант.Если вы хотите иметь в Java
отображение POJO
-> POJO
, вам нужно указать десериализатору, как преобразовать JSON
- String
- key
в объект.Там нет другого варианта.Я попытаюсь объяснить этот процесс, используя библиотеку Jackson
, потому что она наиболее часто используется в RESTful Web Services
.Давайте определим класс Person
, который соответствует вашей полезной нагрузке JSON
.
class Person {
private String name;
private double weight;
private int id;
public Person() {
}
public Person(String value) {
String[] values = value.split(",");
name = values[0];
weight = Double.valueOf(values[1]);
id = Integer.valueOf(values[2]);
}
public Person(String name, double weight, int id) {
this.name = name;
this.weight = weight;
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getWeight() {
return weight;
}
public void setWeight(double weight) {
this.weight = weight;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
return id == person.id;
}
@Override
public int hashCode() {
return Objects.hash(id);
}
@Override
public String toString() {
return name + "," + weight + "," + id;
}
}
Поскольку он используется в Map
в качестве ключа, нам нужно реализовать методы hashCode
и equals
.За исключением конструктора public Person(String value)
и метода toString
, все остальное выглядит довольно нормально.Теперь давайте посмотрим на этот конструктор и метод toString
.Они находятся в корреляции: toString
строит String
из экземпляра Person
и конструктор строит Person
из String
.Первое преобразование мы можем назвать сериализацией , а второе - десериализацией нашего ключа в Map
сериализации и десериализацией. (Хорошо ли реализованы эти два аспекта - это уже другая история. Я просто хочу показать идею, стоящую за этим. Перед использованием на производстве следует улучшить)
Давайте использовать эти знания и Jackson
функции для сериализации и десериализации Map<Person, Person>
:
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.KeyDeserializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.type.MapType;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
public class JsonApp {
public static void main(String[] args) throws Exception {
// register deserializer for Person as keys.
SimpleModule module = new SimpleModule();
module.addKeyDeserializer(Person.class, new PersonKeyDeserializer());
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(module);
mapper.enable(SerializationFeature.INDENT_OUTPUT);
// Create example Map
Person key = new Person("Rick", 80.5, 1);
Person value = new Person("Morty", 40.1, 2);
Map<Person, Person> personMap = new HashMap<>();
personMap.put(key, value);
// Serialise Map to JSON
String json = mapper.writeValueAsString(personMap);
System.out.println(json);
// Deserialise it back to `Object`
MapType mapType = mapper.getTypeFactory().constructMapType(HashMap.class, Person.class, Person.class);
System.out.println(mapper.readValue(json, mapType).toString());
}
}
class PersonKeyDeserializer extends KeyDeserializer {
@Override
public Object deserializeKey(String key, DeserializationContext ctxt) {
return new Person(key);
}
}
Выше кода печатается как первый JSON
:
{
"Rick,80.5,1" : {
"name" : "Morty",
"weight" : 40.1,
"id" : 2
}
}
Как видите, метод Person
* toString
был использован для генерации JSON
key
.Обычный процесс сериализации сериализовал объект Person
до JSON
.Как показано ниже, печатается второй текст:
{Rick,80.5,1=Morty,40.1,2}
Это стандартное представление Map
и его ключей и значений.Поскольку оба объекта Person
, вызывается метод toString
.
Как видите, есть возможность отправить JSON
как Map<Person, Person>
, но ключ должен быть как-то представлен.Вам нужно взглянуть на реализацию класса Person
.Может быть, вы найдете некоторые сходства с моим примером.Если нет, возможно, это было настроено как-то.Прежде всего, попробуйте отправить PostMan
:
{
"123" : {"name":"def","weight":200.0,"id":"123"}
}
Или:
{
"{\"name\":\"abc\",\"weight\":100.0,\"id\":\"123\"}":{
"name":"def",
"weight":200.0,
"id":"123"
}
}
Возможно, это будет работать.
См. Также: