问题描述
我有一个新要求,我正在创建具有动态请求(动作)的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);
}
}
调试时,您会注意到我们的对象已相应填充:
,一般来说,我更喜欢不涉及组件注释的任何解决方案。这是我个人的偏爱,因为消除constructors
和方法parameters
通常令人头疼。这是基于1999年-2006年Java编程经验。如果您需要动态生成类和constructors
或getters
,则可以轻松地忽略或删除此答案。对我来说, 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;
...
}