SpringCloud组件OpenFeign之拦截器怎么创建

其他教程   发布日期:2025年04月19日   浏览次数:129

这篇文章主要介绍“SpringCloud组件OpenFeign之拦截器怎么创建”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“SpringCloud组件OpenFeign之拦截器怎么创建”文章能帮助大家解决问题。

    SpringCloud组件OpenFeign之拦截器

    OpenFeign组件中有这么一个接口。

    我们来看一下源码中关于这个接口的介绍。

    1. package feign;
    2. /**
    3. * 可以配置零个或多个请求拦截器,可以用于例如给所有请求添加请求头信息.但是不能保证拦截器的应用顺
    4. * 序。一旦拦截器被应用,就会调用Target类中的apply(RequestTemplate)方法去创建不可变的http请
    5. * 求,该请求通过Client类中的execute(Request, feign.Request.Options)发送。
    6. *
    7. * 拦截器是在设置rest模板参数后才被应用的,因此不能再拦截器中添加参数,比如不能再
    8. * apply(RequestTemplate)方法中给/path/{foo}/bar中的foo设置参数。
    9. * 这个类类似于RequestInterceptor.intercept()方法,可以实现读取、删除或以其他方式改变请求模板
    10. * 的任何部分。
    11. */
    12. public interface RequestInterceptor {
    13. /**
    14. * 可以被每个请求调用。使用RequestTemplate提供的这个方法可以添加数据。
    15. */
    16. void apply(RequestTemplate template);
    17. }

    通过对该类及方法的注释可以了解到RequestInterceptor接口的apply方法可以对请求进行拦截,可以在该方法中添加请求头信息。

    实践一下。

    一、创建一个拦截器在请求头中添加traceId信息

    场景如下,使用拦截器在请求头中添加traceId属性,服务端可以获取到该traceId,用于日志追踪。

    方式一:创建自定义拦截器+@Configuration

    1. package com.example.rtbootconsumer.config.interceptor;
    2. import com.example.rtbootconsumer.common.utils.TraceIdUtil;
    3. import feign.Request;
    4. import feign.RequestInterceptor;
    5. import feign.RequestTemplate;
    6. import org.apache.commons.lang3.StringUtils;
    7. import org.springframework.context.annotation.Configuration;
    8. /**
    9. * @Description Feign接口请求拦截器
    10. **/
    11. @Configuration
    12. public class FeignRequestInterceptor implements RequestInterceptor {
    13. /**
    14. * @description: 将traceId设置到请求头
    15. */
    16. @Override
    17. public void apply(RequestTemplate template) {
    18. String traceId = TraceIdUtil.getTraceId();
    19. if (StringUtils.isNotEmpty(traceId)) {
    20. template.header("traceId", traceId);
    21. }
    22. }
    23. }

    方式二:创建自定义拦截器+配置@FeignClient注解的configuration属性

    1. package com.example.rtbootconsumer.config.interceptor;
    2. import com.example.rtbootconsumer.common.utils.TraceIdUtil;
    3. import feign.Request;
    4. import feign.RequestInterceptor;
    5. import feign.RequestTemplate;
    6. import org.apache.commons.lang3.StringUtils;
    7. import org.springframework.context.annotation.Configuration;
    8. /**
    9. * @Description Feign接口请求拦截器
    10. **/
    11. public class FeignRequestInterceptor implements RequestInterceptor {
    12. /**
    13. * @description: 将traceId设置到请求头
    14. */
    15. @Override
    16. public void apply(RequestTemplate template) {
    17. String traceId = TraceIdUtil.getTraceId();
    18. if (StringUtils.isNotEmpty(traceId)) {
    19. template.header("traceId", traceId);
    20. }
    21. }
    22. }
    1. package com.example.rtbootconsumer.feignservice;
    2. import com.example.rtbootconsumer.pojo.User;
    3. import com.example.rtbootconsumer.vo.ResultBody;
    4. import org.springframework.cloud.openfeign.FeignClient;
    5. import org.springframework.web.bind.annotation.*;
    6. import java.util.List;
    7. @FeignClient(name = "service-provider", path = "/testComm", url = "${addr.url}",configuration = FeignRequestInterceptor.class)
    8. public interface UserFeignService {
    9. @PostMapping(value = "/getUser")
    10. public ResultBody<User> getUser(@RequestBody User user);
    11. }

    二、创建两个拦截器

    也可以同时创建多个拦截器实现拦截器链的功能。

    此时再创建一个拦截器FeignRequestInterceptor2,用于在请求头中设置属性名为test,值为lalala信息。

    方式一:同上

    1. package com.example.rtbootconsumer.config.interceptor;
    2. import com.example.rtbootconsumer.common.utils.TraceIdUtil;
    3. import feign.Request;
    4. import feign.RequestInterceptor;
    5. import feign.RequestTemplate;
    6. import org.apache.commons.lang3.StringUtils;
    7. import org.springframework.context.annotation.Configuration;
    8. /**
    9. * @Description Feign接口请求拦截器
    10. **/
    11. @Configuration
    12. public class FeignRequestInterceptor2 implements RequestInterceptor {
    13. /**
    14. * @description: 将test设置到请求头
    15. */
    16. @Override
    17. public void apply(RequestTemplate template) {
    18. String traceId = TraceIdUtil.getTraceId();
    19. if (StringUtils.isNotEmpty(traceId)) {
    20. template.header("test", "lalala");
    21. }
    22. }
    23. }

    方式二:同上,注意这里设置的@FeignClient注解的configuration属性值是两个拦截器的class数组。

    1. package com.example.rtbootconsumer.feignservice;
    2. import com.example.rtbootconsumer.pojo.User;
    3. import com.example.rtbootconsumer.vo.ResultBody;
    4. import org.springframework.cloud.openfeign.FeignClient;
    5. import org.springframework.web.bind.annotation.*;
    6. import java.util.List;
    7. @FeignClient(name = "service-provider", path = "/testComm", url = "${addr.url}",configuration = {FeignRequestInterceptor.class,FeignRequestInterceptor2.class})
    8. public interface UserFeignService {
    9. @PostMapping(value = "/getUser")
    10. public ResultBody<User> getUser(@RequestBody User user);
    11. @PostMapping(value = "/testList")
    12. public ResultBody<List<User>> testList(@RequestBody List<User> list);
    13. }

    三、注意

    在创建并配置拦截器时有两点需要特别注意。

    1.在使用方式一去创建拦截器时

    会拦截所有请求。用方式二时若@FeignClient注解的configuration属性未设置拦截器,那么并不会拦截该接口下所有方法的请求。拦截器只会拦截所有configuration属性值设置了拦截器的接口下所有方法的请求。因此使用方式二更灵活。

    2.拦截器执行顺序

    若使用方式一去创建多个拦截器时,正如前面注释所讲,不能保证拦截器的执行顺序。

    但是使用方式二则可以控制拦截器的执行顺序,拦截器的执行顺序和@FeignClient注解中configuration属性中拦截器的配置顺序有关。

    若配置为 {FeignRequestInterceptor.class,FeignRequestInterceptor2.class}),则会先执行FeignRequestInterceptor中的拦截,再执行FeignRequestInterceptor2中的拦截。

    若配置为 {FeignRequestInterceptor2.class,FeignRequestInterceptor.class}),则会先执行FeignRequestInterceptor2中的拦截,再执行FeignRequestInterceptor中的拦截。有兴趣的可以试一下。

    以上就是SpringCloud组件OpenFeign之拦截器怎么创建的详细内容,更多关于SpringCloud组件OpenFeign之拦截器怎么创建的资料请关注九品源码其它相关文章!