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

使用Spring Cloud OpenFeign如何读取嵌套JSON数据?

问题描述

使用Spring Cloud OpenFeign调用接口读取嵌套结构JSON时触发反序列化错误,移除Student类中的courseList字段后能正常返回数据,但无法获取课程列表。需要解决嵌套JSON的反序列化问题,或者将返回的List<Object>解析为Student和Course实体类进行操作。

现有代码实现

Feign客户端接口

@FeignClient(name="service", url="http://localhost:80/")
public interface apiService {

    @GetMapping(value = "/student")
    @Headers(value = "Content-Type: application/json")
    List<Student> getAll();
} 

Feign接口实现类

@RestController
@RequestMapping("/apiController")
@Primary
public class apiController implements apiService{
    
    @Autowired
    private apiService proxy;
    
    @Override
    public List<Student> getAll() {
        List<Student> all = proxy.getAll();
        return all;
    }
}

MVC控制器

@Controller
public class mvcController  {
    @Autowired
    apiController apiC;

    @GetMapping("/student")
    public String getAll(Model m) {
        List<Student> student = apiC.getAll();
        System.out.println(student.get(0).getCourseList());
        return "student";
    }
}

Student实体类

@NoArgsConstructor
@Getter
@Setter
@AllArgsConstructor
public class Student {
    private int id;
    private String firstName;
    private String lastName;
    private List<Course> courseList;

    public Student(String firstName, String lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }
}

错误信息

Error while extracting response for type [java.util.List<com.example.restconsume.Entity.Student>] and content type [application/json]; nested exception is org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot deserialize value of type `com.example.restconsume.Entity.Student` from Array value (token `JsonToken.START_ARRAY`); nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize value of type `com.example.restconsume.Entity.Student` from Array value (token `JsonToken.START_ARRAY`) at [Source: (org.springframework.util.StreamUtils$NonClosingInputStream); line: 1, column: 99] (through reference chain: java.util.ArrayList[0]->com.example.restconsume.Entity.Student["courseList"]->java.util.ArrayList[0]->com.example.restconsume.Entity.Course["student"])
feign.codec.DecodeException: Error while extracting response for type [java.util.List<com.example.restconsume.Entity.Student>] and content type [application/json]; nested exception is org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot deserialize value of type `com.example.restconsume.Entity.Student` from Array value (token `JsonToken.START_ARRAY`); nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize value of type `com.example.restconsume.Entity.Student` from Array value (token `JsonToken.START_ARRAY`)

待消费的示例JSON

[
    {
        "id": 10,
        "firstName": "Jan",
        "lastName": "Cen",
        "courseList": [
            {
                "id": 10,
                "courseName": "Math",
                "student": [
                    10
                ],
                "teacher": {
                    "id": 2,
                    "firstName": "Albert",
                    "lastName": "Einstein",
                    "email": "Einstein@gmail.com",
                    "course": [
                        10
                    ]
                }
            }
        ]
    }
]

解决方案

核心问题分析

错误日志明确指向类型不匹配:JSON中Course的student字段是整数数组[10],但你的Course实体类大概率将该字段定义为Student对象类型,导致Jackson无法将数组反序列化为单个对象。同时Teacher类的course字段也是整数数组,同样存在类型不匹配问题。

步骤1:修正嵌套实体类字段类型

创建/调整Course和Teacher实体类,确保字段类型与JSON结构完全对齐:

Course实体类

@NoArgsConstructor
@Getter
@Setter
@AllArgsConstructor
public class Course {
    private int id;
    private String courseName;
    // 对应JSON中的整数数组
    private List<Integer> student;
    private Teacher teacher;
}

Teacher实体类

@NoArgsConstructor
@Getter
@Setter
@AllArgsConstructor
public class Teacher {
    private int id;
    private String firstName;
    private String lastName;
    private String email;
    // 对应JSON中的整数数组
    private List<Integer> course;
}

步骤2:验证反序列化

修正实体类后,直接通过Feign接口返回List<Student>即可正常完成反序列化,调用student.get(0).getCourseList()就能正常获取课程列表。

备选方案:手动解析List(不推荐)

若因特殊原因无法修改实体类,可将Feign接口返回类型改为List<Object>,再手动转换为实体类:

// 修改Feign接口返回类型
@GetMapping(value = "/student")
@Headers(value = "Content-Type: application/json")
List<Object> getAll();

调用处转换代码:

List<Object> studentList = apiC.getAll();
ObjectMapper objectMapper = new ObjectMapper();
List<Student> students = studentList.stream()
        .map(obj -> objectMapper.convertValue(obj, Student.class))
        .collect(Collectors.toList());

此方式繁琐且易出错,优先推荐实体类类型匹配的方案。


内容的提问来源于stack exchange,提问作者Cen Jake

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 11:15:44