Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如果在解析之前我不知道所有JSON字段,如何将JSON转换为Java对象?_Java_Json - Fatal编程技术网

如果在解析之前我不知道所有JSON字段,如何将JSON转换为Java对象?

如果在解析之前我不知道所有JSON字段,如何将JSON转换为Java对象?,java,json,Java,Json,我的服务可以接收多个不同的JSON,例如: { "event":"conversation_started", "context":"context information", "user":{ "id":"01234567890A=", "name":"John McClane", "avatar":"http://avatar.example.com", "country":"UK", "language":"en

我的服务可以接收多个不同的JSON,例如:

{
   "event":"conversation_started",
   "context":"context information",
   "user":{
      "id":"01234567890A=",
      "name":"John McClane",
      "avatar":"http://avatar.example.com",
      "country":"UK",
      "language":"en",
      "api_version":1
   },
   "subscribed":false
}

或者其他几个JSON。所有JSON唯一相同的字段是“event”。所有其他字段可以不同(取决于“事件”值)


所以问题是:如何将这些JSON转换为java对象(而不产生混乱的代码)?我知道的唯一方法是手动检查“event”值(如
json.startsWith(“{\n\”event\“:\”message\”)
,但我确信这样做有任何简单的决定。

UPD:如果不想通过声明POJO将json字符串转换为JAVA对象,可以将其解析为
JSONObject
(com.alibaba.fastjson.JSONObject)

如下所示声明一个
Event
类,然后将JSON字符串转换为
Event
JAVA对象

@Data
public class Event {
    private String event;
    private String context;
    private User user;
    private boolean subscribed;
    private Message message;

    @Data
    public static class User {
        private String id;
        private String name;
        private String avatar;
        private String country;
        private String language;
        private int api_version;
    }

    @Data
    public static class Message {
        private String type;
        private String text;
        private Location location;

        @Data
        public static class Location {
            private double lat;
            private double lon;
        }
    }

    public static void main(String[] args) {
        String jsonA = "{\"event\":\"conversation_started\",\"context\":\"context information\",\"user\":{\"id\":\"01234567890A=\",\"name\":\"John McClane\",\"avatar\":\"http://avatar.example.com\",\"country\":\"UK\",\"language\":\"en\",\"api_version\":1},\"subscribed\":false}";
        String jsonB = "{\"event\":\"message\",\"message\":{\"type\":\"text\",\"text\":\"a message to the service\",\"location\":{\"lat\":12.34,\"lon\":12.34}}}";

        ObjectMapper objectMapper = new ObjectMapper();
        try {
            Event eventA = objectMapper.readValue(jsonA, new TypeReference<Event>() {
            });
            System.out.println(objectMapper.writeValueAsString(eventA));

            Event eventB = objectMapper.readValue(jsonB, new TypeReference<Event>() {
            });
            System.out.println(objectMapper.writeValueAsString(eventB));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
@数据
公开课活动{
私有字符串事件;
私有字符串上下文;
私人用户;
私有布尔订阅;
私人信息;
@资料
公共静态类用户{
私有字符串id;
私有字符串名称;
私有字符串化身;
私人国家;
私有字符串语言;
私有int api_版本;
}
@资料
公共静态类消息{
私有字符串类型;
私有字符串文本;
私人位置;
@资料
公共静态类位置{
私人双lat;
私人双伦敦;
}
}
公共静态void main(字符串[]args){
字符串jsonA=“{\”事件\“:\”对话\”开始\“,\”上下文\“:\”上下文信息\“,\”用户\“:{\”id \“:\”01234567890A=\”,\“名称\“:\”约翰·麦克莱恩\“,”化身\“:\”http://avatar.example.com\“,”国家“:”英国“,”语言“:”en“,”api\U版本\“:1},\”订阅\“:false}”;
字符串jsonB=“{\'event\':\'message\',\'message\':{\'type\':\'text\',\'text\':\'a message to the service\',\'location\':{\'lat\':12.34,\'lon\':12.34}”;
ObjectMapper ObjectMapper=新的ObjectMapper();
试一试{
Event eventA=objectMapper.readValue(jsonA,new TypeReference(){
});
System.out.println(objectMapper.writeValueAsString(eventA));
eventB=objectMapper.readValue(jsonB,新类型引用(){
});
System.out.println(objectMapper.writeValueAsString(eventB));
}捕获(IOE异常){
e、 printStackTrace();
}
}
}

使用JSON对象。这是动态的,可以加载任何JSON。然后您可以一致地引用事件字段

例1

 //import java.util.ArrayList;
 //import org.bson.Document;


 Document root = Document.parse("{ \"event\" : \"conversation_started\", \"context\" : \"context information\", \"user\" : { \"id\" : \"01234567890A=\", \"name\" : \"John McClane\", \"avatar\" : \"http://avatar.example.com\", \"country\" : \"UK\", \"language\" : \"en\", \"api_version\" : 1 }, \"subscribed\" : false }");

 System.out.println(((String)root.get("event")));
例2

 //import java.util.ArrayList;
 //import org.bson.Document;


 Document root = Document.parse("{ \"event\" : \"message\", \"message\" : { \"type\" : \"text\", \"text\" : \"a message to the service\", \"location\" : { \"lat\" : 12.34, \"lon\" : 12.34 } } }");

 System.out.println(((String)root.get("event")));

我有三种方法可以做到这一点。第一种方法是按照您的建议来做——解析JSON,检查类型,然后创建对象。使用字符串解析器时要非常小心,因为您可能有或可能没有新行。相反,请执行以下操作:

ObjectMapper objectMapper = new ObjectMapper();
JsonNode jsonNode = objectMapper.readTree(eventString);
String eventType = jsonNode.get("event").asText();

if( eventType.equalsIgnoreCase("conversation_started")) {
    // create ConversationStarted object using something like:
    ConversationStarted conversationStarted = objectMapper.readValue( eventString, ConversationStarted.class );
}
if( JsonPath.read(eventString, "$.event").equals("conversation_started") ) {
    String avatar = JsonPath.read(eventString, "$.user.avatar");
    System.out.println("conversation started - avatar is " + avatar);
 }
当然,这要求所有类都有一个具体的POJO,以允许反序列化

另一种方法是做许多其他编程语言做的事情,并有一个键/值映射。有几种方法可以做到这一点。一种是使用Jackson库:

Map<String, Object> map = objectMapper.readValue(eventString, new TypeReference<Map<String,Object>>(){});

Map<String, Object> user = (Map<String, Object>) map.get("user");

System.out.println( "conversation started - avatar is " + user.get("avatar"));
最后两种方法要求您一次提取一个值,如图所示。第一种解决方案为您提供了一个完整的对象来处理。这是您对在您的环境中最有效的方法的要求

Map<String, Object> map = objectMapper.readValue(eventString, new TypeReference<Map<String,Object>>(){});

Map<String, Object> user = (Map<String, Object>) map.get("user");

System.out.println( "conversation started - avatar is " + user.get("avatar"));
if( JsonPath.read(eventString, "$.event").equals("conversation_started") ) {
    String avatar = JsonPath.read(eventString, "$.user.avatar");
    System.out.println("conversation started - avatar is " + avatar);
 }