问题
@FeignClient(name = "test", url="http://xxxx")
How can I change the feign URL (url="http://xxxx") during the runtime? because the URL can only be determined at run time.
回答1:
Feign has a way to provide the dynamic URLs and endpoints at runtime.
The following steps have to be followed:
- In the
FeignClient
interface we have to remove the URL parameter. We have to use@RequestLine
annotation to mention the REST method (GET, PUT, POST, etc.):
@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);
}
- In RestController you have to import FeignClientConfiguration
- You have to write one RestController constructor with encoder and decoder as parameters.
- You need to build the
FeignClient
with the encoder, decoder. - While calling the
FeignClient
methods, provide the URI (BaserUrl + endpoint) along with rest call parameters if any.
@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);
}
}
回答2:
You can add an unannotated URI parameter (that can potentially be determined at runtime) and that will be the base path that will be used for the request. E.g.:
@FeignClient(name = "dummy-name", url = "https://this-is-a-placeholder.com")
public interface MyClient {
@PostMapping(path = "/create")
UserDto createUser(URI baseUrl, @RequestBody UserDto userDto);
}
And then the usage will be:
@Autowired
private MyClient myClient;
...
URI determinedBasePathUri = URI.create("https://my-determined-host.com");
myClient.createUser(determinedBasePathUri, userDto);
This will send a POST
request to https://my-determined-host.com/create
(source).
回答3:
You can create the client manually:
@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");
}
}
Please see the documentation: https://cloud.spring.io/spring-cloud-netflix/multi/multi_spring-cloud-feign.html#_creating_feign_clients_manually
回答4:
I don`t know if you use spring depend on multiple profile. for example: like(dev,beta,prod and so on)
if your depend on different yml or properties. you can define FeignClient
like:(@FeignClient(url = "${feign.client.url.TestUrl}", configuration = FeignConf.class)
)
then
define
feign:
client:
url:
TestUrl: http://dev:dev
in your application-dev.yml
define
feign:
client:
url:
TestUrl: http://beta:beta
in your application-beta.yml (I prefer yml).
......
thanks god.enjoy.
回答5:
In interface you can change url by Spring annotations. The base URI is configured in yml Spring configuration.
@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);
}
来源:https://stackoverflow.com/questions/43733569/how-can-i-change-the-feign-url-during-the-runtime