2

我在代码中使用 jsonschema2pojo 时遇到问题。所以,我使用 jsonschema2pojo 生成器(http://www.jsonschema2pojo.org/)从这个 URL 生成 POJO:http ://store.steampowered.com/api/appdetails/?appids=10

最后,我在一个包“模型”中创建了所有这些类。然后在我尝试使用它从链接中读取 json 但我收到异常:

Exception in thread "main" java.lang.NullPointerException
    at controller.View.main(View.java:26)

我不明白为什么。这是代码我该怎么做:

public class View {
private static String urlStr = "http://store.steampowered.com/api/appdetails/?appids=10";

public static void main(String[] args) {

    ObjectMapper objectMapper = new ObjectMapper();

    try {
        Game game = objectMapper.readValue(new URL(urlStr), Game.class);

        System.out.println(game.getData().getName());
    } catch (MalformedURLException e) {
        e.printStackTrace();
    } catch (JsonParseException e) {
        e.printStackTrace();
    } catch (JsonMappingException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }


}

}

Game.class 是我在生成器中设置为“类名”的 finall 类。

怎么了?如何从此链接获取所有这些数据?

在 Maven 中,我像这样配置它:

<plugin>
            <groupId>org.jsonschema2pojo</groupId>
            <artifactId>jsonschema2pojo-maven-plugin</artifactId>
            <version>0.4.18</version>
            <configuration>
                <sourceType>jsonschema</sourceType>
                <outputEncoding>${project.build.sourceEncoding}</outputEncoding>
                <outputDirectory>${project.build.directory}/generated-sources</outputDirectory>
                <annotationStyle>jackson2</annotationStyle>
                <generateBuilders>true</generateBuilders>
                <initializeCollections>true</initializeCollections>
            </configuration>
            <executions>
                <execution>
                    <id>generate-game</id>
                    <goals>
                        <goal>generate</goal>
                    </goals>
                    <configuration>
                        <targetPackage>model.game</targetPackage>
                        <sourceDirectory>${basedir}/src/main/resources/schema/game</sourceDirectory>
                    </configuration>
                </execution>
            </executions>
        </plugin>

正如我所说,所有类都在 src/main/java 和包“模型”中,我的模式在文件“游戏”中的 sr/main/resources/schema/

我的架构看起来像:

{
  "type": "object",
  "required":false,
  "javaType":"model.Game",
  "properties": {
    "10": {
      "id": "10",
      "type": "object",
      "properties": {
        "success": {
          "id": "success",
          "type": "boolean"
        },
        "data": {
          "id": "data",
          "type": "object",
          "properties": {
            "type": {
              "id": "type",
              "type": "string"
            },
            "name": {
              "id": "name",
              "type": "string"
            },
            "steam_appid": {
              "id": "steam_appid",
              "type": "integer"
            },
            "required_age": {
              "id": "required_age",
              "type": "integer"
            },
            "is_free": {
              "id": "is_free",
              "type": "boolean"
            },
            "detailed_description": {
              "id": "detailed_description",
              "type": "string"
            },
            "about_the_game": {
              "id": "about_the_game",
              "type": "string"
            },
            "supported_languages": {
              "id": "supported_languages",
              "type": "string"
            },
            "header_image": {
              "id": "header_image",
              "type": "string"
            },
            "website": {
              "id": "website",
              "type": "null"
            },
            "pc_requirements": {
              "id": "pc_requirements",
              "type": "object",
              "properties": {
                "minimum": {
                  "id": "minimum",
                  "type": "string"
                }
              }
            },
            "mac_requirements": {
              "id": "mac_requirements",
              "type": "object",
              "properties": {
                "minimum": {
                  "id": "minimum",
                  "type": "string"
                }
              }
            },
            "linux_requirements": {
              "id": "linux_requirements",
              "type": "object",
              "properties": {
                "minimum": {
                  "id": "minimum",
                  "type": "string"
                }
              }
            },
            "developers": {
              "id": "developers",
              "type": "array",
              "items": {
                "id": "0",
                "type": "string"
              }
            },
            "publishers": {
              "id": "publishers",
              "type": "array",
              "items": {
                "id": "0",
                "type": "string"
              }
            },
            "price_overview": {
              "id": "price_overview",
              "type": "object",
              "properties": {
                "currency": {
                  "id": "currency",
                  "type": "string"
                },
                "initial": {
                  "id": "initial",
                  "type": "integer"
                },
                "final": {
                  "id": "final",
                  "type": "integer"
                },
                "discount_percent": {
                  "id": "discount_percent",
                  "type": "integer"
                }
              }
            },
            "packages": {
              "id": "packages",
              "type": "array",
              "items": [
                {
                  "id": "0",
                  "type": "string"
                },
                {
                  "id": "1",
                  "type": "integer"
                },
                {
                  "id": "2",
                  "type": "integer"
                },
                {
                  "id": "3",
                  "type": "integer"
                }
              ]
            },
            "package_groups": {
              "id": "package_groups",
              "type": "array",
              "items": {
                "id": "0",
                "type": "object",
                "properties": {
                  "name": {
                    "id": "name",
                    "type": "string"
                  },
                  "title": {
                    "id": "title",
                    "type": "string"
                  },
                  "description": {
                    "id": "description",
                    "type": "string"
                  },
                  "selection_text": {
                    "id": "selection_text",
                    "type": "string"
                  },
                  "save_text": {
                    "id": "save_text",
                    "type": "string"
                  },
                  "display_type": {
                    "id": "display_type",
                    "type": "integer"
                  },
                  "is_recurring_subscription": {
                    "id": "is_recurring_subscription",
                    "type": "string"
                  },
                  "subs": {
                    "id": "subs",
                    "type": "array",
                    "items": [
                      {
                        "id": "0",
                        "type": "object",
                        "properties": {
                          "packageid": {
                            "id": "packageid",
                            "type": "string"
                          },
                          "percent_savings_text": {
                            "id": "percent_savings_text",
                            "type": "string"
                          },
                          "percent_savings": {
                            "id": "percent_savings",
                            "type": "integer"
                          },
                          "option_text": {
                            "id": "option_text",
                            "type": "string"
                          },
                          "option_description": {
                            "id": "option_description",
                            "type": "string"
                          },
                          "can_get_free_license": {
                            "id": "can_get_free_license",
                            "type": "string"
                          },
                          "is_free_license": {
                            "id": "is_free_license",
                            "type": "boolean"
                          },
                          "price_in_cents_with_discount": {
                            "id": "price_in_cents_with_discount",
                            "type": "integer"
                          }
                        }
                      },
                      {
                        "id": "1",
                        "type": "object",
                        "properties": {
                          "packageid": {
                            "id": "packageid",
                            "type": "integer"
                          },
                          "percent_savings_text": {
                            "id": "percent_savings_text",
                            "type": "string"
                          },
                          "percent_savings": {
                            "id": "percent_savings",
                            "type": "integer"
                          },
                          "option_text": {
                            "id": "option_text",
                            "type": "string"
                          },
                          "option_description": {
                            "id": "option_description",
                            "type": "string"
                          },
                          "can_get_free_license": {
                            "id": "can_get_free_license",
                            "type": "string"
                          },
                          "is_free_license": {
                            "id": "is_free_license",
                            "type": "boolean"
                          },
                          "price_in_cents_with_discount": {
                            "id": "price_in_cents_with_discount",
                            "type": "integer"
                          }
                        }
                      },
                      {
                        "id": "2",
                        "type": "object",
                        "properties": {
                          "packageid": {
                            "id": "packageid",
                            "type": "integer"
                          },
                          "percent_savings_text": {
                            "id": "percent_savings_text",
                            "type": "string"
                          },
                          "percent_savings": {
                            "id": "percent_savings",
                            "type": "integer"
                          },
                          "option_text": {
                            "id": "option_text",
                            "type": "string"
                          },
                          "option_description": {
                            "id": "option_description",
                            "type": "string"
                          },
                          "can_get_free_license": {
                            "id": "can_get_free_license",
                            "type": "string"
                          },
                          "is_free_license": {
                            "id": "is_free_license",
                            "type": "boolean"
                          },
                          "price_in_cents_with_discount": {
                            "id": "price_in_cents_with_discount",
                            "type": "integer"
                          }
                        }
                      },
                      {
                        "id": "3",
                        "type": "object",
                        "properties": {
                          "packageid": {
                            "id": "packageid",
                            "type": "integer"
                          },
                          "percent_savings_text": {
                            "id": "percent_savings_text",
                            "type": "string"
                          },
                          "percent_savings": {
                            "id": "percent_savings",
                            "type": "integer"
                          },
                          "option_text": {
                            "id": "option_text",
                            "type": "string"
                          },
                          "option_description": {
                            "id": "option_description",
                            "type": "string"
                          },
                          "can_get_free_license": {
                            "id": "can_get_free_license",
                            "type": "string"
                          },
                          "is_free_license": {
                            "id": "is_free_license",
                            "type": "boolean"
                          },
                          "price_in_cents_with_discount": {
                            "id": "price_in_cents_with_discount",
                            "type": "integer"
                          }
                        }
                      }
                    ]
                  }
                }
              }
            },
            "platforms": {
              "id": "platforms",
              "type": "object",
              "properties": {
                "windows": {
                  "id": "windows",
                  "type": "boolean"
                },
                "mac": {
                  "id": "mac",
                  "type": "boolean"
                },
                "linux": {
                  "id": "linux",
                  "type": "boolean"
                }
              }
            },
            "metacritic": {
              "id": "metacritic",
              "type": "object",
              "properties": {
                "score": {
                  "id": "score",
                  "type": "integer"
                },
                "url": {
                  "id": "url",
                  "type": "string"
                }
              }
            },
            "categories": {
              "id": "categories",
              "type": "array",
              "items": [
                {
                  "id": "0",
                  "type": "object",
                  "properties": {
                    "id": {
                      "id": "id",
                      "type": "integer"
                    },
                    "description": {
                      "id": "description",
                      "type": "string"
                    }
                  }
                },
                {
                  "id": "1",
                  "type": "object",
                  "properties": {
                    "id": {
                      "id": "id",
                      "type": "integer"
                    },
                    "description": {
                      "id": "description",
                      "type": "string"
                    }
                  }
                }
              ]
            },
            "genres": {
              "id": "genres",
              "type": "array",
              "items": {
                "id": "0",
                "type": "object",
                "properties": {
                  "id": {
                    "id": "id",
                    "type": "string"
                  },
                  "description": {
                    "id": "description",
                    "type": "string"
                  }
                }
              }
            },
            "screenshots": {
              "id": "screenshots",
              "type": "array",
              "items": [
                {
                  "id": "0",
                  "type": "object",
                  "properties": {
                    "id": {
                      "id": "id",
                      "type": "integer"
                    },
                    "path_thumbnail": {
                      "id": "path_thumbnail",
                      "type": "string"
                    },
                    "path_full": {
                      "id": "path_full",
                      "type": "string"
                    }
                  }
                },
                {
                  "id": "1",
                  "type": "object",
                  "properties": {
                    "id": {
                      "id": "id",
                      "type": "integer"
                    },
                    "path_thumbnail": {
                      "id": "path_thumbnail",
                      "type": "string"
                    },
                    "path_full": {
                      "id": "path_full",
                      "type": "string"
                    }
                  }
                },
                {
                  "id": "2",
                  "type": "object",
                  "properties": {
                    "id": {
                      "id": "id",
                      "type": "integer"
                    },
                    "path_thumbnail": {
                      "id": "path_thumbnail",
                      "type": "string"
                    },
                    "path_full": {
                      "id": "path_full",
                      "type": "string"
                    }
                  }
                },
                {
                  "id": "3",
                  "type": "object",
                  "properties": {
                    "id": {
                      "id": "id",
                      "type": "integer"
                    },
                    "path_thumbnail": {
                      "id": "path_thumbnail",
                      "type": "string"
                    },
                    "path_full": {
                      "id": "path_full",
                      "type": "string"
                    }
                  }
                },
                {
                  "id": "4",
                  "type": "object",
                  "properties": {
                    "id": {
                      "id": "id",
                      "type": "integer"
                    },
                    "path_thumbnail": {
                      "id": "path_thumbnail",
                      "type": "string"
                    },
                    "path_full": {
                      "id": "path_full",
                      "type": "string"
                    }
                  }
                },
                {
                  "id": "5",
                  "type": "object",
                  "properties": {
                    "id": {
                      "id": "id",
                      "type": "integer"
                    },
                    "path_thumbnail": {
                      "id": "path_thumbnail",
                      "type": "string"
                    },
                    "path_full": {
                      "id": "path_full",
                      "type": "string"
                    }
                  }
                },
                {
                  "id": "6",
                  "type": "object",
                  "properties": {
                    "id": {
                      "id": "id",
                      "type": "integer"
                    },
                    "path_thumbnail": {
                      "id": "path_thumbnail",
                      "type": "string"
                    },
                    "path_full": {
                      "id": "path_full",
                      "type": "string"
                    }
                  }
                },
                {
                  "id": "7",
                  "type": "object",
                  "properties": {
                    "id": {
                      "id": "id",
                      "type": "integer"
                    },
                    "path_thumbnail": {
                      "id": "path_thumbnail",
                      "type": "string"
                    },
                    "path_full": {
                      "id": "path_full",
                      "type": "string"
                    }
                  }
                },
                {
                  "id": "8",
                  "type": "object",
                  "properties": {
                    "id": {
                      "id": "id",
                      "type": "integer"
                    },
                    "path_thumbnail": {
                      "id": "path_thumbnail",
                      "type": "string"
                    },
                    "path_full": {
                      "id": "path_full",
                      "type": "string"
                    }
                  }
                },
                {
                  "id": "9",
                  "type": "object",
                  "properties": {
                    "id": {
                      "id": "id",
                      "type": "integer"
                    },
                    "path_thumbnail": {
                      "id": "path_thumbnail",
                      "type": "string"
                    },
                    "path_full": {
                      "id": "path_full",
                      "type": "string"
                    }
                  }
                },
                {
                  "id": "10",
                  "type": "object",
                  "properties": {
                    "id": {
                      "id": "id",
                      "type": "integer"
                    },
                    "path_thumbnail": {
                      "id": "path_thumbnail",
                      "type": "string"
                    },
                    "path_full": {
                      "id": "path_full",
                      "type": "string"
                    }
                  }
                },
                {
                  "id": "11",
                  "type": "object",
                  "properties": {
                    "id": {
                      "id": "id",
                      "type": "integer"
                    },
                    "path_thumbnail": {
                      "id": "path_thumbnail",
                      "type": "string"
                    },
                    "path_full": {
                      "id": "path_full",
                      "type": "string"
                    }
                  }
                },
                {
                  "id": "12",
                  "type": "object",
                  "properties": {
                    "id": {
                      "id": "id",
                      "type": "integer"
                    },
                    "path_thumbnail": {
                      "id": "path_thumbnail",
                      "type": "string"
                    },
                    "path_full": {
                      "id": "path_full",
                      "type": "string"
                    }
                  }
                }
              ]
            },
            "recommendations": {
              "id": "recommendations",
              "type": "object",
              "properties": {
                "total": {
                  "id": "total",
                  "type": "integer"
                }
              }
            },
            "achievements": {
              "id": "achievements",
              "type": "object",
              "properties": {
                "total": {
                  "id": "total",
                  "type": "integer"
                }
              }
            },
            "release_date": {
              "id": "release_date",
              "type": "object",
              "properties": {
                "coming_soon": {
                  "id": "coming_soon",
                  "type": "boolean"
                },
                "date": {
                  "id": "date",
                  "type": "string"
                }
              }
            },
            "support_info": {
              "id": "support_info",
              "type": "object",
              "properties": {
                "url": {
                  "id": "url",
                  "type": "string"
                },
                "email": {
                  "id": "email",
                  "type": "string"
                }
              }
            },
            "background": {
              "id": "background",
              "type": "string"
            }
          }
        }
      },
      "required": [
        "success",
        "data",
        "id",
        "path_thumbnail",
        "path_full"
      ]
    }
  },
  "required": [
    "10"
  ]
}

有了这个配置,我可以使用这一行而不是在 System.out.println 之前读取所有数据:

System.out.println( objectMapper.writeValueAsString( game ) );

现在我可以看到完整的 json 字符串,但是如何使用 'game.getData().getName()' 等读取它?

4

2 回答 2

0

与其尝试使用 对包含 id 的对象进行建模,不如properties使用additionalProperties。假设顶级类型包含多个游戏,您可以尝试替换

{
  "type": "object",
  "required":false,
  "javaType":"model.Game",
  "properties": {
    "10": {
      "id": "10",
      "type": "object",
      ...
    }
  }
}

有类似的东西

{
  "type": "object",
  "required":false,
  "javaType":"model.Games",
  "additionalProperties": {
      "id": "game",
      "type": "object",
      "javaType": "model.Game"
      ...
  }
}

这应该model.Games使用类似的方法创建一个类型public Map<String, Game> getAdditionalProperties()

于 2016-01-11T19:28:11.797 回答
0

您提供的 JSON 模式将“10”定义为包含其他所有内容的顶级属性。

{
  "type": "object",
  "required":false,
  "javaType":"model.Game",
  "properties": {
    "10": {
      "id": "10",
      "type": "object",
      "properties": {
        "success": {
          "id": "success",
          "type": "boolean"
        },
        "data": {
          "id": "data",
          "type": "object",
          "properties": {
            "type": {
              "id": "type",
              "type": "string"
            },
            "name": {
              "id": "name",
              "type": "string"
            },
...

jsonschema2pojo 读取该模式并生成一个命名_10为模型一部分的类。您可以在生成源目录的 _10.java 中找到它。

@JsonInclude(JsonInclude.Include.NON_NULL)
@Generated("org.jsonschema2pojo")
@JsonPropertyOrder({
    "success",
    "data"
})
public class _10 {

我不知道这是否是架构中的故意。如果是故意的,那么您需要像这样访问名称。

System.out.println(game.get10().getData().getName());

进行更改后,我能够使其正常工作。

编辑:看起来这些 JSON 消息应该有一个变量 ID 作为包含其他所有内容的顶级键,所以我们需要稍微不同地处理这个问题。我们可以概括模式,使其不特定于特定 ID,然后我们可以使用两步过程来解析消息。首先,我们将使用 [ ObjectMapper#readValue]( https://fasterxml.github.io/jackson-databind/javadoc/2.5/com/fasterxml/jackson/databind/ObjectMapper.html#readValue(java.net.URL , com.fasterxml .jackson.core.type.TypeReference)) 将整个消息解析为Map<String, Object>. 我们期望顶级映射将包含单个元素,对应于我们请求的文档的 ID,其值将是包含我们感兴趣的值的子映射。然后我们将传递该子映射通过 [ ObjectMapper#convertValue](https://fasterxml.github.io/jackson-databind/javadoc/2.5/com/fasterxml/jackson/databind/ObjectMapper.html#convertValue(java.lang.Object , java.lang.Class)) 获取Game对象我们想要。

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>cnauroth</groupId>
    <artifactId>test-json</artifactId>
    <packaging>jar</packaging>
    <version>0.0.1-SNAPSHOT</version>
    <name>Test JSON</name>
    <description>Test JSON</description>
    <build>
        <plugins>            
            <plugin>
                <groupId>org.jsonschema2pojo</groupId>
                <artifactId>jsonschema2pojo-maven-plugin</artifactId>
                <version>0.4.18</version>
                <configuration>
                    <sourceType>jsonschema</sourceType>
                    <outputEncoding>${project.build.sourceEncoding}</outputEncoding>
                    <outputDirectory>${project.build.directory}/generated-sources/java</outputDirectory>
                    <annotationStyle>jackson2</annotationStyle>
                    <generateBuilders>true</generateBuilders>
                    <initializeCollections>true</initializeCollections>
                </configuration>
                <executions>
                    <execution>
                        <id>generate-game</id>
                        <goals>
                            <goal>generate</goal>
                        </goals>
                        <configuration>
                            <targetPackage>model.game</targetPackage>
                            <sourceDirectory>${basedir}/src/main/resources/schema/game</sourceDirectory>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <artifactId>maven-assembly-plugin</artifactId>
                <configuration>
                    <archive>
                        <manifest>
                            <addDefaultImplementationEntries>true</addDefaultImplementationEntries>
                            <mainClass>View</mainClass>
                        </manifest>
                    </archive>
                    <descriptorRefs>
                        <descriptorRef>jar-with-dependencies</descriptorRef>
                    </descriptorRefs>
                    <finalName>${project.artifactId}</finalName>
                    <appendAssemblyId>false</appendAssemblyId>
                </configuration>
                <executions>
                    <execution>
                        <id>make-assembly</id>
                        <phase>package</phase>
                        <goals>
                            <goal>single</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
    <dependencies>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.5.0</version>
        </dependency>
        <dependency>
            <groupId>commons-lang</groupId>
            <artifactId>commons-lang</artifactId>
            <version>2.6</version>
        </dependency>
    </dependencies>
</project>

游戏

JSON 模式文件太大而无法粘贴,因此这里有一个指向gist的链接。

查看.java

import java.net.URI;
import java.util.Map;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;

import model.Game;

public class View {

    public static void main(String[] args) throws Exception {
        String id = args[0];
        URI uri = new URI("http", "store.steampowered.com", "/api/appdetails",
                "appids=" + id, null);
        ObjectMapper objectMapper = new ObjectMapper();
        Map<String, Object> obj = objectMapper.readValue(uri.toURL(),
                new TypeReference<Map<String, Object>>(){});
        Game game = objectMapper.convertValue(obj.get(id), Game.class);
        System.out.println(game.getData().getName());
    }
}

演示

> mvn clean package

> java -jar target/test-json.jar 10
Counter-Strike

> java -jar target/test-json.jar 219
Half-Life 2: Demo

此外,我需要对架构进行另一项更改。我删除了该linux_requirements属性。这是因为查看文档 10 与文档 219,前者是一个对象,后者是一个数组。对于文档 219,解析器不知道如何理解数组,因为我们期待的是一个对象。从 API 返回的数据像这样不一致是很奇怪的。您可能需要对架构进行更多修改,以使其完全适用于从该 API 返回的所有可能的 JSON 文档。

我已将所有代码放入GitHub 存储库。您可以获取该代码,构建它并运行它以查看它是否正常工作。然后,您可以根据自己的需要进一步调整它。

于 2015-12-31T00:21:19.613 回答