【问题标题】:how to modify HttpRequest body parameters in a HttpFilter如何在 HttpFilter 中修改 HttpRequest 正文参数
【发布时间】:2021-07-13 19:00:57
【问题描述】:

我正在使用 Micronaut HttpFilter 来拦截请求和请求正文参数之一。

到目前为止,这是我尝试过的,但我无法在拦截器中获取请求正文参数。

这里的目的是检查urlbody参数,如果与白名单域名不匹配,则将urlbody参数替换为白名单域名。

拦截器类

package com.aabingunz.web

import groovy.json.JsonSlurper
import io.micronaut.http.HttpRequest
import io.micronaut.http.HttpRequestWrapper
import io.micronaut.http.HttpResponse
import io.micronaut.http.annotation.Filter
import io.micronaut.http.filter.FilterChain
import io.micronaut.http.filter.HttpFilter
import io.micronaut.http.netty.NettyHttpHeaders
import org.reactivestreams.Publisher

@Filter('/**')
class RequestInterceptor implements HttpFilter {

    private final JsonSlurper mapper = new JsonSlurper()

    @Override
    Publisher<? extends HttpResponse<?>> doFilter(HttpRequest<?> request, FilterChain chain) {
        request = new HttpRequestWrapper<?>(request)
        NettyHttpHeaders headers = request.getHeaders()

        /**
        * Intercept headers
        */
        String tokenHeader = headers.get("token")
        println "Reached inside RequestInterceper tokenHeader: " + tokenHeader

        /**
        * Intercept body params
        */
        Optional<String> body = request.getBody(String.class)
        def params = mapper.parseText(body.get())

        /**
        * TO-DO: Valdate and modify url body parameter
        */

        println "Inside RequestInterceper tokenHeader: " + tokenHeader
        println "Inside RequestInterceper body params: " + params

        return chain.proceed(request)
    }
}

控制器类

package com.aabingunz.web

import io.micronaut.core.annotation.Nullable
import io.micronaut.http.HttpHeaders
import io.micronaut.http.HttpRequest
import io.micronaut.http.HttpResponse
import io.micronaut.http.MediaType
import io.micronaut.http.annotation.Body
import io.micronaut.http.annotation.Consumes;
import io.micronaut.http.annotation.Controller
import io.micronaut.http.annotation.Get
import io.micronaut.http.annotation.Post
import io.micronaut.http.annotation.Produces


@Controller("/base/api/v1")
class BaseController {

    @Get(uri="/get/example", produces="text/plain")
    String index() {
        return "Example Response"
    }
    @Post("/post/example")
    @Produces(MediaType.APPLICATION_JSON)
    @Consumes(MediaType.APPLICATION_JSON)
    HttpResponse<String> postIndex(@Nullable @Body String payload, HttpRequest<?> request) {
        HttpHeaders httpHeaders = request.getHeaders()
        String token = httpHeaders.get('token').toString()

        println "Inside BaseController body payload: " + payload
        println "Inside BaseController tokenHeader: " + token

        String results = "{'tokenHeader':"+token+"}"
        return HttpResponse.ok(results)
    }

}

邮递员/Curl 请求

curl --location --request POST 'http://localhost:8080/base/api/v1/post/example' \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--header 'token: 5678' \
--data-raw '{
    "userId": "aabingunz",
    "url": "http://hacker-domain.com"
}'

输出(RequestInterceptor body.get() 给出No value present

09:24:13.369 [main] INFO  io.micronaut.runtime.Micronaut - Startup completed in 3124ms. Server Running: http://localhost:8080
Reached inside RequestInterceper tokenHeader: 5678
09:25:17.617 [default-nioEventLoopGroup-1-3] ERROR i.m.h.s.netty.RoutingInBoundHandler - Unexpected error occurred: No value present
java.util.NoSuchElementException: No value present
    at java.util.Optional.get(Optional.java:135)
    at java_util_Optional$get.call(Unknown Source)
    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:130)
    at com.aabingunz.web.RequestInterceptor.doFilter(RequestInterceptor.groovy:33)
    at io.micronaut.http.server.netty.RoutingInBoundHandler.filterPublisher(RoutingInBoundHandler.java:2106)
    at io.micronaut.http.server.netty.RoutingInBoundHandler.buildResultEmitter(RoutingInBoundHandler.java:1432)
    at io.micronaut.http.server.netty.RoutingInBoundHandler.executeRoute(RoutingInBoundHandler.java:1109)
    at io.micronaut.http.server.netty.RoutingInBoundHandler.handleRouteMatch(RoutingInBoundHandler.java:775)
    at io.micronaut.http.server.netty.RoutingInBoundHandler.channelRead0(RoutingInBoundHandler.java:606)
    at io.micronaut.http.server.netty.RoutingInBoundHandler.channelRead0(RoutingInBoundHandler.java:148)
    at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:99)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
    at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:102)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
    at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:103)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
    at io.micronaut.http.netty.reactive.HandlerPublisher.channelRead(HandlerPublisher.java:351)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
    at io.micronaut.http.netty.stream.HttpStreamsHandler.channelRead(HttpStreamsHandler.java:255)
    at io.micronaut.http.netty.stream.HttpStreamsServerHandler.channelRead(HttpStreamsServerHandler.java:123)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
    at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:103)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
    at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:103)
    at io.netty.handler.codec.MessageToMessageCodec.channelRead(MessageToMessageCodec.java:111)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
    at io.netty.channel.ChannelInboundHandlerAdapter.channelRead(ChannelInboundHandlerAdapter.java:93)
    at io.netty.handler.codec.http.HttpServerKeepAliveHandler.channelRead(HttpServerKeepAliveHandler.java:64)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
    at io.netty.handler.flow.FlowControlHandler.dequeue(FlowControlHandler.java:200)
    at io.netty.handler.flow.FlowControlHandler.channelRead(FlowControlHandler.java:162)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
    at io.netty.channel.CombinedChannelDuplexHandler$DelegatingChannelHandlerContext.fireChannelRead(CombinedChannelDuplexHandler.java:436)
    at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:324)
    at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:311)
    at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:432)
    at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:276)
    at io.netty.channel.CombinedChannelDuplexHandler.channelRead(CombinedChannelDuplexHandler.java:251)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
    at io.netty.handler.timeout.IdleStateHandler.channelRead(IdleStateHandler.java:286)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
    at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
    at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919)
    at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:166)
    at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:719)
    at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:655)
    at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:581)
    at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:493)
    at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:989)
    at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
    at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
    at java.lang.Thread.run(Thread.java:748)
Reached inside RequestInterceper tokenHeader: 5678

使用Micronaut v2.5.1

【问题讨论】:

  • 您的过滤器运行了吗?它打印什么吗?
  • @Renato 是的,如果我删除 Intercept body params 评论下方的 2 条语句,过滤器就会工作。我已经用输出更新了我的问题。
  • GET 请求没有正文。此外,即使他们这样做,也不意味着正文是 JSON...您应该检查方法是 POST(或您正在使用的任何方法)并且 Content-Type 包括 application/json
  • @Renato:我正在发出具有所需正文参数的 POST 请求(我的问题中存在 curl 命令)。 doFilter 方法也是通用的,它能够捕获 GET 和 POST 请求(包括 json 正文),因为它能够到达我的控制器并且在被 RequestInterceptor 拦截并且控制器可以访问 json 数据之后。只有在我在Intercept body params 评论之后添加了 2 个语句之后,此流程才停止工作。
  • @Renato:你有没有关于如何使用 HttpRequest 或扩展 HttpRequestWrapper 来读取和修改现有请求来捕获和修改 doFilter 中的正文参数的示例?

标签: java groovy micronaut


【解决方案1】:

我想是因为这个breaking changes

In Micronaut 2.5 the body will not be read until after filters are executed.
This may lead to cases where the body was available in a filter and is no longer available.

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-09-13
    • 1970-01-01
    • 2019-12-12
    • 2023-03-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-30
    相关资源
    最近更新 更多