Feign:REST Client for SpringCloud

In the Spring Cloud cluster, communication between roles is based on REST services. When invoking services, you need to use a REST client, which is commonly used. In addition to using the RestTemplate that Spring comes with, you can also use another REST client: Feign.

When using Feign, you can decorate the interface with your own or third-party annotations to give it access to Web Service s.
Feign also supports plug-in encoders and decoders that encapsulate and parse requests and responses differently.
Spring Cloud integrates Feign into Netflix projects, and when integrated with Eureka and Ribbon, Feign has load balancing capabilities.
Examples of Feign's use in the Spring Boot Web project are as follows: Spring Boot 2 Publish and Call REST Services>

The following example is the use of Spring Cloud.
Development Tools: IntelliJ IDEA 2019.2.3

1. Server-side

1. Create Project

Create a new SpringBoot project in IDEA named "spring-feign-server", SpringBoot version selection 2.1.10, check Spring Cloud Discovert ->on the interface of selecting Dependencies
Eureka Server, the pom.xml configuration file created automatically adds the latest stable version dependency of SpringCloud, currently Greenwich.SR3.
The complete content of pom.xml is as follows:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.10.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>spring-feign-server</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>spring-feign-server</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
        <spring-cloud.version>Greenwich.SR3</spring-cloud.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

2. Modify configuration application.yml

Modify the port number to 8761; unregister your own information to the Eureka server and do not grab the registration information from the Eureka server.

server:
  port: 8761
eureka:
  client:
    register-with-eureka: false
    fetch-registry: false

3. Modify the startup class code SpringFeignServerApplication.java

Add comment @EnableEurekaServer

package com.example.springfeignserver;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

@SpringBootApplication
@EnableEurekaServer
public class SpringFeignServerApplication {
    public static void main(String[] args) {
        SpringApplication.run(SpringFeignServerApplication.class, args);
    }
}

2. Service Providers

1. Create Project

Create a new SpringBoot project in IDEA, with the exception of the name "spring-feign-provider", as you did above to create the server side.

2. Modify configuration application.yml

spring:
  application:
    name: spring-feign-provider
eureka:
  instance:
    hostname: localhost
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/

3. Add an entity class User.java

package com.example.springfeignprovider;

public class User {
    String name;
    Integer age;

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Integer getAge() {
        return age;
    }
    public void setAge(Integer age) {
        this.age = age;
    }
}

4. Modify the startup class code SpringFeignProviderApplication.java

Add the comment @EnableEurekaClient and @RestController;
Let the class read console input at startup to decide which port to use to start the server;
Add 2 controller methods for testing.

package com.example.springfeignprovider;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.util.Scanner;

@SpringBootApplication
@EnableEurekaClient
@RestController
public class SpringFeignProviderApplication {

    public static void main(String[] args) {
        //SpringApplication.run(SpringFeignProviderApplication.class, args);
        Scanner scan = new Scanner(System.in);
        String port = scan.nextLine();
        new SpringApplicationBuilder(SpringFeignProviderApplication.class).properties("server.port=" + port).run(args);
    }

    @RequestMapping("/hello")
    public String hello(HttpServletRequest request) {
        return "hello world." + request.getServerPort();
    }

    @RequestMapping(value="/user/{name}", produces = MediaType.APPLICATION_JSON_VALUE)
    public User user(@PathVariable String name) {
        User u = new User();
        u.setName(name);
        u.setAge(30);
        return u;
    }
}

3. Service Callers

1. Create Project
Create a new SpringBoot project in IDEA named "spring-feign-invoker", SpringBoot version selection 2.1.10, check Spring Cloud Discovert -> Eureka Server, Spring Cloud Routing -> OpenFeign on the interface of selecting Dependencies.
The complete content of pom.xml is as follows:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.10.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>spring-feign-invoker</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>spring-feign-invoker</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
        <spring-cloud.version>Greenwich.SR3</spring-cloud.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

2. Modify configuration application.yml

server:
  port: 9000
spring:
  application:
    name: spring-feign-invoker
eureka:
  instance:
    hostname: localhost
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/

3. Add an entity class User.java

package com.example.springfeigninvoker;

public class User {
    String name;
    Integer age;

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Integer getAge() {
        return age;
    }
    public void setAge(Integer age) {
        this.age = age;
    }
}

4. Add a client interface UserClient.java

package com.example.springfeigninvoker;

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

//Declare the name of the service invoked
@FeignClient("spring-feign-provider")
public interface UserClient {
    @RequestMapping(method = RequestMethod.GET, value = "/hello")
    String hello();

    @RequestMapping(method = RequestMethod.GET, value = "/user/{name}")
    User getUser(@PathVariable("name") String name);
}

5. Modify the startup class code CloudInvokerApplication.java

Add the comment @EnableEurekaClient and @EnableFeignClients.

package com.example.springfeigninvoker;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.openfeign.EnableFeignClients;

@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
public class SpringFeignInvokerApplication {
    public static void main(String[] args) {
        SpringApplication.run(SpringFeignInvokerApplication.class, args);
    }
}

6. Add Controller InvokerController.java

package com.example.springfeigninvoker;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

@RestController
@Configuration
public class InvokerController {
    @Autowired
    private UserClient userClient;

    @RequestMapping(value = "/invokeHello", method = RequestMethod.GET)
    public String invokeHello(){
        return userClient.hello();
    }

    @RequestMapping(value = "/invokeUser", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
    public String invokeUser(){
        return userClient.getUser("Xiao Ming").getAge().toString();
    }
}

IV. Testing

1. Start the server side.
Browser access http://localhost:8761/, normal
2. Start two service providers by typing 8080 and 8081 in the console, respectively.
(1) Browser access http://localhost:8080/user/Xiaoming
Output: {"name": "Xiaoming", "age":30}
(2) Browser access http://localhost:8081/user/Xiaoqiang
Output: {"name": "Xiaoqiang", "age":30}
3. Start the service caller.
(1) Browsers access http://localhost:9000/invokeHello, and pages display toggling between ports 8080 and 8081 below:
hello world.8080
hello world.8081
(2) Browser access http://localhost:9000/invokeUser, output:
30

Keywords: Java Spring Maven Apache

Added by bigdaddysheikh on Sat, 16 Nov 2019 07:51:47 +0200