当前位置:网站首页>Implementing declarative rest calls using feign
Implementing declarative rest calls using feign
2022-06-11 10:37:00 【chentian114】
Use Feign Implement declarative REST call
List of articles
Preface
In the foreword 《 Use Ribbon Achieve client load balancing 》https://mp.weixin.qq.com/s/YwwCsUKoUA1UsaarZWVMHw in , Inter service calls use RestTemplate:
User entity = restTemplate.getForObject("http://micro-provider-user/user/v1/"+id, User.class);
From the code , It is mainly constructed by splicing strings URL To make the call , This makes the code difficult to maintain .
Feign brief introduction
Feign yes Netflix Developed declarative 、 templated HTTP client ,Feign Can help us more convenient 、 Call... Gracefully HTTP API .
stay Spring Cloud in , Use Feign It's simple – Create an interface , And add some comments to the interface , The code is done . Feign Support for multiple annotation , for example Feign Own notes or JAX-RS Annotations etc. .
Spring Cloud Yes Feign Enhanced , send Feign Support SpringMVC annotation , And integrated Ribbon and Eureka , So that Feign It is more convenient to use .
Spring Cloud Feign In essence, it is a dynamic agent mechanism , You just give one RESTful API Corresponding Java Interface , It can dynamically assemble the strong type client of the corresponding interface at run time , The simplified structure of the assembled client and the process of request response , Here's the picture :

Although the services we developed are weakly typed RESTful Service for , But because of Spring Cloud Feign Support for , Let's simply give a strongly typed Java API Interface , You automatically get a strongly typed client .
For details of strong / weak type interfaces, see :《 How to base on Spring Cloud Feign Implement strongly typed interface calls RESTful service 》https://mp.weixin.qq.com/s/bYZXhf9BfAfL5aC3bSyiHQ
Integrate for service consumers Feign
Create project , Copy project micro-consumer-movie , take artifactId It is amended as follows micro-consumer-movie-feign .
add to Feign Dependence
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
</dependency>
- Create a Feign Interface , And add
@FeignClientannotation .
@FeignClient(name = "micro-provider-user")
public interface UserFeignClient {
@RequestMapping(value = "/user/v1/{id}", method = RequestMethod.GET)
User findById(@PathVariable("id") Long id);
}
@FeignClient In the annotations micro-provider-user Is an arbitrary client name , be used for Ribbon Load Balancer .
In this case , Due to the use of Eureka , therefore Ribbon Will be able to micro-provider-user It can be interpreted as Eureka Server Services in the service registry .
Of course , If you don't want to use it Eureka You can use service.ribbon.listOfServers Property to configure the server list .
You can also use url Property specifies the requested URL (URL It can be complete URL Or the Lord name ), for example @FeignClient(name = "micro-provider-user", url="http://localhost:8000/")".
- modify Controller Code , Let it call Feign Interface .
@RestController
@RequestMapping("/movie/v1")
public class MovieController {
@Resource
private UserFeignClient userFeignClient;
@GetMapping("/{id}")
public User findById(@PathVariable Long id){
User entity = userFeignClient.findById(id);
return entity;
}
}
- Modify the startup class , To add
@EnableFeignClientsannotation .
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class MicroConsumerMovieFeignApplication {
public static void main(String[] args) {
SpringApplication.run(MicroConsumerMovieFeignApplication.class, args);
}
}
- Start service test . start-up Eureka Server: micro-discovery-eureka 、 Service providers :micro-provider-user 、 Serving consumers :micro-consumer-movie-feign ; visit :http://localhost:8010/movie/v1/1 .
Manually create Feign
In some cases , You can use Feign Builder API Manually create Feign .
For example, the following scenario :
- The user microservice interface can only be called after logging in , And for the same API , Users in different roles have different behaviors .
- Let the movie micro service be the same Feign The interface uses different accounts to log in , And call the user microservice interface .
One 、 Modify the user microservice , Make it accessible only after login and authentication
Create project , Copy project micro-provider-user , take artifactId It is amended as follows micro-provider-user-with-auth .
Add dependencies to the project .
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
- establish Spring Scurity Configuration class
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Resource
private UserDetailsService userDetailsService;
@Bean
public PasswordEncoder passwordEncoder(){
// Plaintext encoder .Spring Provide clear text testing
return NoOpPasswordEncoder.getInstance();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
// All requests , All need to go through HTTP basic authentication
http.authorizeRequests().anyRequest().authenticated().and().httpBasic();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
}
}
@Component
public class CustomUserDetailsService implements UserDetailsService {
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
if("user".equalsIgnoreCase(username)){
return new SecurityUser("user", "password1", "user-role");
} else if("admin".equalsIgnoreCase(username)){
return new SecurityUser("admin", "password2", "admin-role");
} else {
return null;
}
}
}
public class SecurityUser implements UserDetails {
private Long id;
private String username;
private String password;
private String role;
public SecurityUser(String username, String password, String role){
super();
this.username = username;
this.password = password;
this.role = role;
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
Collection<GrantedAuthority> authorities = new ArrayList<>();
SimpleGrantedAuthority authority = new SimpleGrantedAuthority(this.role);
authorities.add(authority);
return authorities;
}
//...
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
}
Simulated two accounts : user and admin , Their passwords are password1 and password2 , The roles are user-role and admin-role .
- modify Controller , Print the currently logged in user information in the log .
@RestController
@RequestMapping("/user/v1")
public class UserController {
private Logger logger = LoggerFactory.getLogger(this.getClass());
@Resource
private UserRepository userRepository;
@GetMapping("/{id}")
public User findById(@PathVariable Long id){
Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
if(principal instanceof UserDetails){
UserDetails user = (UserDetails) principal;
Collection<? extends GrantedAuthority> authorities = user.getAuthorities();
for(GrantedAuthority authority : authorities){
logger.info(" The current user is :{}, The role is :{}", user.getUsername(), authority.getAuthority());
}
}
User entity = userRepository.findOne(id);
return entity;
}
}
- Start service test , start-up Eureka Server: micro-discovery-eureka 、 Service providers :micro-provider-user-auth , Access address : http://localhost:8000/user/v1/1 .
Two 、 Modify the movie microservice , Make it possible to achieve the same Feign The interface uses different accounts to log in
Copy project micro-consumer-movie-feign , modify artifactId by micro-consumer-movie-feign-manual .
Get rid of Feign Interface UserFeignClient Of
@FeignClientannotation .Remove the on the startup class
@EnableFeignClientsannotation .modify Controller as follows :
@Import(FeignClientsConfiguration.class)
@RestController
@RequestMapping("/movie/v1")
public class MovieController {
private UserFeignClient userFeignClient;
private UserFeignClient adminFeignClient;
@Autowired
public MovieController(Decoder decoder, Encoder encoder, Client client, Contract contract){
this.userFeignClient = Feign.builder().client(client).encoder(encoder).decoder(decoder).contract(contract)
.requestInterceptor(new BasicAuthRequestInterceptor("user", "password1"))
.target(UserFeignClient.class, "http://micro-provider-user");
this.adminFeignClient = Feign.builder().client(client).encoder(encoder).decoder(decoder).contract(contract)
.requestInterceptor(new BasicAuthRequestInterceptor("admin", "password2"))
.target(UserFeignClient.class, "http://micro-provider-user");
}
@GetMapping("/user-user/{id}")
public User findByIdUser(@PathVariable Long id){
User entity = userFeignClient.findById(id);
return entity;
}
@GetMapping("/user-admin/{id}")
public User findByIdAdmin(@PathVariable Long id){
User entity = adminFeignClient.findById(id);
return entity;
}
}
among ,@Import Imported FeignClientsConfiguration yes Spring Cloud by Feign The configuration class provided by default .
userFeignClient Login account user, adminFeignClient Login account admin , They use the same interface UserFeignClient .
- Start the test , start-up Eureka Server: micro-discovery-eureka 、 Service providers :micro-provider-user-auth 、 Serving consumers :micro-consumer-movie-feign-manual ; visit http://localhost:8010/movie/v1/user-user/1 and http://localhost:8010/movie/v1/user-admin/1 , see user Logs of services , You can see that different user accounts have been printed .
Code warehouse
https://gitee.com/chentian114/spring-cloud-practice
official account
Reference resources
《Spring Cloud And Docker Microservice architecture practice 》 Zhou Li
边栏推荐
- Install MySQL version 5.7 or above on windows (install in compressed package)
- 在线文件不落地转base64
- Start jar
- Golang compilation and linking parameters, runtime
- 数字藏品app系统源码
- Wsarecv: an existing connection was forcefully closed by the remote host
- Ngui, chat scroll box, UI textlist
- rpc的正确打开方式|读懂Go原生net/rpc包
- 以银行异业合作为例,浅谈小程序生态的建设
- C语言课程设计
猜你喜欢
随机推荐
Unity字体间距
&lt; Pytorch series 4 & gt;: Constructing neural network model
用真金做的电路板——金手指
【DBSCAN】DBSCAN实例
FPGA infrastructure [reference ug998]
NGUI,飘血
Arbitrum infrastructure: a quick start
[machine learning theory] true positive, true negative, false positive, false negative concept
[MySQL] use of stored procedures
Use of JMeter (simulating high concurrency)
1. system in Library
C#入門系列(十一) -- 多維數組
Ngui, map zoom in and out
C # introductory series (11) -- multidimensional array
Streaming computing knowledge
Start jar
NGUI,聊天滚动框,UI TextList
5.读取指定路径名-dirname
Dimension types for different CV tasks
Leetcode 1995. 统计特殊四元组(暴力枚举)






![FPGA infrastructure [reference ug998]](/img/68/7eee191c52029dc140168bdb64b947.png)


