I've seen the issue https://github.com/spring-cloud/spring-cloud-netflix/issues/1211 and the spring document http://cloud.spring.io/spring-cloud-static/Camden.SR2/#_creating_feign_clients_manually, but when I follow it ,it can never work. WHAT'S WRONG?
Here is my code.
https://github.com/eacdy/spring-cloud-creating-feign-manually
@Import(FeignClientsConfiguration.class)
@RestController
public class MovieController {
private UserFeignClient userUserFeignClient;
private UserFeignClient adminUserFeignClient;
@Autowired
public MovieController(ResponseEntityDecoder decoder, SpringEncoder encoder, Client client) {
this.userUserFeignClient = Feign.builder().client(client).encoder(encoder).decoder(decoder)
.requestInterceptor(new BasicAuthRequestInterceptor("user", "password1")).target(UserFeignClient.class, "http://microservice-provider-user/");
this.adminUserFeignClient = Feign.builder().client(client).encoder(encoder).decoder(decoder)
.requestInterceptor(new BasicAuthRequestInterceptor("admin", "password2"))
.target(UserFeignClient.class, "http://microservice-provider-user/");
}
@GetMapping("/user-user/{id}")
public User findByIdUser(@PathVariable Long id) {
return this.userUserFeignClient.findById(id);
}
@GetMapping("/user-admin/{id}")
public User findByIdAdmin(@PathVariable Long id) {
return this.adminUserFeignClient.findById(id);
}
}
When I start the application, it can never start up. It comes this exception
Description:
Parameter 0 of constructor in com.itmuch.cloud.study.user.controller.MovieController required a bean of type 'org.springframework.cloud.netflix.feign.support.ResponseEntityDecoder' that could not be found.
My Spring Cloud version is Camden.SR2.
The overarching problem is an issue with my example. However I noticed a couple of other issues in your sample.
You don't need @EnableFeignClients
https://github.com/eacdy/spring-cloud-creating-feign-manually/blob/master/microservice-consumer-movie-feign-manual/src/main/java/com/itmuch/cloud/study/ConsumerMovieApplication.java#L10
And your interface should use the Feign annotations not the Spring MVC annotations
package com.itmuch.cloud.study.user.feign;
import feign.Param;
import feign.RequestLine;
import com.itmuch.cloud.study.user.entity.User;
public interface UserFeignClient {
@RequestLine(value = "GET /{id}")
public User findById(@Param("id") Long id);
}
To fix the problem however your RestController constructor should use the interface types for Decoder and Encoder.
package com.itmuch.cloud.study.user.controller;
import feign.Client;
import feign.Feign;
import feign.auth.BasicAuthRequestInterceptor;
import feign.codec.Decoder;
import feign.codec.Encoder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.netflix.feign.FeignClientsConfiguration;
import org.springframework.context.annotation.Import;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import com.itmuch.cloud.study.user.entity.User;
import com.itmuch.cloud.study.user.feign.UserFeignClient;
@RestController
@Import(FeignClientsConfiguration.class)
public class MovieController {
private UserFeignClient userUserFeignClient;
private UserFeignClient adminUserFeignClient;
@Autowired
public MovieController(Decoder decoder, Encoder encoder, Client client) {
this.userUserFeignClient = Feign.builder().client(client).encoder(encoder).decoder(decoder)
.requestInterceptor(new BasicAuthRequestInterceptor("user", "password1")).target(UserFeignClient.class, "http://microservice-provider-user/");
this.adminUserFeignClient = Feign.builder().client(client).encoder(encoder).decoder(decoder)
.requestInterceptor(new BasicAuthRequestInterceptor("admin", "password2"))
.target(UserFeignClient.class, "http://microservice-provider-user/");
}
@GetMapping("/user-user/{id}")
public User findByIdUser(@PathVariable Long id) {
return this.userUserFeignClient.findById(id);
}
@GetMapping("/user-admin/{id}")
public User findByIdAdmin(@PathVariable Long id) {
return this.adminUserFeignClient.findById(id);
}
}
I will update the documentation.
@ryanjbaxter
Thanks for your help, it works.
I鈥榲e pushed the code into my github.
@Import(FeignClientsConfiguration.class)
@RestController
public class MovieController {
private UserFeignClient userUserFeignClient;
private UserFeignClient adminUserFeignClient;
@Autowired
public MovieController(Decoder decoder, Encoder encoder, Client client, Contract contract) {
this.userUserFeignClient = Feign.builder().client(client).encoder(encoder).decoder(decoder).contract(contract)
.requestInterceptor(new BasicAuthRequestInterceptor("user", "password1")).target(UserFeignClient.class, "http://microservice-provider-user/");
this.adminUserFeignClient = Feign.builder().client(client).encoder(encoder).decoder(decoder).contract(contract)
.requestInterceptor(new BasicAuthRequestInterceptor("admin", "password2"))
.target(UserFeignClient.class, "http://microservice-provider-user/");
}
@GetMapping("/user-user/{id}")
public User findByIdUser(@PathVariable Long id) {
return this.userUserFeignClient.findById(id);
}
@GetMapping("/user-admin/{id}")
public User findByIdAdmin(@PathVariable Long id) {
return this.adminUserFeignClient.findById(id);
}
}
And then I can use Spring MVC annotations.
Most helpful comment
@ryanjbaxter
Thanks for your help, it works.
I鈥榲e pushed the code into my github.
And then I can use Spring MVC annotations.