Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Spring 使用带有RestController的ClientHttpRequestInterceptor拦截传入的客户端请求_Spring_Spring Boot_Spring Mvc - Fatal编程技术网

Spring 使用带有RestController的ClientHttpRequestInterceptor拦截传入的客户端请求

Spring 使用带有RestController的ClientHttpRequestInterceptor拦截传入的客户端请求,spring,spring-boot,spring-mvc,Spring,Spring Boot,Spring Mvc,我想在传入的请求中附加一些数据。与随机生成的令牌或uuid类似,发送到传入请求。然后我想通过控制器来处理它。我开始了解ClientHttpRequestInterceptor。但从这个角度看,它似乎只截取响应,而不截取请求。这是我没有看到的。还有别的办法吗 我如何在RestController中注册这个截取?因此,在控制器处理请求之前,请求应该已经具有数据 编辑: 我刚刚发现,我可以使用请求体中的set方法直接在控制器中设置数据。这是有效的。但我不确定这是否是推荐的方式。因为据我所知,请求必须在

我想在传入的请求中附加一些数据。与随机生成的令牌或uuid类似,发送到传入请求。然后我想通过控制器来处理它。我开始了解ClientHttpRequestInterceptor。但从这个角度看,它似乎只截取响应,而不截取请求。这是我没有看到的。还有别的办法吗

我如何在RestController中注册这个截取?因此,在控制器处理请求之前,请求应该已经具有数据

编辑: 我刚刚发现,我可以使用请求体中的set方法直接在控制器中设置数据。这是有效的。但我不确定这是否是推荐的方式。因为据我所知,请求必须在DispatcherServlet中修改


请给出建议。

您需要添加自己的
OncePerRequestFilter
实现。在下一个链接中,您将看到一个示例:

在这种情况下,它用于包含您希望在控制器层中使用的信息(不要包含类似于
MDC.remove(mdcTokenKey);
在代码中,您希望保留
MDC
上的信息以在控制器中访问它)

PD:Spring MVC的内部服务器:Tomcat、Jetty等重用线程,因此,如果您不想出现一些问题,那么在“TheadContext缓存”中始终包含一个值是很重要的。通过这种方式,您将避免查找“旧值”,我的意思是,当前线程中包含的值,但是“以前的Http请求”中包含的值


更新(修改请求正文):

如果要修改请求本身,请查看以下链接:


您需要添加自己的
OncePerRequestFilter
实现。在下一个链接中,您将看到一个示例:

在这种情况下,它用于包含您希望在控制器层中使用的信息(不要包含类似于
MDC.remove(mdcTokenKey);
在代码中,您希望保留
MDC
上的信息以在控制器中访问它)

PD:Spring MVC的内部服务器:Tomcat、Jetty等重用线程,因此,如果您不想出现一些问题,那么在“TheadContext缓存”中始终包含一个值是很重要的。通过这种方式,您将避免查找“旧值”,我的意思是,当前线程中包含的值,但是“以前的Http请求”中包含的值


更新(修改请求正文):

如果要修改请求本身,请查看以下链接:


如果您不想这样做(), 您可以执行以下操作之一:

  • OncePerRequestFilter
    (如@doctore答案中所述)并向请求添加参数。这将允许您向请求添加数据,但不会更改客户端发送的任何内容
  • 在控制器中添加一个方法,并在处理开始时调用它。我不太喜欢这种方法,因为与过滤器方法不同,它需要调用方法
  • [注意:我从未尝试过这个方法,但应该可以]在控制器中输入handler方法之前,添加一个方法[某处]并使用Spring AOP调用它。这很好,但本质上只是您创建自己的处理OncePerRequestFilter的方法
  • 对于Spring,肯定还有其他方法可以做到这一点,
    我只是不认识他们。

    如果你不想这样做(), 您可以执行以下操作之一:

  • OncePerRequestFilter
    (如@doctore答案中所述)并向请求添加参数。这将允许您向请求添加数据,但不会更改客户端发送的任何内容
  • 在控制器中添加一个方法,并在处理开始时调用它。我不太喜欢这种方法,因为与过滤器方法不同,它需要调用方法
  • [注意:我从未尝试过这个方法,但应该可以]在控制器中输入handler方法之前,添加一个方法[某处]并使用Spring AOP调用它。这很好,但本质上只是您创建自己的处理OncePerRequestFilter的方法
  • 对于Spring,肯定还有其他方法可以做到这一点,
    我只是不认识他们。

    我认为这不允许我向传入的请求中添加额外的数据。我没有试图为请求设置uuid。我正在尝试将uuid设置为请求中的数据在上述方法中,您将能够执行类似的操作,我的意思是,对于每个输入请求,您将能够在ThreadContext缓存中包含您所需的内容,并且可以在代码的“每个部分”中访问它(甚至可以重用它来对其他微服务执行另一个请求)。然而,我已经用一种更类似于您所寻找的方法更新了答案。我只是想了解更多,我这样做的方式是在控制器中设置值。但我只是想知道,是否建议修改控制器中的数据?我不希望代码的其他部分可以访问这些数据,否则它永远不会重用这些数据。答案取决于您想要实现什么。如果要在所有传入请求中包含相同的信息,您有两个选项:
    修改每个传入请求正文
    (我的答案的更新部分)或
    创建一个过滤器以在ThreadContext中包含所需内容
    (我的答案的初始部分)。第二种方法的优点是,您不需要准备DTO(Java对象来存储控制器方法中接收到的信息)来处理这些新属性。但是,如果您只在某些控制器方法中需要这些信息,那么还有更合适的方法。使用您提到的“setter方法”,您需要将其包含在每个控制器(或创建pa)中