• 微服务远程调用之拦截器实战


    微服务远程调用之拦截器实战

    前言:
    在我们开发过程中,很可能是项目是从0到1开发,或者在原有基础上做二次开发,这次是根据已有代码做二次开发,需要在我们微服务一【这里方便举例,我们后面叫模版微服务】调用微服务二【后面叫系统管理模块】

    需求背景
    1,模版服务需要给当前系统所有用户做默认的模版数据
    2,用户数据在系统管理模块里面
    3,需要将没有默认模板的用户的人查找出来,添加默认模板数据。
    4,一般服务与服务之间调用要有请求头信息,比如token,user_id …【遇到问题里面细讲】

    使用步骤

    1、引入openfeign依赖
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-openfeign</artifactId>
    </dependency>
    
    2、Feignclient远程接口
    package com.xx.xx.xx.feign.client;
    
    import com.xx.xx.xx.api.R;
    import org.springframework.cloud.openfeign.FeignClient;
    import org.springframework.http.HttpHeaders;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RequestHeader;
    import org.springframework.web.bind.annotation.RequestParam;
    
    /**
     * @author psd 
     *  xxx_manage_service 远程调用微服务的名字
     * 请求地址是全路径地址
     *
     */
    @FeignClient(name = "xxx_manage_service")
    public interface SmartGateWayClient {
      
           @GetMapping("/api/xx/portalMyConfig/queryAllPortalMyConfig")
           R<List<MyxxxConfigVo>> queryAllMyxxxConfigVo();
    
    }
    
    
    3、编写feignClient拦截器

    每次远程调用前,设置请求头信息

    package com.xx.xx.xx.interceptor;
    
    import feign.RequestInterceptor;
    import feign.RequestTemplate;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.stereotype.Component;
    
    import javax.servlet.http.HttpServletRequest;
    
    /**
     * @author psd 远程调用拦截器设置头参数信息
     */
    @Slf4j
    @Component
    public class FeignClientInterceptor implements RequestInterceptor {
    
        HttpServletRequest request;
    
        public FeignClientInterceptor(HttpServletRequest request) {
            this.request = request;
        }
    
        @Override
        public void apply(RequestTemplate requestTemplate) {
            // 设置请求头的数据
            requestTemplate.header("Authorization",request.getHeader("Authorization"));
            // TODO:有的还需要添加 user_id 信息 
            log.info("FeignClientInterceptor 拦截器中的请求头的信息 Authorization :{}",request.getHeader("Authorization"));
        }
    }
    
    4、主启动类添加@EnableFeignClients 注解
    package com.xx.xxx.platform;
    
    import org.mybatis.spring.annotation.MapperScan;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
    import org.springframework.cloud.context.config.annotation.RefreshScope;
    import org.springframework.cloud.openfeign.EnableFeignClients;
    import org.springframework.scheduling.annotation.EnableScheduling;
    import springfox.documentation.swagger2.annotations.EnableSwagger2;
    
    /**
     * @author psd
     */
    
    @RefreshScope
    @EnableSwagger2
    @EnableScheduling
    @EnableFeignClients
    @EnableDiscoveryClient
    @MapperScan("xx.xx.xx.xx.mapper")
    @SpringBootApplication
    public class PortalPlatformApplication {
        public static void main(String[] args) {
            SpringApplication.run(PlatformApplication.class, args);
        }
    }
    
    

    遇到的问题

    1、使用Feignclient 是从网关还是直接走指定微服务

    网关现在理解就是所有的请求都走网关,就是负载均衡,路由转发作用… 看项目需求一般走指定微服务

    2、编写Feignclient拦截器时候,有时需要添加user_id 信息,在系统管理服务里面有拦截,这个不一定,具体业务具体分析
    3、有个远程调用返回MyxxxConfigVo 里面有个时间
     /**
         * 创建时间
         */
        
        private LocalDateTime createTime;
        /**
         * 修改时间
         */
        private LocalDateTime updateTime;
    

    在项目接收方也是这个数据类型,报以下异常
    Caused by: org.springframework.web.client.RestClientException: Error while extracting response for type [com.pubinfo.smart.common.web.R>] and content type [application/json;charset=UTF-8]; nested exception is org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot deserialize value of type java.time.LocalDateTime from String “2024-05-25T16:25:02”: Failed to deserialize java.time.LocalDateTime: (java.time.format.DateTimeParseException) Text ‘2024-05-25T16:25:02’ could not be parsed at index 10; nested exception is com.fasterxml.jackson.databind.exc.InvalidFormatException: Cannot deserialize value of type java.time.LocalDateTime from String “2024-05-25T16:25:02”: Failed to deserialize java.time.LocalDateTime: (java.time.format.DateTimeParseException) Text ‘2024-05-25T16:25:02’ could not be pars
    大概意思是返回JSON String “2024-05-25T16:25:02”: 不能转换为 LocalDateTime 类型的时间。

    修改为以下问题解决。

        /**
         * 创建时间
         */
        @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss")
        private LocalDateTime createTime;
    
        /**
         * 修改时间
         */
        @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss")
        private LocalDateTime updateTime;
    
    4、自定义模版服务调用系统管理服务 在请求的时候报 用户不存在

    详细描述:
    但是添加了token的信息,且token不为空,这个后面猜测可能是在系统管理服务里面有个拦截器需要校验user_id 是否为空,为空就报异常。
    后面在远程调用前添加 请求头信息user_id 的值。问题解决

    喜欢我的文章的话,点个阅读或者点个点赞,是我编写博客的动力,持续更新中 ing…

  • 相关阅读:
    峰回网关数采PLC
    嵌入式常用计算神器EXCEL,欢迎各位推荐技巧,以保持文档持续更新,为其他人提供便利
    【安全狗】Linux后渗透常见后门驻留方式分析
    【无标题】
    一文带你搞懂 SSR
    Python Argparse 库讲解特别好的
    华为ac+fit漫游配置案例
    RAG综述 《Retrieval-Augmented Generation for Large Language Models: A Survey》笔记
    谷歌Chrome庆祝15周年,推出全新设计!了解最新信息!
    HTTP协议中GET请求和POST请求的区别
  • 原文地址:https://blog.csdn.net/qq_45938780/article/details/139323587