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

SpringBoot开发课程加购接口时Swagger显示字段不符求助

问题排查:Swagger显示非预期请求体字段(加入购物车功能)

我在实现课程加入购物车功能时,Swagger里显示的请求体不是预期的字段,而是:

{
  "additionalProp1": "string",
  "additionalProp2": "string",
  "additionalProp3": "string"
}

以下是相关代码,帮忙排查问题:

CartController

@RestController
public class AddToCartController {

    @Autowired
    CartService cartService;

    @PostMapping("/addToCart")
    public Cart addCartwithCourse(@RequestBody HashMap<String,String> addCartRequest)
    {
        try {
           // String keys[] = {"courseId","userId","qty","price"};

            long courseId = Long.parseLong(addCartRequest.get("courseId"));
            long userId =  Long.parseLong(addCartRequest.get("userId"));
            int qty =  Integer.parseInt(addCartRequest.get("qty"));
            double price = Double.parseDouble(addCartRequest.get("price"));
            Cart obj = cartService.addCartbyUserIdAndCourseId(courseId,userId,qty,price);
            return obj;
        }
        catch (Exception e) {
            e.printStackTrace();
            return null;
        }

    }

}

Cart Model

package com.hashedin.hu22.entities;

import org.springframework.data.annotation.CreatedDate;

import javax.persistence.*;
import java.time.Instant;

@Entity
public class Cart {

    @Id
    long id;
    int qty;
    double price;
    Long user_id;

    @CreatedDate
    private Instant createdDate;

    String CourseName;


    @OneToOne(cascade = CascadeType.ALL)
    @JoinColumn(name="cr_fid", referencedColumnName = "id")
    Course course;

    public long getId() {
        return id;
    }

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

    public int getQty() {
        return qty;
    }

    public void setQty(int qty) {
        this.qty = qty;
    }

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }

    public Long getUser_id() {
        return user_id;
    }

    public void setUser_id(Long user_id) {
        this.user_id = user_id;
    }

    public Instant getCreatedDate() {
        return createdDate;
    }

    public void setCreatedDate(Instant createdDate) {
        this.createdDate = createdDate;
    }

    public String getCourseName() {
        return CourseName;
    }

    public void setCourseName(String courseName) {
        CourseName = courseName;
    }

    public Course getCourse() {
        return course;
    }

    public void setCourse(Course course) {
        this.course = course;
    }

}

AddToCartRepo

public interface AddToCartRepo extends JpaRepository<Cart, Long> {
    @Query("Select addCart  FROM Cart addCart WHERE addCart.course.id= :course_id and addCart.user_id=:user_id")
    Optional<Cart> getCartByProductIdAnduserId(@Param("user_id")Long user_id, @Param("course_id")Long course_id);

    @Query("Select addCart  FROM Cart addCart WHERE addCart.user_id=:user_id")
    List<Cart> getCartByuserId(@Param("user_id")Long user_id);

}

CartService

@Service
public class CartServiceImpl implements CartService {

    @Autowired
    AddToCartRepo addToCartRepo;
    @Autowired
    CourseSerivce courseSerivce;

    @Override
    public Cart addCartbyUserIdAndCourseId(long courseId, long userId, int qty, double price) throws Exception
    {
        try {
                
            if (addToCartRepo.getCartByProductIdAnduserId(userId, courseId).isPresent()) {
                throw new Exception("Product is Already Exist");
            }

            Cart obj = new Cart();
            obj.setQty(qty);
            obj.setUser_id(userId);
            Course course = courseSerivce.getCourseById(courseId);
            obj.setCourse(course);
            obj.setPrice(price);

            return addToCartRepo.save(obj);
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
        return null;
    }


    @Override
    public List<Cart> getCartByUserId(long userId){
        return addToCartRepo.getCartByuserId(userId);
    }
}

问题根源

你在Controller的addCartwithCourse方法里用了HashMap<String,String>作为@RequestBody的参数类型。Swagger(以及Spring Doc/OpenAPI)无法识别HashMap的具体键值结构,只能默认显示通用的"additionalProp"占位符,这就是你看到的非预期内容。同时,手动解析HashMap的参数还容易出现类型转换错误、空指针问题,代码可读性也差。

修复步骤

1. 创建专用的请求DTO类

代替HashMap,定义一个明确的请求数据传输对象(DTO),让Swagger能识别具体字段:

import javax.validation.constraints.NotNull;

public class AddCartRequestDTO {
    @NotNull(message = "课程ID不能为空")
    private Long courseId;
    
    @NotNull(message = "用户ID不能为空")
    private Long userId;
    
    @NotNull(message = "数量不能为空")
    private Integer qty;
    
    @NotNull(message = "价格不能为空")
    private Double price;

    // Getter和Setter方法
    public Long getCourseId() {
        return courseId;
    }

    public void setCourseId(Long courseId) {
        this.courseId = courseId;
    }

    public Long getUserId() {
        return userId;
    }

    public void setUserId(Long userId) {
        this.userId = userId;
    }

    public Integer getQty() {
        return qty;
    }

    public void setQty(Integer qty) {
        this.qty = qty;
    }

    public Double getPrice() {
        return price;
    }

    public void setPrice(Double price) {
        this.price = price;
    }
}

2. 修改CartController的方法

把HashMap替换成刚才创建的DTO类,同时简化参数解析逻辑:

@RestController
public class AddToCartController {

    @Autowired
    CartService cartService;

    @PostMapping("/addToCart")
    public ResponseEntity<Cart> addCartwithCourse(@Valid @RequestBody AddCartRequestDTO addCartRequest) {
        try {
            Cart obj = cartService.addCartbyUserIdAndCourseId(
                addCartRequest.getCourseId(),
                addCartRequest.getUserId(),
                addCartRequest.getQty(),
                addCartRequest.getPrice()
            );
            return ResponseEntity.ok(obj);
        } catch (Exception e) {
            // 这里可以返回自定义错误响应,而不是打印堆栈后返回null
            return ResponseEntity.badRequest().body(null);
        }
    }
}

注:这里用到了@Valid注解来开启参数校验,需要确保你的项目里引入了spring-boot-starter-validation依赖。

3. 优化Cart实体的小问题

你的Cart实体里的@CreatedDate注解不会自动生效,需要在主启动类上添加@EnableJpaAuditing注解,同时给该字段加上@EntityListeners和@Column(updatable = false):

@Entity
@EntityListeners(AuditingEntityListener.class)
public class Cart {
    // ... 其他字段 ...

    @CreatedDate
    @Column(updatable = false)
    private Instant createdDate;

    // ... 其他Getter/Setter ...
}

然后在主启动类添加:

@SpringBootApplication
@EnableJpaAuditing
public class YourApplication {
    public static void main(String[] args) {
        SpringApplication.run(YourApplication.class, args);
    }
}

4. 优化Service层的异常处理

目前Service里的try-catch会捕获异常后打印堆栈再返回null,建议直接向上抛出异常,让Controller统一处理:

@Service
public class CartServiceImpl implements CartService {

    @Autowired
    AddToCartRepo addToCartRepo;
    @Autowired
    CourseSerivce courseSerivce;

    @Override
    public Cart addCartbyUserIdAndCourseId(long courseId, long userId, int qty, double price) throws Exception {
        if (addToCartRepo.getCartByProductIdAnduserId(userId, courseId).isPresent()) {
            throw new Exception("商品已存在于购物车");
        }

        Cart obj = new Cart();
        obj.setQty(qty);
        obj.setUser_id(userId);
        Course course = courseSerivce.getCourseById(courseId);
        obj.setCourse(course);
        obj.setPrice(price);

        return addToCartRepo.save(obj);
    }

    @Override
    public List<Cart> getCartByUserId(long userId){
        return addToCartRepo.getCartByuserId(userId);
    }
}

修复后效果

修改完成后,Swagger会自动识别AddCartRequestDTO里的所有字段,显示出courseId、userId、qty、price这些你预期的请求参数,同时参数校验和代码可读性也会提升。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 08:15:34