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


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

    前言:
    在我们开发过程中,很可能是项目是从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…

  • 相关阅读:
    ②【Maven】从0上手Maven的安装与配置 - 最全教程 (下载 + 配置 + 环境变量 )
    UI设计 ,我只推荐这6个网站,真的太好用了。
    性能测试方法全解
    【Bio】基础生物学 - 基因 gene
    没有哪件事比可视化运维大屏上线更有意义了!这一天等了好久
    什么是误差和残差
    Laravel Routes Group-Prefix 使用变量问题
    Linux C应用编程-5-线程
    yarn install 这个命令安装如何加速
    2023.09.30使用golang1.18编译Hel10-Web/Databasetools的windows版
  • 原文地址:https://blog.csdn.net/qq_45938780/article/details/139323587