java - 无法保存用户: Cannot deserialize instance of `java.util.ArrayList<>` out of START_OBJECT token at [Source: (BufferedInputStream)

标签 java json hibernate spring-boot h2

我已经厌倦了我的问题。 我有一个 JSON,我正在尝试:
1.使用Jackson将其转换为POJO,并在Spring Boot应用程序中自定义方法
2. 使用 H2 Db 和 Hibernate 保存: 下面的 JSON 不起作用。
没有“国家/地区”:一切正常。
请向我解释一下“国家/地区”是什么意思以及如何将其保存到数据库中?
另外]之后的最后一个“Date”:“2020-04-05T06:37:00Z”意味着什么,我也应该将其保存到数据库吗?

JSON:

 {
      "Countries": [
        {
          "Country": "ALA Aland Islands",
          "CountryCode": "AX",
          "Slug": "ala-aland-islands",
          "NewConfirmed": 0,
          "TotalConfirmed": 0,
          "NewDeaths": 0,
          "TotalDeaths": 0,
          "NewRecovered": 0,
          "TotalRecovered": 0,
          "Date": "2020-04-05T06:37:00Z"
        },
        {
          "Country": "Afghanistan",
          "CountryCode": "AF",
          "Slug": "afghanistan",
          "NewConfirmed": 18,
          "TotalConfirmed": 299,
          "NewDeaths": 1,
          "TotalDeaths": 7,
          "NewRecovered": 0,
          "TotalRecovered": 10,
          "Date": "2020-04-05T06:37:00Z"
        }
      ],
"Date": "2020-04-05T06:37:00Z"
    }

我的POJO:

@Data
@AllArgsConstructor
@Entity
public class Country {

    @JsonProperty("Countries")
    ArrayList <Country> countries = new ArrayList<>();  

    @Id
    @GeneratedValue
    @Column(name = "id")
    Long id;  

    @JsonProperty("Country")
    private String country;  

    @JsonProperty("CountryCode")
    private String countryside;  

    @JsonProperty("Slug")
    private String slug;  

    @JsonProperty("NewConfirmed")
    private Integer newConfirmed;  

    @JsonProperty("TotalConfirmed")
    private Integer totalConfirmed;  

    @JsonProperty("NewDeaths")
    private Integer newDeaths;  

    @JsonProperty("TotalDeaths")
    private Integer totalDeaths;  

    @JsonProperty("NewRecovered")
    private Integer newRecovered;  

    @JsonProperty("TotalRecovered")
    private Integer totalRecovered;  

    @JsonProperty("Date")
    private String date;

    public Country() {
    }
}

错误:

2020-05-10 01:07:52.255  INFO 27321 --- [  restartedMain] com.vicchern.Covid19JsonToDb             : Started Covid19JsonToDb in 3.786 seconds (JVM running for 4.595)
**Unable to save users: Cannot deserialize instance of `java.util.ArrayList<com.vicchern.domain.Country>` out of START_OBJECT token**
 at [Source: (BufferedInputStream); line: 2, column: 1]
2020-05-10 01:07:52.632  INFO 27321 --- [on(2)-127.0.0.1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
2020-05-10 01:07:52.633  INFO 27321 --- [on(2)-127.0.0.1] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
2020-05-10 01:07:52.642  INFO 27321 --- [on(2)-127.0.0.1] o.s.web.servlet.DispatcherServlet        : Completed initialization in 9 ms

我想用 Jackson 将其转换为 POJO,在 Spring Boot 应用程序中使用此自定义方法并保存到数据库:

public static void main(String[] args) {
        SpringApplication.run(Covid19JsonToDb.class, args);
    }

    @Bean
    CommandLineRunner runner(UserService userService){
        return args -> {
            // read JSON and load json
            ObjectMapper mapper = new ObjectMapper();
            TypeReference<List<Country>> typeReference = new TypeReference<>(){};
            InputStream inputStream = TypeReference.class.getResourceAsStream("/json/countries.json");
            try {
                List<Country> users = mapper.readValue(inputStream,typeReference);
                userService.save(users);
                System.out.println("Users Saved!");
            } catch (IOException e){
                System.out.println("Unable to save users: " + e.getMessage());
            }
        };
    }

这是我的服务:

@Service
public class CountryService {

    private CountryRepository countryRepository;

    public CountryService(CountryRepository countryRepository) {
        this.countryRepository = countryRepository;
    }

    public Iterable<Country> list() {
        return countryRepository.findAll();
    }

    public Country save(Country country) {
        return countryRepository.save(country);
    }

    public void save(List<Country> countries) {
        countryRepository.saveAll(countries);
    }
}

Repository 实现 JpaRepository(无自定义输入)

我已经在这里和互联网上阅读了很多内容。我看过关于列表“包装器”的答案。但该如何处理,请大家帮忙指点一下。

最佳答案

我发现您上面发布的代码有两个问题。

1) 您需要一个 Country 列表,但您的 JSON 实际上是 Country 的对象。

TypeReference<List<Country>> typeReference = new TypeReference<>(){}; 

应该改为,

TypeReference<Country> typeReference = new TypeReference<>(){};

2) 您只有一个代表国家/地区及其信息的类,但实际上您需要两个不同的类,因为 Countries 不是国家/地区信息对象的一部分(您是通过将其包含在同一个类中来期望它成为它的一部分)。

分割的类应该看起来像这样,

@Data
@AllArgsConstructor
@Entity
public class Country {
    @JsonProperty("Countries")
    List<CountryMetadata> countries = new ArrayList<>();

    public Country() {
       // ...
    }
}

@Data
@AllArgsConstructor
@Entity
public class CountryMetadata {
    @Id
    @GeneratedValue
    @Column(name = "id")
    Long id;  

    @JsonProperty("Country")
    private String country;  

    @JsonProperty("CountryCode")
    private String countryside;  

    @JsonProperty("Slug")
    private String slug;  

    @JsonProperty("NewConfirmed")
    private Integer newConfirmed;  

    @JsonProperty("TotalConfirmed")
    private Integer totalConfirmed;  

    @JsonProperty("NewDeaths")
    private Integer newDeaths;  

    @JsonProperty("TotalDeaths")
    private Integer totalDeaths;  

    @JsonProperty("NewRecovered")
    private Integer newRecovered;  

    @JsonProperty("TotalRecovered")
    private Integer totalRecovered;  

    @JsonProperty("Date")
    private String date;

    public CountryMetadata() {
       // ...
    }
}

关于java - 无法保存用户: Cannot deserialize instance of `java.util.ArrayList<>` out of START_OBJECT token at [Source: (BufferedInputStream),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61704917/

相关文章:

java - 是否可以检测来自另一个项目的实体?

java - 收集特定时间段的android传感器并计算平均值

java - 如何使用 Apache Commons 库从 CMD 运行 Java

java - 在 Java 异常中返回导致该异常的行的内容

json - Haskell JSON 问题

java - 如何在 Spring/Hibernate 事务中包装 Wicket 页面渲染?

java - 将变量从一个jsp页面传递到另一个页面?

ios - 如何使用 Objective-C 初始化嵌套的 Node.js 模式

java - 如何在 Eclipse 中导入 javax.json

java - Hibernate Envers 是如何工作的?