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

如何在Micronaut中实现JAX-RS风格的ContainerRequest/ResponseFilter

在Micronaut中实现类似JAX-RS的入站/出站过滤器

Micronaut的HttpServerFilter虽然没有像JAX-RS那样拆分出独立的入站/出站接口,但可以通过**chain.proceed()方法的执行时机**来区分处理方向,完全实现和ContainerRequestFilter、ContainerResponseFilter一致的效果。


1. 仅处理入站请求(对应ContainerRequestFilter)

在调用chain.proceed(request)之前编写的逻辑,会在请求进入服务时触发,专门处理入站请求的修改、校验等操作。

import io.micronaut.http.HttpRequest;
import io.micronaut.http.HttpResponse;
import io.micronaut.http.annotation.Filter;
import io.micronaut.http.filter.HttpServerFilter;
import io.micronaut.http.filter.ServerFilterChain;
import org.reactivestreams.Publisher;

@Filter("/**") // 匹配所有路径,可根据业务调整范围
public class InboundRequestFilter implements HttpServerFilter {

    @Override
    public Publisher<HttpResponse<?>> doFilter(HttpRequest<?> request, ServerFilterChain chain) {
        // 这里处理入站请求逻辑:比如校验请求头、修改请求参数
        System.out.println("处理入站请求: " + request.getMethod() + " " + request.getUri());
        
        // 示例:给请求添加自定义头
        HttpRequest<?> modifiedRequest = request.header("X-Inbound-Filter", "processed");
        
        // 继续执行后续过滤器和控制器逻辑
        return chain.proceed(modifiedRequest);
    }
}

2. 仅处理出站响应(对应ContainerResponseFilter)

通过订阅chain.proceed(request)返回的Publisher<HttpResponse>,在响应返回客户端前处理响应内容、头信息等。

import io.micronaut.http.HttpRequest;
import io.micronaut.http.HttpResponse;
import io.micronaut.http.annotation.Filter;
import io.micronaut.http.filter.HttpServerFilter;
import io.micronaut.http.filter.ServerFilterChain;
import org.reactivestreams.Publisher;
import reactor.core.publisher.Flux;

@Filter("/**")
public class OutboundResponseFilter implements HttpServerFilter {

    @Override
    public Publisher<HttpResponse<?>> doFilter(HttpRequest<?> request, ServerFilterChain chain) {
        // 先让请求正常流转到控制器,再处理响应
        return Flux.from(chain.proceed(request))
                .map(response -> {
                    // 这里处理出站响应逻辑:比如添加响应头、修改响应体
                    System.out.println("处理出站响应: " + response.getStatus());
                    
                    // 示例:给响应添加自定义头
                    return response.header("X-Outbound-Filter", "processed");
                });
    }
}

3. 单个过滤器同时处理入站和出站

如果需要在同一个过滤器中兼顾请求和响应处理,只需结合上面两种写法即可:

import io.micronaut.http.HttpRequest;
import io.micronaut.http.HttpResponse;
import io.micronaut.http.annotation.Filter;
import io.micronaut.http.filter.HttpServerFilter;
import io.micronaut.http.filter.ServerFilterChain;
import org.reactivestreams.Publisher;
import reactor.core.publisher.Flux;

@Filter("/api/**") // 仅匹配/api前缀的请求
public class CombinedFilter implements HttpServerFilter {

    @Override
    public Publisher<HttpResponse<?>> doFilter(HttpRequest<?> request, ServerFilterChain chain) {
        // 1. 处理入站请求
        System.out.println("入站请求: " + request.getUri());
        HttpRequest<?> modifiedRequest = request.header("X-Combined", "inbound-done");
        
        // 2. 处理出站响应
        return Flux.from(chain.proceed(modifiedRequest))
                .map(response -> {
                    System.out.println("出站响应: " + response.getStatus());
                    return response.header("X-Combined", "outbound-done");
                });
    }
}

核心逻辑说明

Micronaut过滤器和JAX-RS的核心区别在于:

  • JAX-RS用两个独立接口拆分入站/出站逻辑
  • Micronaut用**chain.proceed()的执行阶段**区分:
    • chain.proceed()之前:入站请求处理(对应ContainerRequestFilter)
    • chain.proceed()返回的响应流处理:出站响应处理(对应ContainerResponseFilter)

额外注意点

  • 用@Filter注解指定过滤器的匹配路径,支持通配符(如/**、/api/**)
  • 可用@Order注解指定过滤器执行顺序,数值越小优先级越高
  • 基于Reactive编程模型,处理响应时需使用Reactive操作符(如map、flatMap),避免阻塞线程

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 03:10:28