美文网首页
springboot2.x feign集成 统一验证sign f

springboot2.x feign集成 统一验证sign f

作者: X作业写完了吗 | 来源:发表于2020-05-08 22:58 被阅读0次

    微服务大行其道,新框架一般都基于springboot2.x
    系统越来越多,系统间的交互不可避免,feign应用越来越广泛。
    那么问题来了:
    springboot2如何整合feign呢 , 系统间调用,如何统一验签?往下看

    1、如何集成呢?

    https://start.spring.io/

    initial-springboot.png

    Application中启用@EnableFeignClients

    @EnableFeignClients
    @SpringBootAApplication
    public class XXXApplication {
        public static void main(String[] args) {
            SpringApplication.run(XXXApplication.class, args);
        }
    }
    

    声明Feign@FeignClient

    @FeignClient(name = "xxxName", url = "${xxx.server.domain}", configuration = CustomFeignConfig.class)
    public interface XXXFeign {
        @RequestMapping(value = "/api/v/xxx", method = RequestMethod.GET)
        String xxx(@RequestParam String x1);
    @RequestMapping(value = "/api/xxx2", method = RequestMethod.POST,consumes = {MediaType.APPLICATION_FORM_URLENCODED_VALUE})
        String xxx2(Map<String,?> map, @RequestHeader(value = "u2at")String u2at);// map中 一定要 ? 此处有坑
    }
    

    FeignConfig配置

    @Configuration
    public class CustomFeignConfig  {
        @Bean
        Logger.Level feignLoggerLevel() {
            return Logger.Level.FULL;
        }
    
       @Autowired
        private ObjectFactory<HttpMessageConverters> messageConverters;
    
        // new一个form编码器,实现支持form表单提交
        @Bean
        public Encoder feignFormEncoder() {
            return new SpringFormEncoder(new SpringEncoder(messageConverters));
        }
        @Bean
        FeignLoggerFactory infoFeignLoggerFactory() {
            return new CustomFeignLoggerFactory();
        }
        static class CustomFeignLoggerFactory implements FeignLoggerFactory {
            public Logger create(Class<?> type) {
                return new CustomFeignLogger(LoggerFactory.getLogger(type));
            }
        }
        static class CustomFeignLogger extends Logger {
            private final org.slf4j.Logger logger;
            public CustomFeignLogger(org.slf4j.Logger logger) {
                this.logger = logger;
            }
            @Override
            protected void log(String configKey, String format, Object... args) {
                if (logger.isInfoEnabled()) {
                    this.logger.info(String.format(methodTag(configKey) + format, args));
                }
            }
            @Override
            protected void logRequest(String configKey, Level logLevel, Request request) {
                if (this.logger.isInfoEnabled()) {
                    super.logRequest(configKey, logLevel, request);
                }
            }
            @Override
            protected Response logAndRebufferResponse(String configKey, Level logLevel, Response response,
                                                      long elapsedTime) throws IOException {
                return this.logger.isInfoEnabled() ? super
                        .logAndRebufferResponse(configKey, logLevel, response, elapsedTime) : response;
            }
        }
    
    }
    

    feign超时,必须!!!

    受相关系统影响导致宕机!!!亲眼所见多次,really,no kidding
    feign.client.config.default.connectTimeout=2000
    feign.client.config.default.readTimeout=3000

    2、feign如何统一验签呢?

    每次调用接口前计算验签、赋值,显然是不可接受的,那么
    RequestInterceptor了解一下
    接口通过Target#apply发送http请求,在这里你可以拿到参数。
    计算后可以写入header、或者query、甚至body

    * Zero or more {@code RequestInterceptors} may be configured for purposes such as adding headers to
    
    * all requests. No guarantees are give with regards to the order that interceptors are applied.
    
    * Once interceptors are applied, {@link Target#apply(RequestTemplate)} is called to create the
    
    * immutable http request sent via {@link Client#execute(Request, feign.Request.Options)}.
    

    FeignConfig实现RequestInterceptor#apply

    @Configuration
    public class CustomFeignConfig implements RequestInterceptor {
        @Value("${xxx1.server.appId}")
        private String appId1;
        @Value("${xxx1.server.secret}")
        private String secret1;
        @Value("${xxx1.server.domain}")
        private String domain1;
        @Override
        public void apply(RequestTemplate requestTemplate) {
            String host = ((Target.HardCodedTarget) requestTemplate.feignTarget()).url();
            String sign = "";
            if (domain1.equals(host)) {
                if ("GET".equals(requestTemplate.method())) {
                    sign = ztGetSign(requestTemplate);
                    requestTemplate.header("sign", sign);//如果参数在header中
                    requestTemplate.header("appId", appId1);
                } else if ("POST".equals(requestTemplate.method())) {
    //                sign = ApiMac.sign(secret1, new String(requestTemplate.body()));
    //                requestTemplate.header("sign",sign);//如果参数在header中
                    JSONObject jsonParam = JSONObject.parseObject(new String(requestTemplate.body()));
                    jsonParam.put("appId", appId1);
                    jsonParam.put("sign", getParamSign(jsonParam));//如果sign在参数中
                    requestTemplate.body(jsonParam.toJSONString());
                } else {
                    throw new UnsupportedOperationException(requestTemplate.method() + " 请先实现method sign");
                }
            } else if (domain2.equals(host)) {
                // 验签计算赋值
            }
        }
        private String getSign(RequestTemplate requestTemplate) {
            // requestTemplate.queries();  calculate sign
        }
    }
    

    到这里就完成了feign的整合,是不是觉得很简单。
    后续可以想想怎么处理接口返回数据了。

    相关文章

      网友评论

          本文标题:springboot2.x feign集成 统一验证sign f

          本文链接:https://www.haomeiwen.com/subject/imrcnhtx.html