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

Spring Boot POST请求映射报错:不支持的媒体类型问题排查

嵌套JSON请求的媒体类型不支持问题排查与解决

问题描述

我在Postman中发送如下嵌套结构的JSON请求:

{
    "title": "the",
    "type": "MCQ",
    "teacher_id": "2",
    "questions" : [{
    "content": "Who are you",
    "answers":[{
        "content": "you",
        "correct" : "true"
    }]
  }],
    "status": "OPEN"
}

尝试切换媒体类型后仍无法请求到对应接口,怀疑问题出在包含answers列表的questions嵌套结构上,收到的错误信息:

"error": "Unsupported Media Type", "trace": "org.springframework.web.HttpMediaTypeNotSupportedException: Content-Type 'application/json;charset=UTF-8'"

相关代码

Exam实体类

package com.academy.exams.entity;
import com.fasterxml.jackson.annotation.JsonManagedReference;
import jakarta.annotation.PostConstruct;
import jakarta.persistence.*;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

import java.util.List;

@Entity
@Table(name = "Exam")
public class Exam {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "exam_id")
    private Long examId;

    private String title;

    @Enumerated(EnumType.STRING)
    private ExamType type;

    @JsonManagedReference
    @OneToMany(mappedBy = "exam", cascade = CascadeType.ALL)
    private List<Question> questions;

    @Column(name = "teacher_id")
    private Long teacherId;

    private String status;

    public Long getId() {
        return examId;
    }

    public void setId(Long examId) {
        this.examId = examId;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public ExamType getType() {
        return type;
    }

    public void setType(ExamType type) {
        this.type = type;
    }

    public List<Question> getQuestions() {
        return questions;
    }

    public void setQuestions(List<Question> questions) {
        this.questions = questions;
    }

    public Long getTeacherId() {
        return teacherId;
    }

    public void setTeacherId(Long teacherId) {
        this.teacherId = teacherId;
    }

    public String getStatus() {
        return status;
    }

    public void setStatus(String status) {
        this.status = status;
    }

    @PostConstruct
    public void init() {
        System.out.println("Exam initialized");
    }
}

仓库接口

@Repository
public interface ExamRepository extends JpaRepository<Exam, Long> {}

服务层代码

public Exam CreateExam(Exam exam){
    return examRepository.save(exam);
}

控制器代码

package com.academy.exams.controller;
import com.academy.exams.entity.Exam;
import com.academy.exams.service.ExamService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping("/exams")
public class ExamController {

    @Autowired
    private ExamService examService;

    @PostMapping("/create")
    public Exam createExam(@RequestBody Exam exam){
        return examService.CreateExam(exam);
    }
}

Question实体类

package com.academy.exams.entity;
import com.academy.exams.entity.Exam;
import com.fasterxml.jackson.annotation.JsonBackReference;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import jakarta.persistence.*;
import java.util.List;

@Entity
@Table(name = "Question")
public class Question {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "question_id")
    private Long questionId;

    @Column(name = "content")
    private String content;

    @JsonBackReference
    @ManyToOne
    @JoinColumn(name = "exam_id")
    private Exam exam;

    @JsonBackReference
    @OneToMany(mappedBy = "question", cascade = CascadeType.ALL)
    private List<Answer> answers;

    public Long getId() {
        return questionId;
    }

    public void setId(Long id) {
        this.questionId = questionId;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public Exam getExam() {
        return exam;
    }

    public void setExam(Exam exam) {
        this.exam = exam;
    }

    public List<Answer> getAnswers() {
        return answers;
    }

    public void setAnswers(List<Answer> answers) {
        this.answers = answers;
    }
}

Answer实体类

package com.academy.exams.entity;

import com.fasterxml.jackson.annotation.JsonManagedReference;
import jakarta.persistence.*;

@Entity
@Table(name = "Answer")
public class Answer {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name ="answer_id")
    private Long answerId;

    private String content;

    @Column(name="correct")
    private Boolean correct;

    @JsonManagedReference
    @ManyToOne
    @JoinColumn(name = "question_id" )
    private Question question;

    public Long getId() {
        return answerId;
    }

    public void setId(Long answerId) {
        this.answerId = answerId;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public Boolean getCorrect() {
        return correct;
    }

    public void setCorrect(Boolean correct) {
        this.correct = correct;
    }
}

问题排查与解决

1. JSON字段与实体类属性不匹配

  • 请求中的teacher_id是字符串类型"2",但Exam实体类的teacherId是Long类型,序列化时会触发类型转换失败;
  • 请求中的correct是字符串"true",但Answer实体类的correct是Boolean类型,同样会导致解析失败,最终引发媒体类型不支持的异常(Spring无法解析请求体时会抛出该错误);
  • 字段名不匹配:请求中的teacher_id与实体类的teacherId不对应,Jackson默认采用驼峰映射规则。

解决:
修改请求JSON为以下格式:

{
    "title": "the",
    "type": "MCQ",
    "teacherId": 2,
    "questions" : [{
        "content": "Who are you",
        "answers":[{
            "content": "you",
            "correct" : true
        }]
    }],
    "status": "OPEN"
}

2. Jackson双向引用注解错误

Question实体类中answers字段使用@JsonBackReference,Answer实体类的question字段使用@JsonManagedReference,这会导致嵌套的answers无法被正确反序列化。正确的配置应该是:一对多关系中,一方(Question)的集合字段用@JsonManagedReference,多方(Answer)的引用字段用@JsonBackReference。

解决:
修改Question实体类的answers字段注解:

@JsonManagedReference
@OneToMany(mappedBy = "question", cascade = CascadeType.ALL)
private List<Answer> answers;

修改Answer实体类的question字段注解:

@JsonBackReference
@ManyToOne
@JoinColumn(name = "question_id" )
private Question question;

3. Postman请求配置检查

  • 确保请求方法为POST,URL正确指向/exams/create;
  • 在Headers中设置Content-Type: application/json,无需额外添加charset=UTF-8参数;
  • 选择Raw格式发送JSON,避免使用其他格式。

4. 依赖检查

确认项目的pom.xml(或build.gradle)中包含spring-boot-starter-web依赖,它默认集成了Jackson相关模块,确保未排除Jackson组件。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 07:15:55