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

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

作者: 贝贝的备忘录 | 来源:发表于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