webflux 在过滤器中向 ServerHttpRequest

2021-03-27  本文已影响0人  itkkanae

这里使用反射来实现参数添加,先贴代码、Controller接口代码:

@GetMapping("/test")
public Mono<String> test(String param1, String param2, String param3) {
    return Mono.just(param1 + param2 + param3);
}

Filter代码:

@Configuration
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE)
public class TokenFilter implements WebFilter {

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
        // 获取Request
        ServerHttpResponse res = exchange.getResponse();
        // 获取参数列表
        MultiValueMapAdapter params = (MultiValueMapAdapter) req.getQueryParams();

        try {
            // 反射获取请求参数成员变量
            Field targetMap = params.getClass().getDeclaredField("targetMap");
            targetMap.setAccessible(true);
            // 创建一个新的可修改的Map
            Map newMap = new HashMap((Map) targetMap.get(params));
            // TODO: 这里插入需要的参数(value类型需要是List)
            newMap.put("param1", List.of("string1..."));
            newMap.put("param2", List.of("string2..."));
            newMap.put("param3", List.of("string3..."));
            // 将原有参数表替换
            targetMap.set(params, newMap);
        } catch (NoSuchFieldException | IllegalAccessException e) {
            e.printStackTrace();
        }
        return chain.filter(exchange);
    }

}

效果:



插入参数可能需要注意的几点:
1、请求参数列表QueryParams的类型是MultiValueMapAdapter,参数存放在成员变量targetMap中

public class MultiValueMapAdapter<K, V> implements MultiValueMap<K, V>, Serializable {

        private final Map<K, List<V>> targetMap;
        // ...

}

2、targetMap是一个final成员,使用原有的put(),add()等操作都会报下面这个错

java.lang.UnsupportedOperationException
Caused by: java.lang.UnsupportedOperationException: null
    at java.base/java.util.Collections$UnmodifiableMap.computeIfAbsent(Collections.java:1535)
    at org.springframework.util.MultiValueMapAdapter.add(MultiValueMapAdapter.java:66)
    // ...

3、targetMap的value需要是一个List,否则可能还会意外收获这个错

java.lang.ClassCastException: class java.lang.String cannot be cast to class java.util.List (java.lang.String and java.util.List are in module java.base of loader 'bootstrap')
    at org.springframework.util.MultiValueMapAdapter.get(MultiValueMapAdapter.java:132)
    Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException: 
Error has been observed at the following site(s):
    |_ checkpoint ⇢ springfox.boot.starter.autoconfigure.SwaggerUiWebFluxConfiguration$CustomWebFilter [DefaultWebFilterChain]
    // ...
上一篇 下一篇

猜你喜欢

热点阅读