使用Feign封装HTTP请求代码实例

一、总体说明

现在的Web后端基本上都是采用微服务架构,服务间交互走http协议,通过restful接口。调用restful接口的方式很多,有用httpclient、RestTemplate, 使用第三组件如CXF。下面介绍使用第三件Feign做http请求客户端封装。

不论采用哪种方式,都是为了使http接口请求native化–让客户端代码像调用本地接口那样调用远程接口。

二、服务端发布restful接口

1、定义接口中使用的模型User

package com.elon.feign.client.model;

import lombok.Data;
import java.io.Serializable;

@Data
public class User implements Serializable {

    private static final long serialVersionUID = -5699625542142109964L;

    private int id = -1;

    private String name = "";

    private int age = 0;
}

2、发布Rest接口

package com.elon.feign.server.rest;

import com.elon.feign.server.model.User;
import org.springframework.web.bind.annotation.*;

import java.io.UnsupportedEncodingException;

/**
 * 用于测试feign的rest接口定义。
 */
@RestController
@RequestMapping("/v1/feign-server")
public class FeignServerController {

    /**
     * 根据ID查询用户
     * @param id ID
     * @return 用户信息
     */
    @GetMapping("/user/{id}")
    public User queryUserById(@PathVariable("id") int id) {
        System.out.println("id:" + id);

        User user = new User();
        user.setId(id);
        return user;
    }

    /**
     * 根据名称查询用户
     * @param name 名称
     * @return 用户信息
     */
    @GetMapping("/user/query-by-name")
    public User queryUserByName(@RequestParam("name") String name) {
        System.out.println("name:" + name);
        User user = new User();
        user.setName(name);
        return user;
    }

    /**
     * 修改用户信息
     * @param name 姓名
     * @param age 年龄
     * @param id 用户ID
     * @return 用户信息
     */
    @PostMapping("/user/update-user/{id}")
    public User updateUserInfo(@RequestHeader("name") String name, @RequestHeader("age") int age,
                               @PathVariable("id") int id){

        // header 是8859编码,不做转码的话,中文会乱码
        try {
            name = new String(name.getBytes("ISO-8859-1"), "utf8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

        System.out.println("id:" + id + "|name:" + name + "|age:" + age);
        User user = new User();
        user.setId(id);
        user.setName(name);
        user.setAge(age);
        return user;
    }

    /**
     * 添加用户
     * @param user 用户信息
     * @return 处理结果
     */
    @PutMapping(value = "/user")
    public boolean addUser(@RequestBody User user){
        System.out.println("user:" + user);
        return true;
    }

    /**
     * 删除用户。
     * @param userId 用户ID
     * @return 处理结果
     */
    @DeleteMapping("/user/{userId}")
    public boolean deleteUser(@PathVariable("userId") int userId) {
        System.out.println("Delete user. userId:" + userId);
        return true;
    }
}

三、客户端调用代码

1、在pom.xml中引入feign的依赖

        <dependency>
            <groupId>com.netflix.feign</groupId>
            <artifactId>feign-jackson</artifactId>
            <version>8.18.0</version>
        </dependency>
        <dependency>
            <groupId>com.netflix.feign</groupId>
            <artifactId>feign-core</artifactId>
            <version>8.18.0</version>
        </dependency>

2、定义代理接口

package com.elon.feign.client;

import com.elon.feign.client.model.User;
import feign.Headers;
import feign.Param;
import feign.RequestLine;

/**
 * 客户端代理接口
 */
@Headers({"content-type: application/json", "accept: application/json"})
public interface ProxyInterface {

    @RequestLine("GET /v1/feign-server/user/{id}")
    User queryUserById(@Param("id") int id);

    @RequestLine("GET /v1/feign-server/user/query-by-name?name={name}")
    User queryUserByName(@Param("name") String name);

    @Headers({"name: {name}", "age: {age}"})
    @RequestLine("POST /v1/feign-server/user/update-user/{id}")
    User updateUserInfo(@Param("name") String name, @Param("age") int age, @Param("id") int id);

    @RequestLine("PUT /v1/feign-server/user")
    boolean addUser(User user);

    @RequestLine("DELETE /v1/feign-server/user/{userId}")
    boolean deleteUser(@Param("userId") int userId);
}


上面的样例代码中包含了常见的GET、POST、PUT、DELETE请求,参数也包含Path参数、Query参数、Header参数和Body参数。需要注意的是addUser接口使用了自定义的User对象做参数,指定使用json格式传输。

3、写测试代码调用接口

package com.elon.feign.client;

import com.elon.feign.client.model.User;
import feign.Feign;
import feign.jackson.JacksonDecoder;
import feign.jackson.JacksonEncoder;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class FeignClientApplication {
    public static void main(String[] args) {
        SpringApplication.run(FeignClientApplication.class);
        System.out.println("Start up Feign client success!");

        ProxyInterface proxyInterface = buildInterfaceInstance(ProxyInterface.class,
                "http://localhost:10001/feignserver/");

        User user = proxyInterface.queryUserById(123);
        System.out.println("GET请求&&path参数:" + user);

        User user2 = proxyInterface.queryUserByName("张三");
        System.out.println("GET请求&&query参数:" + user2);

        User user3 = proxyInterface.updateUserInfo("李四", 25, 100);
        System.out.println("POST请求&&header参数:" + user3);

        User user4 = new User();
        user4.setId(10001);
        user4.setName("王五");
        user4.setAge(30);
        boolean result = proxyInterface.addUser(user4);
        System.out.println("PUT请求&&Body参数:" + result);

        boolean result2 = proxyInterface.deleteUser(9999);
        System.out.println("DELETE请求&&Path参数:" + result2);
    }

    private static <T> T buildInterfaceInstance(Class<T> type, String url) {
        return Feign.builder().encoder(new JacksonEncoder()).decoder(new JacksonDecoder())
                .target(type, url);
    }
}

调用接口前先构建代理接口实例, 传入的Url需要包含到context-path。

发布了113 篇原创文章 · 获赞 183 · 访问量 29万+

猜你喜欢

转载自blog.csdn.net/ylforever/article/details/92391761