zoukankan      html  css  js  c++  java
  • 非springboot项目使用原生feign减少模板代码(十五)

    说明

    对于老项目 比如非spring boot项目,我们不能使用spring cloud的feign 可以采用原生的写法。spring cloud feign本质也是用原生,只是进行了封装 让我们可以采用更友好的方式使用

    调用远程接口传统写法

    为了保证复用性,会手动将外部依赖服务写入

     /**
         * 实人认证
         * @param verifyThreeMetaAndBindReqDto
         * @return
         */
        @Override
        public VerifyThreeMetaAndBindResDto verifyThreeMetaAndBind(VerifyThreeMetaAndBindReqDto verifyThreeMetaAndBindReqDto) {
            VerifyThreeMetaAndBindResDto verifyThreeMetaAndBindResDto = null;
            try {
                HttpHeaders headers = new HttpHeaders();
                headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
                headers.add("Accept", MediaType.APPLICATION_JSON.toString());
                String contentStr = JsonUtils.obj2Json(verifyThreeMetaAndBindReqDto);
                HttpEntity<String> requestEntity = new HttpEntity<>(contentStr, headers);
                LocalLoadBalanceRestTemplate restTemplate = oauth2RestTemplateFactory.create(projectCode);
    
                ResponseEntity<String> responseEntity = restTemplate.postForEntity("/openapi/members/verifyThreeMetaAndBind", requestEntity, String.class);
    
                JSONObject jsonObjectResult = JSONObject.parseObject(responseEntity.getBody());
    
                if(log.isDebugEnabled()){
                    log.debug("入参:{}",JSON.toJSONString(requestEntity));
                    log.debug("预约返回结果:{}",JSON.toJSONString(jsonObjectResult));
                }
                if (jsonObjectResult != null) {
                    if ((Integer) jsonObjectResult.get("code") == 200) {
                        verifyThreeMetaAndBindResDto = JSONObject.parseObject(jsonObjectResult.get("data").toString(), VerifyThreeMetaAndBindResDto.class);
                    } else {
                        verifyThreeMetaAndBindResDto = new VerifyThreeMetaAndBindResDto();
                        verifyThreeMetaAndBindResDto.setVerifyMsg(jsonObjectResult.get("msg") != null ? jsonObjectResult.get("msg").toString() : null);
                        verifyThreeMetaAndBindResDto.setVerifyResult(jsonObjectResult.get("code").toString());
                    }
                } else {
                    String traceId = ArmsUtils.getTraceId();
                    verifyThreeMetaAndBindResDto = new VerifyThreeMetaAndBindResDto();
                    verifyThreeMetaAndBindResDto.setVerifyResult("notResponse");
                    verifyThreeMetaAndBindResDto.setVerifyMsg(String.format("未返回数据异常编号:%s", traceId));
                    log.error("异常编号:{}接口调用/verifyThreeMetaAndBind数据异常,返回数据null,入参:{}", traceId, JSON.toJSONString(verifyThreeMetaAndBindReqDto));
                }
            } catch (Exception e) {
                String traceId = ArmsUtils.getTraceId();
                verifyThreeMetaAndBindResDto = new VerifyThreeMetaAndBindResDto();
                verifyThreeMetaAndBindResDto.setVerifyResult("notReponse");
                verifyThreeMetaAndBindResDto.setVerifyMsg(String.format("未返回数据异常编号:%s", traceId));
                log.error("异常编号:{}接口调用/verifyThreeMetaAndBind数据异常,入参:{}", traceId, JSON.toJSONString(verifyThreeMetaAndBindReqDto),e);
            }
            return verifyThreeMetaAndBindResDto;
        }

    改为feign

    引入pom依赖

    <!--feign核心包依赖-->
            <dependency>
                <groupId>com.netflix.feign</groupId>
                <artifactId>feign-core</artifactId>
                <version>8.18.0</version>
            </dependency>
            <!--使用包里里面封装的对于请求响应参数的序列化和反序列化处理-->
            <dependency>
                <groupId>com.netflix.feign</groupId>
                <artifactId>feign-jackson</artifactId>
                <version>8.18.0</version>
            </dependency>
            <!--使用扩展功能熔断降级-->
            <dependency>
                <groupId>com.netflix.feign</groupId>
                <artifactId>feign-hystrix</artifactId>
                <version>8.18.0</version>
            </dependency>
            <!--使用feign接入slf4j的功能-->
            <dependency>
                <groupId>io.github.openfeign</groupId>
                <artifactId>feign-slf4j</artifactId>
                <version>9.7.0</version>
                <scope>compile</scope>
            </dependency>

    定义接口

    /**
     * @author liqiang
     * @date 2020/9/7 10:26
     * @Description: (what) 外部接口的抽象定义,以及定义调用形式
     * (why)使用feign的方式生成代理调用api 减少模板代码
     * (how)FeignApiConfig 定义
     */
    public interface PromotionApi {
    
        @Headers({"Content-Type: application/json", "Accept: application/json"})
        @RequestLine("POST /promotion/app/maotaiBooking/getActivityInfo")
        public JsonResult<GetActivityInfoResVo> getActivityInfo(GetActivityInfoReqVo getActivityInfoReqVo);
    
        @Headers({"Content-Type: application/json", "Accept: application/json"})
        @RequestLine("POST /publicapi/v2/promotion/activity/list")
        public JsonResult<SpringPageVO<PromotionInfoVo>> list(PromotionQueryVo promotionQueryVo);
    
        @Headers({"Content-Type: application/json", "Accept: application/json"})
        @RequestLine("POST /publicapi/v2/promotion/activity/enable")
        public JsonResult enable(PromotionOperateVo promotionOperateVo);
    
        @Headers({"Content-Type: application/json", "Accept: application/json"})
        @RequestLine("POST /publicapi/v2/promotion/activity/detailedQuery/{id}")
        public JsonResult<PromotionDetailedInfoVo> detailedQuery(@Param("id") Long id);
    
        @Headers({"Content-Type: application/json", "Accept: application/json"})
        @RequestLine("POST /publicapi/v2/promotion/activity/saveOrUpdate")
        public JsonResult saveOrUpdate(PromotionCreateVo promotionCreateVo);
    
    
        @Headers({"Content-Type: application/json", "Accept: application/json"})
        @RequestLine("POST /publicapi/v2/promotion/activity/delete")
        public JsonResult delete(PromotionOperateVo promotionOperateVo);
    
        @Headers({"Content-Type: application/json", "Accept: application/json"})
        @RequestLine("POST /publicapi/v2/promotion/activity/riskEs")
        public JsonResult<List<PromotionActiveMatchRespVo>> riskEs(PromotionActiveMatchSearchReqVo reqVo);
    }

    配置

    package com.biz.bbc.config.feign;
    
    import com.biz.bbc.config.ApiAddressConfig;
    import com.biz.bbc.service.external.PromotionApi;
    import com.biz.bbc.service.external.TestHttpsApi;
    import com.biz.ut.helper.Oauth2ResourceServerExecutor;
    import feign.*;
    import feign.hystrix.HystrixFeign;
    import feign.jackson.JacksonDecoder;
    import feign.jackson.JacksonEncoder;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    /**
     * @author liqiang
     * @date 2020/9/7 10:24
     * @Description: (what)
     * (why)
     * (how)
     */
    //demo
    
    /**
     * HystrixFeign.builder()
     * .encoder(new JacksonEncoder()) //编码
     * .decoder(new JacksonDecoder()) //解码
     * //建立链接http超时1秒 请求处理3秒超时
     * .options(new Request.Options(1000, 3500))
     * //每次重试间隔和最大间隔 默认是5次
     * .retryer(new Retryer.Default(5000, 5000, 3))
     * //降级
     * .target(PromotionApi.class, "http://localhost:9905", new PromotionApi() {
     *
     * @Override public JsonResult<GetActivityInfoResVo> getActivityInfo(GetActivityInfoReqVo getActivityInfoReqVo) {
     * log.error("com.biz.bbc.service.external.PromotionApi.getActivityInfoHttp异常降级,入参:{}", JSON.toJSON(getActivityInfoReqVo));
     * return JsonResult.of(null);
     * }
     * });
     */
    
    @Configuration
    @Slf4j
    public class FeignApiConfig {
    
        @Autowired
        private ApiAddressConfig apiAddressConfig;
    
        @Autowired
        private Oauth2ResourceServerExecutor oauth2ResourceServerExecutor;
    
        @Bean
        public PromotionApi initPromotionApi() {
            return HystrixFeign.builder()
                    .encoder(new JacksonEncoder())
                    .decoder(new JacksonDecoder())
                    .logger(new feign.slf4j.Slf4jLogger(PromotionApi.class))
                    .requestInterceptor(new RequestInterceptor() {
                        @Override
                        public void apply(RequestTemplate requestTemplate) {
                            //设置token
                            requestTemplate.header("Authorization", "accessToken" + oauth2ResourceServerExecutor.getAccessToken());
                        }
                    })//默认会重试5次 不重试
                    .retryer(NeverRetry.neverRetry)
                    .logLevel(Logger.Level.FULL)
                    //建立链接http超时1秒 请求处理3秒超时
                    .options(new Request.Options(1000, 3500))
                    .target(PromotionApi.class, apiAddressConfig.promotionCenterDomain);
        }
    
        @Bean
        public TestHttpsApi TestHttpsApi() {
            return HystrixFeign.builder()
                    .encoder(new JacksonEncoder())
                    .decoder(new JacksonDecoder())
                    .logger(new feign.slf4j.Slf4jLogger(PromotionApi.class))
                    .requestInterceptor(new RequestInterceptor() {
                        @Override
                        public void apply(RequestTemplate requestTemplate) {
                            //设置token
                            requestTemplate.header("Authorization", "accessToken" + oauth2ResourceServerExecutor.getAccessToken());
                        }
                    })//默认会重试5次 不重试
                    .retryer(NeverRetry.neverRetry)
                    .logLevel(Logger.Level.FULL)
                    //建立链接http超时1秒 请求处理3秒超时
                    .options(new Request.Options(1000, 3500))
                    .target(TestHttpsApi.class, " https://swagger-hub.1919.cn");
        }
    
        /**
         * 自定义实现不重试的Retryer
         */
        public static class NeverRetry implements Retryer {
    
            public final static NeverRetry neverRetry = new NeverRetry();
    
            private NeverRetry() {
    
            }
    
            @Override
            public void continueOrPropagate(RetryableException e) {
                //不重试
                throw e;
            }
    
            @Override
            public Retryer clone() {
                return this;
            }
        }
    }
  • 相关阅读:
    对Java面向对象的理解(笔记)
    java中switch语句实际的执行顺序;java中scanner输入为什么会被跳过;Java中scanner close方法慎用的问题;什么是方法
    面向对象编程思想 以及 封装,继承,多态 和 python中实例方法,类方法,静态方法 以及 装饰器
    python关于debug设置断点调试模式下无法命中断点的问题
    手把手教大家如何用scrapy爬虫框架爬取王者荣耀官网英雄资料
    python中可变长度参数详解
    爬虫如何使用phantomjs无头浏览器解决网页源代码经过渲染的问题(以scrapy框架为例)
    python如何通过正则表达式一次性提取到一串字符中所有的汉字
    Linux 输入输出(I/O)重定向
    Linux shell 通配符 / glob 模式
  • 原文地址:https://www.cnblogs.com/LQBlog/p/13722529.html
Copyright © 2011-2022 走看看