You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot调用外部API存入JPA数据库返回空值问题

问题:Spring Boot调用外部API后保存实体到MySQL,除ID外所有字段为null

在Spring Boot应用中调用OpenLibrary的API获取书籍数据,尝试将响应保存到MySQL数据库,但最终保存的Book实体除自动生成的id外,所有字段均为null。

实体类代码

public class Book {
    @Id
    @GeneratedValue(
            strategy = GenerationType.AUTO
    )
    private Long id;
    private String bookName;
    private LocalDate publishYear;
    private Integer stock;
    private String ISBN;
    private String bib_key;
    private String info_url;
    private String preview;
    private String preview_url;
    private String thumbnail_url;
}

原服务层代码

public Book getExternal(String isbn) {
    String uri = "https://openlibrary.org/api/books?bibkeys=ISBN:" + isbn + "&format=json";
    String ISBNCode = "ISBN:" + isbn;
    RestTemplate restTemplate = new RestTemplate();
    ResponseEntity<String> externalBook = restTemplate.getForEntity(uri, String.class);
    JSONObject jsonObject = new JSONObject(externalBook);
    Book entity = new Book();
    jsonObject.put(ISBNCode, entity);
    bookRepository.saveAndFlush(entity);
    return entity;
}

API响应示例

{
"ISBN:1931498717": {
"bib_key": "ISBN:1931498717",
"info_url": "https://openlibrary.org/books/OL34424821M/Don't_Think_of_an_Elephant!",
"preview": "borrow",
"preview_url": "https://archive.org/details/dontthinkofeleph0000lako",
"thumbnail_url": "https://covers.openlibrary.org/b/id/12039210-S.jpg"
}
}

保存后的实体示例

{
    "id": 42,
    "bookName": null,
    "publishYear": null,
    "stock": null,
    "bib_key": null,
    "info_url": null,
    "preview": null,
    "preview_url": null,
    "thumbnail_url": null,
    "kind": null,
    "isbn": null
}

解决方案

1. 修复核心逻辑错误

原代码中jsonObject.put(ISBNCode, entity)是将空的Book对象存入JSON,完全搞反了数据流向——应该是从JSON响应中提取数据赋值给Book实体,而非反过来。

2. 修正RestTemplate响应处理

直接将ResponseEntity传入JSONObject构造器是错误的,需要先获取响应体内容:externalBook.getBody()。

3. 补充实体类Getter/Setter方法

JPA和JSON数据映射都需要实体类具备对应的Getter/Setter方法,否则无法完成字段赋值。可以手动编写,也可以用Lombok的@Data注解自动生成:

import lombok.Data;
import javax.persistence.*;
import java.time.LocalDate;

@Data
@Entity
public class Book {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    private String bookName;
    private LocalDate publishYear;
    private Integer stock;
    private String ISBN;
    private String bib_key;
    private String info_url;
    private String preview;
    private String preview_url;
    private String thumbnail_url;
}

4. 正确映射API响应数据

API返回的是外层以ISBN为key的嵌套结构,需要先提取内层的书籍对象,再逐个字段赋值。推荐使用Jackson的ObjectMapper来处理JSON解析:

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;
import java.io.IOException;

public Book getExternal(String isbn) {
    String uri = "https://openlibrary.org/api/books?bibkeys=ISBN:" + isbn + "&format=json";
    String ISBNCode = "ISBN:" + isbn;
    RestTemplate restTemplate = new RestTemplate();
    ResponseEntity<String> response = restTemplate.getForEntity(uri, String.class);
    
    ObjectMapper objectMapper = new ObjectMapper();
    Book book = new Book();
    book.setISBN(isbn);
    book.setStock(0); // 初始化库存字段
    
    try {
        JsonNode rootNode = objectMapper.readTree(response.getBody());
        JsonNode bookNode = rootNode.get(ISBNCode);
        
        if (bookNode != null) {
            book.setBib_key(bookNode.get("bib_key").asText());
            book.setInfo_url(bookNode.get("info_url").asText());
            book.setPreview(bookNode.get("preview").asText());
            book.setPreview_url(bookNode.get("preview_url").asText());
            book.setThumbnail_url(bookNode.get("thumbnail_url").asText());
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
    
    bookRepository.saveAndFlush(book);
    return book;
}

注意事项

当前调用的OpenLibrary API返回结果中不包含bookName和publishYear字段,如果需要这两个数据,需要额外调用书籍详情接口(比如info_url指向的页面对应的API)来获取。


内容的提问来源于stack exchange,提问作者Levent Kaya

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 13:01:55