POST请求添加Drink时返回415 Unsupported Media Type问题排查
415 Unsupported Media Type 错误排查:JPA继承+REST POST接口场景
场景说明
现有两个继承自PanacheEntity的JPA实体类:Item(父类)和Drink(子类),采用JOINED继承策略。开发POST新增Drink的REST接口时,Postman请求返回415错误,已添加@Consumes(MediaType.APPLICATION_JSON)但问题未解决。
相关代码
实体类代码
@Entity @Table(name = "t_items") @Inheritance(strategy = InheritanceType.JOINED) public class Item extends PanacheEntity { @Column(nullable = false) private String title; @Column private String description; @Column(nullable = false) private float price; @Column private LocalDateTime lastUpdatedDate; @Column(nullable = false) private String lastUpdatedUser; } @Entity @Table(name = "t_drinks") public class Drink extends Item { @Column private int volume; @Column private boolean containsAlcohol; @Column private float alcoholPercentage; }
控制器代码
@POST @Path("/drinks") public Response addDrink(Drink drink, @Context UriInfo uriInfo) { Long drinkId = drinkRepository.persistDrink(drink); UriBuilder builder = uriInfo.getAbsolutePathBuilder().path(Long.toString(drinkId)); Log.info("drink persist"); return Response.created(builder.build()).build(); }
仓库代码
@Transactional(Transactional.TxType.REQUIRED) public Long persistDrink(Drink drink) { Drink.persist(drink); Log.info(String.valueOf(drink.id)); return drink.id; }
Postman请求体
{ "title": "Cola", "description": "Refreshing soda", "price": 2.5, "lastUpdatedDate": "2023-06-05T10:00:00", "lastUpdatedUser": "John Doe", "volume": 500, "containsAlcohol": false, "alcoholPercentage": 0.0 }
问题原因及解决方案
415错误本质是服务器无法解析请求体,结合你的继承场景,主要排查以下几点:
1. 缺少JSON处理依赖
如果是Quarkus项目,必须引入RESTEasy的Jackson依赖才能处理JSON请求体。检查pom.xml是否包含以下依赖:
<!-- RESTEasy Jackson JSON解析器 --> <dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-resteasy-jackson</artifactId> </dependency> <!-- Java 8日期类型支持 --> <dependency> <groupId>com.fasterxml.jackson.datatype</groupId> <artifactId>jackson-datatype-jsr310</artifactId> </dependency>
2. 继承类的JSON反序列化配置缺失
由于Drink继承自Item,Jackson默认无法自动识别子类类型,需要在父类Item上添加JSON类型识别注解:
@Entity @Table(name = "t_items") @Inheritance(strategy = InheritanceType.JOINED) // 添加JSON类型信息注解 @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type") @JsonSubTypes({ @JsonSubTypes.Type(value = Drink.class, name = "drink") }) public class Item extends PanacheEntity { // 原有字段... }
同时修改Postman请求体,添加type字段指定子类类型:
{ "type": "drink", "title": "Cola", "description": "Refreshing soda", "price": 2.5, "lastUpdatedDate": "2023-06-05T10:00:00", "lastUpdatedUser": "John Doe", "volume": 500, "containsAlcohol": false, "alcoholPercentage": 0.0 }
3. 私有字段的访问权限问题
实体类字段均为private且未提供getter/setter,Jackson默认无法访问这些字段。解决方式二选一:
- 为所有字段生成对应的getter和setter方法;
- 在每个私有字段上添加
@JsonProperty注解,允许Jackson直接访问:@Column(nullable = false) @JsonProperty private String title;
4. 确保请求头配置正确
Postman请求时必须设置Content-Type请求头为application/json,否则服务器会认为请求体格式不匹配。
5. 完善控制器注解
明确指定接口的消费和生产类型:
@POST @Path("/drinks") @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) public Response addDrink(Drink drink, @Context UriInfo uriInfo) { // 原有代码... }
总结
优先排查依赖是否齐全,然后处理继承类的JSON反序列化配置,最后确认字段访问权限和请求头配置。按上述步骤逐一验证,即可解决415错误。
内容的提问来源于stack exchange,提问作者Jan D.M.
相关产品推荐
相关产品推荐

