openfeign如何修改接口上的地址???

使用场景:假设在这里配置了路径,但是我又想通过数据库动态配置地址,该如何操作呢???

openfeign如何修改接口上的地址???_第1张图片

请看代码示例:(使用openfeign的拦截器进行处理) ---->  请看大屏幕:

接口:

package mairuirobot.iwarehousecontrol.framework.functions.iwc.feign;

import com.alibaba.fastjson.JSONObject;
import mairuirobot.iwarehousecontrol.framework.functions.dict.annotation.Dict;
import mairuirobot.iwarehousecontrol.framework.functions.dict.constant.DictConstant;
import mairuirobot.iwarehousecontrol.framework.functions.dict.constant.DictDetailConstant;
import mairuirobot.iwarehousecontrol.framework.functions.iwc.feign.interceptor.MyFeignInterceptor;
import mairuirobot.utils.dto.GeneralResponse;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.PostMapping;

/**
 * @author sunchenlong
 * @description OpenFeign 调用 iprotobus 服务
 */
@FeignClient(name = "iprotobusService", url = "${iprotobusService.addr}", configuration = MyFeignInterceptor.class)
public interface IpbFeign {

    /**
     * 上报信息
     *
     * @param req 请求信息
     * @return GeneralResponse /
     */
    @Dict(key = DictConstant.IPB_SEVICE, label = DictDetailConstant.REPORT_MSG_URL)
    @PostMapping(value = "/iprotobus/api/robot/reporter/msg", consumes = MediaType.APPLICATION_JSON_VALUE)
    GeneralResponse reportMsg(JSONObject req);
}

 拦截器:

package mairuirobot.iwarehousecontrol.framework.functions.iwc.feign.interceptor;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import feign.RequestInterceptor;
import feign.RequestTemplate;
import mairuirobot.iwarehousecontrol.domain.entity.DictDetailEntity;
import mairuirobot.iwarehousecontrol.domain.entity.ServerParamEntity;
import mairuirobot.iwarehousecontrol.framework.functions.dict.annotation.Dict;
import mairuirobot.iwarehousecontrol.framework.functions.iwc.feign.IcmFeign;
import mairuirobot.iwarehousecontrol.framework.functions.iwc.feign.IpbFeign;
import mairuirobot.iwarehousecontrol.framework.service.IDictDetailService;
import mairuirobot.iwarehousecontrol.framework.service.IServerParamService;
import mairuirobot.iwarehousecontrol.framework.utils.BeanUtil;
import mairuirobot.utils.tools.MessageFormatUtil;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Method;

/**
 * @author sunchenlong
 * @description OpenFeign 拦截器
 */
public class MyFeignInterceptor implements RequestInterceptor {

    private static final Logger LOGGER = LoggerFactory.getLogger(MyFeignInterceptor.class);

    private static final IDictDetailService DICT_DETAIL_SERVICE = BeanUtil.getBean(IDictDetailService.class);

    private static final IServerParamService SERVER_PARAM_SERVICE = BeanUtil.getBean(IServerParamService.class);

    private static final String PORT_SEPARATOR = ":";

    private static final String PROTOCOL_SEPARATOR = "://";

    @Override
    public void apply(RequestTemplate template) {
        try {
            String comment;
            // 利用正则表达式获取方法名
            String configKey = template.methodMetadata().configKey();
            String[] split = configKey.split("#");
            split = split[1].split("\\(");
            String methodName = split[0];
            Method method = null;
            if (StringUtils.containsIgnoreCase(configKey, IcmFeign.class.getSimpleName())) {
                method = IcmFeign.class.getMethod(methodName, JSONObject.class);
            } else if (StringUtils.containsIgnoreCase(configKey, IpbFeign.class.getSimpleName())) {
                method = IpbFeign.class.getMethod(methodName, JSONObject.class);
            }
            Dict annotation = method.getAnnotation(Dict.class);
            String key = annotation.key();
            String label = annotation.label();

            ServerParamEntity serverParamEntity = SERVER_PARAM_SERVICE.getOne(Wrappers.lambdaQuery().eq(ServerParamEntity::getServerCode, key));
            DictDetailEntity dictDetailEntity = DICT_DETAIL_SERVICE.getByDictKeyAndLabelKey(key, label);
            if (null == serverParamEntity || ObjectUtil.equal(serverParamEntity.getEnabled(), 0) || null == dictDetailEntity || ObjectUtil.equal(dictDetailEntity.getEnabled(), 0)) {
                comment = "暂未配置第三方服务url,使用默认url";
                LOGGER.info(MessageFormatUtil.format(comment + ": serverParam = {0}, dictDetail = {1}", serverParamEntity, dictDetailEntity));
                return;
            }

            String addr = serverParamEntity.getProtocolType() + PROTOCOL_SEPARATOR + serverParamEntity.getServerAddr() + PORT_SEPARATOR + serverParamEntity.getServerPort();
            String url = dictDetailEntity.getLabelValue();
            comment = "获取到第三方服务url";
            LOGGER.info(MessageFormatUtil.format(comment + ": addr = {0}, url = {1}", addr, url));
            template.uri(url, false);
            template.target(addr);
        } catch (Exception e) {
            try {
                throw e;
            } catch (NoSuchMethodException ex) {
                throw new RuntimeException(ex);
            }
        }
    }
}

 只需要用到拦截器中的 uri 和 target 方法即可实现替换接口上固定的请求地址。

注意:uri   第二个参数为true代表追加,如果你想要替换全部路径,可以选择不追加。具体请参考源码。

你可能感兴趣的:(日后嚣张的资本,java)