在运行时,我该如何更改假单URL



@FeignClient(name = "test", url="http://xxxx")

在运行时,如何更改假un(url =" http://xxxx"(?因为只能在运行时确定URL。

您可以添加一个未注释的URI参数(可以在运行时确定,这将是将用于请求的基本路径。例如:

    @FeignClient(name = "dummy-name", url = "https://this-is-a-placeholder.com")
    public interface MyClient {
        @PostMapping(path = "/create")
        UserDto createUser(URI baseUrl, @RequestBody UserDto userDto);
    }

然后用法将是:

    @Autowired 
    private MyClient myClient;
    ...
    URI determinedBasePathUri = URI.create("https://my-determined-host.com");
    myClient.createUser(determinedBasePathUri, userDto);

这将发送POST请求到https://my-determined-host.com/create(源(。

feign可以在运行时提供动态URL和端点。

必须遵循以下步骤:

  1. FeignClient接口中,我们必须删除URL参数。我们必须使用@RequestLine注释来提及其余方法(获取,放置,发布等(:

    @FeignClient(name="customerProfileAdapter")
    public interface CustomerProfileAdaptor {
        // @RequestMapping(method=RequestMethod.GET, value="/get_all")
        @RequestLine("GET")
        public List<Customer> getAllCustomers(URI baseUri); 
     
        // @RequestMapping(method=RequestMethod.POST, value="/add")
        @RequestLine("POST")
        public ResponseEntity<CustomerProfileResponse> addCustomer(URI baseUri, Customer customer);
     
        @RequestLine("DELETE")
        public ResponseEntity<CustomerProfileResponse> deleteCustomer(URI baseUri, String mobile);
    }
    
  1. 在RestController中,您必须导入FeignClientConfiguration
  2. 您必须用编码器和解码器作为参数编写一个RestController构造函数。
  3. 您需要使用编码器,解码器构建FeignClient
  4. 在调用FeignClient方法时,请提供URI(baserurl 端点(以及REST调用参数(如果有(。

    @RestController
    @Import(FeignClientsConfiguration.class)
    public class FeignDemoController {
    
        CustomerProfileAdaptor customerProfileAdaptor;
    
        @Autowired
        public FeignDemoController(Decoder decoder, Encoder encoder) {
            customerProfileAdaptor = Feign.builder().encoder(encoder).decoder(decoder) 
               .target(Target.EmptyTarget.create(CustomerProfileAdaptor.class));
        }
    
        @RequestMapping(value = "/get_all", method = RequestMethod.GET)
        public List<Customer> getAllCustomers() throws URISyntaxException {
            return customerProfileAdaptor
                .getAllCustomers(new URI("http://localhost:8090/customer-profile/get_all"));
        }
    
        @RequestMapping(value = "/add", method = RequestMethod.POST)
        public ResponseEntity<CustomerProfileResponse> addCustomer(@RequestBody Customer customer) 
                throws URISyntaxException {
            return customerProfileAdaptor
                .addCustomer(new URI("http://localhost:8090/customer-profile/add"), customer);
        }
    
        @RequestMapping(value = "/delete", method = RequestMethod.POST)
        public ResponseEntity<CustomerProfileResponse> deleteCustomer(@RequestBody String mobile)
                throws URISyntaxException {
            return customerProfileAdaptor
                .deleteCustomer(new URI("http://localhost:8090/customer-profile/delete"), mobile);
        }
    }

我不知道您是否使用Spring取决于多个配置文件。例如:喜欢(开发,beta,prod等(

如果您取决于不同的YML或属性。您可以定义FeignClient,例如:( @FeignClient(url = "${feign.client.url.TestUrl}", configuration = FeignConf.class)(

然后

定义

feign:
  client:
    url:
      TestUrl: http://dev:dev

在您的application-dev.yml

定义

feign:
  client:
    url:
      TestUrl: http://beta:beta

在您的application-beta.yml中(我更喜欢yml(。

......

谢谢上帝。

使用feign.target.emptytarget

@Bean
public BotRemoteClient botRemoteClient(){
    return Feign.builder().target(Target.EmptyTarget.create(BotRemoteClient.class));
}
public interface BotRemoteClient {
    @RequestLine("POST /message")
    @Headers("Content-Type: application/json")
    BotMessageRs sendMessage(URI url, BotMessageRq message);
}
botRemoteClient.sendMessage(new URI("http://google.com"), rq)

您可以手动创建客户端:

@Import(FeignClientsConfiguration.class)
class FooController {
    private FooClient fooClient;
    private FooClient adminClient;
    @Autowired
    public FooController(ResponseEntityDecoder decoder, SpringEncoder encoder, Client client) {
        this.fooClient = Feign.builder().client(client)
            .encoder(encoder)
            .decoder(decoder)
            .requestInterceptor(new BasicAuthRequestInterceptor("user", "user"))
            .target(FooClient.class, "http://PROD-SVC");
        this.adminClient = Feign.builder().client(client)
            .encoder(encoder)
            .decoder(decoder)
            .requestInterceptor(new BasicAuthRequestInterceptor("admin", "admin"))
            .target(FooClient.class, "http://PROD-SVC");
     }
}

来自文档:https://cloud.spring.io/spring-cloud-netflix/multi/multi_spring-cloud-cloud-feign.html#_creating_feign_feign_feign_feign_feign_clients_meraly

接口中您可以通过弹簧注释更改URL。基本URI以YML Spring配置配置。

   @FeignClient(
            name = "some.client",
            url = "${some.serviceUrl:}",
            configuration = FeignClientConfiguration.class
    )
public interface SomeClient {
    @GetMapping("/metadata/search")
    String search(@RequestBody SearchCriteria criteria);
    @GetMapping("/files/{id}")
    StreamingResponseBody downloadFileById(@PathVariable("id") UUID id);
}

一种简单的方法是使用interceptor:requestInterceptor

假装如果您在Interceptor中设置了目标主机:

将替换目标URL。
  // source code of feign
  Request targetRequest(RequestTemplate template) {
    for (RequestInterceptor interceptor : requestInterceptors) {
      interceptor.apply(template);
    }
    return target.apply(template);
  }
  public Request apply(RequestTemplate input) {
    if (input.url().indexOf("http") != 0) {
      input.target(url());
    }
    return input.request();
  }

自定义拦截器:

public class DynamicFeignUrlInterceptor implements RequestInterceptor {
    @Override
    public void apply(RequestTemplate template) {
        if (isNotDynamicPath(template)) {
            return;
        }
        template.target(getHost());
    }
    private boolean isNotDynamicPath(RequestTemplate template) {
        // TODO Determine whether it is dynamic according to your logic
        return false;
    }
    private String getHost() {
        // use any host you want, host must be contained key word of 'http' 
        return "http://example.com";
    }
}

这样的优点是,如果已经有大量的假端代码,则可以在不修改代码的情况下实现。

@Service    
@FeignClient(name = "otherservicename", decode404 = true)    
public interface myService {
@RequestMapping(method = RequestMethod.POST, value = "/basepath/{request-path}")
ResponseEntity<String> getResult(@RequestHeader("Authorization") String token,
                                                      @RequestBody HashMap<String, String> reqBody,
                                                      @PathVariable(value = "request-path") String requestPath);
}

然后从服务中,构建动态URL路径并发送请求:

String requestPath = "approve-req";
ResponseEntity<String> responseEntity = myService.getResult(
                token, reqBody, requestPath);

您的请求URL将在:&quot; basepath/onerve-req&quot;

我更喜欢通过配置来构建假装客户端以在运行时传递URL(在我的情况下,我从领事发现服务中获得服务名称(

所以我将假装目标类扩展如下:

public class DynamicTarget<T> implements Target<T> {
private final CustomLoadBalancer loadBalancer;
private final String serviceId;
private final Class<T> type;
public DynamicTarget(String serviceId, Class<T> type, CustomLoadBalancer loadBalancer) {
    this.loadBalancer = loadBalancer;
    this.serviceId = serviceId;
    this.type = type;
}
@Override
public Class<T> type() {
    return type;
}
@Override
public String name() {
    return serviceId;
}
@Override
public String url() {
    return loadBalancer.getServiceUrl(name());
}
@Override
public Request apply(RequestTemplate requestTemplate) {
    requestTemplate.target(url());
    return requestTemplate.request();
}
}

 var target = new DynamicTarget<>(Services.service_id, ExamsAdapter.class, loadBalancer);
                package commxx;
                import java.net.URI;
                import java.net.URISyntaxException;
                import feign.Client;
                import feign.Feign;
                import feign.RequestLine;
                import feign.Retryer;
                import feign.Target;
                import feign.codec.Encoder;
                import feign.codec.Encoder.Default;
                import feign.codec.StringDecoder;
                public class FeignTest {
                    public interface someItfs {
                 
                        @RequestLine("GET")
                        String getx(URI baseUri);
                    }
                    public static void main(String[] args) throws URISyntaxException {
                        String url = "http://www.baidu.com/s?wd=ddd";  //ok..
                        someItfs someItfs1 = Feign.builder()
                                // .logger(new FeignInfoLogger()) // 自定义日志类,继承 feign.Logger
                                // .logLevel(Logger.Level.BASIC)// 日志级别
                                // Default(long period, long maxPeriod, int maxAttempts)
                                .client(new Client.Default(null, null))// 默认 http
                                .retryer(new Retryer.Default(5000, 5000, 1))// 5s超时,仅1次重试
                            //  .encoder(Encoder)
                            //  .decoder(new StringDecoder())
                                .target(Target.EmptyTarget.create(someItfs.class));
                //       String url = "http://localhost:9104/";
                //         
                        System.out.println(someItfs1.getx(new URI(url)));
                    }
                }

相关内容

  • 没有找到相关文章

最新更新