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

如何将 Map<Person, Person> 类型的 JSON 输入传递给

如何将 Map<Person, Person> 类型的 JSON 输入传递给

慕仙森 2022-07-14 17:18:52
我有一个 PUT 类型的 JAX-RS REST 端点,我应该将一个 Map 传递给这个 API。@PUT@Path("/some/path")@Consumes({ MediaType.TEXT_PLAIN, MediaType.APPLICATION_XML,        MediaType.TEXT_XML, MediaType.APPLICATION_JSON })@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })public Response updatePerson(HashMap<Person, Person> map) {//some code here}我为 Person 类生成了 JSON,但我无法将它作为 JSON 输入传递给这个 API。我正在使用 Postman 客户端,当我尝试将 JSON 输入作为键值对传递时,它显示语法错误。为 Person 生成的 JSON 如下所示  {"name":"abc","weight":100.0,"id":"123"}我需要将此作为键值对作为映射传递。就像是 {   {"name":"abc","weight":100.0,"id":"123"} :    {"name":"def","weight":200.0,"id":"123"} }任何指示我该怎么做?
查看完整描述

1 回答

?
一只名叫tom的猫

TA贡献1906条经验 获得超3个赞

一般来说,这样创建看起来是个坏主意Map。JSON Object可以转换为Java Mapwhere keyisString和valueis any Object:可以是另一种Map,array或POJO简单类型。所以,通常你JSON应该看起来像:


{

    "key" : { .. complex nested object .. }

}

没有其他选择。如果你想在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;

    }

}

因为它被用作Mapkey 我们需要实现hashCode和equals方法。除了public Person(String value)构造函数和toString方法,其他一切看起来都很正常。现在,让我们看一下这个构造函数和toString方法。它们是相关的:从实例构建,构造toString函数从. 我们可以将第一次转换称为序列化,然后将第二次转换称为序列化和反序列化中密钥的反序列化。(这两个是否很好实现这是另一回事。我只是想展示一个背后的想法。在生产上使用之前应该改进)StringPersonPersonStringMap


让我们使用这些知识和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);

    }

}

上面的代码打印为 first 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"

   }

}

也许它会起作用。


查看完整回答
反对 回复 2022-07-14
  • 1 回答
  • 0 关注
  • 118 浏览

添加回答

举报

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