Java 将JSON转换为具有JSON属性的POJO,将其转换为具有不同属性的jsonObject
我有新的需求,我正在创建RESTAPI,它有动态请求(操作),我想将JSON请求转换为POJO,我知道如何将JSON转换为POJO,其中键是相同的,但不确定当对象上有不同的内容时该怎么办 我的Json如下所示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&
{
"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