Java 将JSON转换为具有JSON属性的POJO,将其转换为具有不同属性的jsonObject

Java 将JSON转换为具有JSON属性的POJO,将其转换为具有不同属性的jsonObject,java,json,jackson,fasterxml,Java,Json,Jackson,Fasterxml,我有新的需求,我正在创建RESTAPI,它有动态请求(操作),我想将JSON请求转换为POJO,我知道如何将JSON转换为POJO,其中键是相同的,但不确定当对象上有不同的内容时该怎么办 我的Json如下所示 { "name":"Workflow", "actions": [ { "name": "EDIT_PROPERTY", "payload&

我有新的需求,我正在创建RESTAPI,它有动态请求(操作),我想将JSON请求转换为POJO,我知道如何将JSON转换为POJO,其中键是相同的,但不确定当对象上有不同的内容时该怎么办

我的Json如下所示

{
  "name":"Workflow",
  "actions": [
    {
      "name": "EDIT_PROPERTY",
      "payload": {
        "name": "city",
        "value": "Pune"
      }
    },
    {
      "name":"SEND_EMAIL",
      "payload":{
        "from":"no-reply@yaho.com",
        "to":"alpesh@yahoo.com",
        "subject":"Try email",
        "body":"content"
      }
    },
    {
      "name":"CREATE_TASK",
      "payload":{
        "user":1,
        "type":"call",
        "status":"open",
        "note":"This is  note content"
      }
    }
  ]
}
正如您所看到的,操作是一组具有名称和负载的对象,现在负载有了不同的字段,我有了预定义的名称。正如您所看到的,每个工作负载都有预定义的键

我想把它转换成POJO之类的东西

class Workflow{
    String name;
    Set<Action> actions;
}

class Action {
    String name;
    //What to add as payload
}
类工作流{
字符串名;
采取行动;
}
集体诉讼{
字符串名;
//添加什么作为有效负载
}
谢谢


阿尔佩什

这是您可以做的:

JSON到POJO模型:

@Data
@JsonInclude(JsonInclude.Include.NON_NULL)
public class Event {
    public String name;
    public List<Action> actions;


    @Data
    public static class Action {
        public String name;
        Map<String, Object> payload;
    }


}

public class TestJson {

    private static String json = "{\n" +
            "  \"name\":\"Workflow\",\n" +
            "  \"actions\": [\n" +
            "    {\n" +
            "      \"name\": \"EDIT_PROPERTY\",\n" +
            "      \"payload\": {\n" +
            "        \"name\": \"city\",\n" +
            "        \"value\": \"Pune\"\n" +
            "      }\n" +
            "    },\n" +
            "    {\n" +
            "      \"name\":\"SEND_EMAIL\",\n" +
            "      \"payload\":{\n" +
            "        \"from\":\"no-reply@yaho.com\",\n" +
            "        \"to\":\"alpesh@yahoo.com\",\n" +
            "        \"subject\":\"Try email\",\n" +
            "        \"body\":\"content\"\n" +
            "      }\n" +
            "    },\n" +
            "    {\n" +
            "      \"name\":\"CREATE_TASK\",\n" +
            "      \"payload\":{\n" +
            "        \"user\":1,\n" +
            "        \"type\":\"call\",\n" +
            "        \"status\":\"open\",\n" +
            "        \"note\":\"This is  note content\"\n" +
            "      }\n" +
            "    }\n" +
            "  ]\n" +
            "}";

    @SneakyThrows
    public static void main(String[] args) {
        ObjectMapper objectMapper = new ObjectMapper();
        Event event = objectMapper.readValue(json, Event.class);
        System.out.println(event);

    }


}
@数据
@JsonInclude(JsonInclude.Include.NON_NULL)
公开课活动{
公共字符串名称;

公共列表

一般来说,我更喜欢任何不涉及组件注释的解决方案。这是我个人的偏好,因为消除
构造函数
和方法
参数
通常是一个非常头痛的问题。这是基于1999-2006年的Java编程经验。如果您需要只需生成类和
构造函数
getter
,您就可以很容易地忽略或删除这个答案。对我来说,JSON解析现在是实践

在这个发布的答案中,我使用了较旧的JavaJSON库,其JavaDoc可在此处查看:。这是我的解决方案。它要求/期望您编写:

  • 您自己的
    toString()
    方法,用于JSON数据类
  • 您自己的检索操作
下面的代码有输出,这已包含在本文末尾。通常我会包含很多代码文档。但是,当代码严格解析数据时,代码本身通常非常清晰,以至于更多的注释会将检索
toString()弄得乱七八糟
操作,因此我将它们保留原样

import java.util.*;
import javax.json.*;
import java.io.*;

public class Messages
{
    public abstract static class Action
    {
        public final String name;
        public Action(String name) { this.name=name; }
    }

    public static class EditProperty extends Action
    {
        public final String propName, propValue;

        public EditProperty(String name, String value)
        { super("EDIT_PROPERTY"); this.propName=name; this.propValue=value; }

        public String toString()
        { 
            return 
                "Action:   " + name         + '\n' + 
                "Name:     " + propName     + '\n' +
                "Value:    " + propValue    + '\n';
        }
    }

    public static class SendEmail extends Action
    {
        public final String from, to, subject, body;

        public SendEmail(String from, String to, String subject, String body)
        { super("SEND_EMAIL"); this.from=from; this.to=to; this.subject=subject; this.body=body; }

        public String toString()
        {
            return
                "Action:   "    + name      + '\n' +
                "From:     "    + from      + '\n' +
                "To:       "    + to        + '\n' +
                "Subject:  "    + subject   + '\n' +
                "Body:     "    + body      + '\n';
        }
    }

    public static class CreateTask extends Action
    {
        public final int user;
        public final String type, status, note;

        public CreateTask(int user, String type, String status, String note)
        { super("CREATE_TASK"); this.user=user; this.type=type; this.status=status; this.note=note; }

        public String toString()
        {
            return
                "Action:   " + name     + '\n' +
                "User:     " + user     + '\n' +
                "Type:     " + type     + '\n' +
                "Status:   " + status   + '\n' +
                "Note:     " + note     + '\n';
        }
    }

    public static void main(String[] argv) throws IOException
    {
        Vector<Action>  actions     = new Vector<>();
        Reader          r           = new FileReader("in.json");

        JsonArray       actionList  = Json
            .createReader(r)
            .readObject()
            .getJsonArray("actions");

        for (JsonObject actionObj : actionList.getValuesAs(JsonObject.class))
        {
            JsonObject  payload = actionObj.getJsonObject("payload");
            Action      action  = null;

            switch (actionObj.getString("name"))
            {
                case "EDIT_PROPERTY"    :   action = new EditProperty(
                                                payload.getString("name"),
                                                payload.getString("value")
                                            ); break;
                case "SEND_EMAIL"       :   action = new SendEmail(
                                                payload.getString("from"),
                                                payload.getString("to"),
                                                payload.getString("subject"),
                                                payload.getString("body")
                                            ); break;
                case "CREATE_TASK"      :   action = new CreateTask(
                                                payload.getInt("user"),
                                                payload.getString("type"),
                                                payload.getString("status"),
                                                payload.getString("note")
                                            ); break;
            }
            
            actions.add(action);
        }
        
        for (Action action : actions) System.out.println(action);
    }
}

您显示的JSON实际上是一个对象类型的列表; 具体来说,有效负载只是字符串到对象的映射

一旦解析了JSON, 您的代码将需要处理每种“不同”的负载类型 基于有效负载类型

以下是一些示例代码:

公共类消息
{
私有字符串名称;
专用地图有效载荷;
...
}
公共类消息持有者
{
@JsonProperty(“操作”)
私有列表消息列表;
私有字符串名称;
...
}

可以将有效负载存储为Map?但当我使用Object时,它不是类型安全的。@Alpesh Jikadra您使用了哪个JSON库?我使用了
Jackson
(JDK 1.8)对其进行了测试如@SKumar所述,将字段
有效载荷
反序列化为
映射
,它可以正常工作,没有任何错误。您是否同意映射或希望保留数据类型?@SKumar,是的,我希望保留数据类型。这样,我可能会在有效载荷类下添加太多字段,这对于其他实体来说是不需要的。例如,编辑属性RTY类型。将来我可能会有新操作的新类型的有效负载。@AlpeshJikadra好的,在这种情况下,我已经将有效负载更新为map,即map payload;也更新了答案,并且它可以正常工作。我可以使用某种继承来代替map,这样我就可以使用基类而不是map了吗?
@cloudshell:~$ java Messages 
Action:   EDIT_PROPERTY
Name:     city
Value:    Pune

Action:   SEND_EMAIL
From:     no-reply@yaho.com
To:       alpesh@yahoo.com
Subject:  Try email
Body:     content

Action:   CREATE_TASK
User:     1
Type:     call
Status:   open
Note:     This is  note content