将JSON转换为具有Json属性的POJO作为具有diffrent属性的jsonObject

问题描述

我有一个新要求,我正在创建具有动态请求(动作)的REST API,我想将该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
}

谢谢

Alpesh

解决方法

这是您可以做的:

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);

    }


}

调试时,您会注意到我们的对象已相应填充:

[1]: https://i.stack.imgur.com/wbGLT.png

,

一般来说,我更喜欢不涉及组件注释的任何解决方案。这是我个人的偏爱,因为消除constructors和方法parameters通常令人头疼。这是基于1999年-2006年Java编程经验。如果您需要动态生成类和constructorsgetters,则可以轻松地忽略或删除此答案。对我来说, JSON解析现在是实践。

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

  • 您自己的用于{strong> JSON数据类
  • toString()方法
  • 您自己的 检索操作

以下代码已输出,并且包含在本文的结尾。通常,我会包含很多代码文档。但是,当代码严格解析数据时,代码本身通常很清晰,以至于更多的注释会使检索 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);
    }
}

在命令行上调用时,上述类和内部类将产生以下输出:

@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
,

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

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

以下是一些示例代码:

public class BlamMessage
{
    private String name;
    private Map<String,Object> payload;

    ...
}

public class MessageHolder
{
    @JsonProperty("actions")
    private List<BlamMessage> messageList;

    private String name;

    ...
}