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

Spring WebFlux函数式端点遇无效媒体类型返回404,如何改为415?

如何让Spring Boot 2函数式端点返回415而非404?

你现在用的是Spring Boot 2.0.1.RELEASE的函数式端点,定义了这样的请求匹配谓词:

private RequestPredicate getByIdPredicate() { 
    return RequestPredicates.GET("/*/{id}")
            .and(RequestPredicates.accept(MediaType.APPLICATION_JSON_UTF8)); 
}

问题是当用错误的媒体类型(比如application/invalidMediaType)调用API时,端点返回的是404,但你希望返回415 Unsupported Media Type对吧?

问题根源

当前你把路径匹配和Accept头匹配合并成了一个谓词,只有两个条件同时满足时,Spring才会认为这个端点存在。如果Accept头不匹配,Spring就找不到对应的端点,自然返回404。要返回415,得把这两个校验分开,先让路径匹配成功,再单独校验Accept头。

具体实现方案

最简单直接的方式是拆分谓词,在请求处理方法里手动校验Accept头:

  1. 先定义只匹配路径的谓词:
private RequestPredicate getByIdPathPredicate() {
    return RequestPredicates.GET("/*/{id}");
}
  1. 在请求处理方法中添加Accept头校验:
public Mono<ServerResponse> handleGetById(ServerRequest request) {
    // 检查请求的Accept头是否符合要求
    List<MediaType> acceptedTypes = request.headers().accept();
    if (!acceptedTypes.contains(MediaType.APPLICATION_JSON_UTF8)) {
        return ServerResponse.status(HttpStatus.UNSUPPORTED_MEDIA_TYPE).build();
    }

    // 正常处理业务逻辑
    String id = request.pathVariable("id");
    // ... 这里写你的业务代码,比如查询数据等
    return ServerResponse.ok()
            .contentType(MediaType.APPLICATION_JSON_UTF8)
            .bodyValue(yourBusinessData);
}
  1. 注册路由时使用路径匹配谓词:
@Bean
public RouterFunction<ServerResponse> routerFunction() {
    return RouterFunctions.route(getByIdPathPredicate(), this::handleGetById);
}

为什么这样能行?

当请求路径匹配成功后,不管Accept头是否符合,都会进入handleGetById方法。这时候我们手动校验Accept头,不符合就直接返回415状态码,这样就不会出现Spring因为找不到端点而返回404的情况了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 04:05:33