Feign的使用示列--呕心沥血之作(1)

文章目录

  • 1、前置
  • 2、GET请求
  • 3、POST请求
  • 4、配置请求头
  • 5、上传文件
  • 6、下载文件
  • 7、Body注解
  • 8、注意点


1、前置

1、这里这是贴出了部分示列代码, 具体代码已经上传到码云: 代码地址
2、本demo采用了feign的继承特性
3、版本: Spring Cloud: Hoxton.SR3、spring-cloud-openfeign: 2.2.2.RELEASE, 服务发现: nacos

2、GET请求

package com.chaim.feignserver.service;

import com.chaim.feignserver.DTO.TestEntity;
import com.chaim.feignserver.util.CommonResult;
import org.springframework.cloud.openfeign.SpringQueryMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

import java.util.Map;

/**
 * @author Chaim
 * @date 2021/4/19 17:06
 */
public interface GetService {
    /**
     * GET 请求无参
     *
     * @return
     */
    @RequestMapping(value = "/get/getNoParameters", method = RequestMethod.GET)
    CommonResult getNoParameters();

    /**
     * GET 请求单参
     *
     * @return
     */
    @RequestMapping(value = "/get/getOneParameter", method = RequestMethod.GET)
    CommonResult getOneParameter(@RequestParam("id") String id);

    /**
     * GET 请求多参, 多参 单个传递
     *
     * @return
     */
    @RequestMapping(value = "/get/getParameters1", method = RequestMethod.GET)
    CommonResult getParameters(@RequestParam("id") String id, @RequestParam("name") String name);

    /**
     * GET 请求多参, 对象方式传递
     *
     * @return
     */
    @RequestMapping(value = "/get/getParameters2", method = RequestMethod.GET)
    CommonResult getParameters2(@RequestParam Map<String, Object> testEntity);

    /**
     * GET 请求多参, 对象方式传递
     *
     * @return
     */
    @RequestMapping(value = "/get/getParameters3", method = RequestMethod.GET)
    CommonResult getParameters3(@SpringQueryMap TestEntity testEntity);

    /**
     * GET 请求多参 + Restful 风格
     *
     * @return
     */
    @RequestMapping(value = "/get/getRestfulParameters/{id}", method = RequestMethod.GET)
    CommonResult getRestfulParameters(@RequestParam(value = "id") String id);
}

package com.chaim.consumerserver.feignclien;

import com.chaim.feignserver.service.GetService;
import org.springframework.cloud.openfeign.FeignClient;

/**
 * 远程 Feign 调用
 *
 * @author Chaim
 * @date 2021/4/19 17:28
 * @FeignClient: 表明是一个 feign 接口. name 微服务的名称
 */
@FeignClient(name = "provider", contextId = "getProvider", path = "get")
public interface GetFeignClient extends GetService {
}

3、POST请求

package com.chaim.feignserver.service;

import com.chaim.feignserver.DTO.TestEntity;
import com.chaim.feignserver.util.CommonResult;
import org.springframework.web.bind.annotation.*;

/**
 * @author Chaim
 * @date 2021/4/19 17:06
 */
public interface PostService {
    /**
     * POST 请求无参
     *
     * @return
     */
    @RequestMapping(value = "/testPost/postNoParameters", method = RequestMethod.POST)
    CommonResult postNoParameters();

    /**
     * POST 请求有参
     *
     * @return
     */
    @RequestMapping(value = "/testPost/postParameters", method = RequestMethod.POST)
    CommonResult postParameters(@RequestBody TestEntity testEntity);

    /**
     * POST 请求有参 + Restful 风格
     *
     * @return
     */
    @RequestMapping(value = "/testPost/postRestfulParameters/{count}", method = RequestMethod.POST)
    CommonResult postRestfulParameters(@RequestBody TestEntity testEntity, @PathVariable("count") String count);

    /**
     * POST 请求有参 + key=value 风格
     *
     * @return
     */
    @RequestMapping(value = "/testPost/postKeyValueParameters", method = RequestMethod.POST)
    CommonResult postKeyValueParameters(@RequestBody TestEntity testEntity, @RequestParam("count") String count);
}

package com.chaim.consumerserver.feignclien;

import com.chaim.feignserver.service.PostService;
import org.springframework.cloud.openfeign.FeignClient;

/**
 * 远程 Feign 调用
 *
 * @author Chaim
 * @date 2021/4/19 17:28
 * @FeignClient: 表明是一个 feign 接口. name 微服务的名称
 */
@FeignClient(name = "${project.feign-prefix}", contextId = "postProvider")
public interface PostFeignClient extends PostService {
}

4、配置请求头

package com.chaim.feignserver.service;

import com.chaim.feignserver.DTO.TestEntity;
import com.chaim.feignserver.util.CommonResult;
import feign.HeaderMap;
import feign.Headers;
import feign.Param;
import feign.RequestLine;
import org.springframework.cloud.openfeign.SpringQueryMap;
import org.springframework.web.bind.annotation.RequestBody;

import java.util.Map;

/**
 * @author Chaim
 * @date 2021/4/19 20:38
 */
public interface HeaderServer {
    /**
     * GET 请求多参, 携带头部
     *
     * @param data
     * @param headerMap
     * @return
     */
    @RequestLine("GET /testHeard/getHeard")
    CommonResult getHeard(@SpringQueryMap TestEntity data, @HeaderMap Map<String, Object> headerMap);

    /**
     * POST 请求多参, 携带头部
     *
     * @param data
     * @param authorization
     * @return
     */
    @RequestLine("POST /testHeard/postHeard")
    @Headers({"Content-Type: application/json", "Authorization: {authorization}"})
    CommonResult postHeard(@RequestBody TestEntity data, @Param("authorization") String authorization);
}

package com.chaim.consumerserver.feignclien;

import com.chaim.feignserver.config.FooConfiguration;
import com.chaim.feignserver.service.HeaderService;
import org.springframework.cloud.openfeign.FeignClient;

/**
 * 如果报错: Request method ‘POST‘ not supported
 * 参考: https://blog.csdn.net/qq_38637558/article/details/115913345
 *
 * 当我们将契约改为 feign 原生的默认契约, 就无法使用类似 @RequestMapping 等注解.
 *
 * @author Chaim
 * @date 2021/4/19 20:50
 */
@FeignClient(name = "provider", contextId = "headerProvider", configuration = FooConfiguration.class)
public interface HeaderFeignClient extends HeaderService {
}

package com.chaim.feignserver.config;

import feign.Contract;
import org.springframework.context.annotation.Bean;

/**
 * 详情见 Readme.md
 *
 * @author Chaim
 * @date 2021/4/19 10:59
 */
//@Configurable
public class FooConfiguration {

    /**
     * 将契约改为 feign 原生的默认契约.
     * 可以使用feign自带的注解
     *
     * @return
     */
    @Bean
    public Contract feignContract() {
        return new feign.Contract.Default();
    }

//    /**
//     * 指定日志
//     * @return
//     */
//    @Bean
//    Logger.Level feignLoggerLevel() {
//        return Logger.Level.FULL;
//    }
}

5、上传文件

package com.chaim.feignserver.service;

import com.chaim.feignserver.util.CommonResult;
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.RequestParam;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.multipart.MultipartFile;

/**
 * 上传文件需要注意两点
 * RequestPart(value = "file")
 * consumes = {MediaType.MULTIPART_FORM_DATA_VALUE}
 *
 * @author Chaim
 * @date 2021/4/22 18:23
 */
public interface UploadService {

    @RequestMapping(value = "/upload/postUpload", method = RequestMethod.POST, consumes = {MediaType.MULTIPART_FORM_DATA_VALUE})
    CommonResult postUpload(@RequestPart(value = "file") MultipartFile file,
                          @RequestParam(value = "id") String id);
}

package com.chaim.consumerserver.feignclien;

import com.chaim.feignserver.service.UploadService;
import org.springframework.cloud.openfeign.FeignClient;

/**
 * @author Chaim
 * @date 2021/4/22 18:30
 */
@FeignClient(name = "provider", contextId = "uploadProvider")
public interface UploadFeignClient extends UploadService {
}

6、下载文件

package com.chaim.feignserver.service;

import feign.Response;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

/**
 * @author Chaim
 * @date 2021/4/22 20:35
 */
public interface DownloadService {

    @RequestMapping(value = "/download/postDownload", method = RequestMethod.POST)
    Response postDownload();
}

package com.chaim.consumerserver.feignclien;

import com.chaim.feignserver.service.DownloadService;
import org.springframework.cloud.openfeign.FeignClient;

/**
 * 远程 Feign 调用
 *
 * @author Chaim
 * @date 2021/4/19 17:28
 * @FeignClient: 表明是一个 feign 接口. name 微服务的名称
 */
@FeignClient(name = "provider", contextId = "downloadProvider")
public interface DownloadFeignClient extends DownloadService {
}

7、Body注解

package com.chaim.feignserver.service;

import com.chaim.feignserver.DTO.TestEntity;
import com.chaim.feignserver.util.CommonResult;
import feign.*;

/**
 * @author Chaim
 * @date 2021/4/25 19:53
 */
public interface BodyService {

    /**
     * BODY POST 请求 JSON 格式
     * {}需转义: { == %7B , } == %7D
     * 必须指定@Headers, 请求参数个格式
     *
     * @param id
     * @param name
     * @return
     */
    @RequestLine("POST /testBody/postJSONBody")
    @Headers("Content-Type: application/json")
    @Body("%7B\"id\": \"{id}\", \"name\": \"{name}\"%7D")
    CommonResult postJSONBody(@Param("id") String id, @Param("name") String name);

    /**
     * BODY POST 请求 JSONString 格式
     *
     * @param testJSONString
     * @return
     */
    @RequestLine("POST /testBody/postJSONBody")
    @Headers("Content-Type: application/json")
    @Body("{testJSONString}")
    CommonResult postJSONStringBody(@Param("testJSONString") String testJSONString);

    /**
     * BODY POST 请求 JSONString 格式 + Restful 风格
     *
     * @param testJSONString
     * @param count
     * @return
     */
    @RequestLine("POST /testBody/jsonRestfulBody/{count}")
    @Headers("Content-Type: application/json")
    @Body("{testJSONString}")
    CommonResult jsonRestfulBody(@Param("testJSONString") String testJSONString, @Param(value = "count") String count);

    /**
     * BODY POST 请求 JSONString 格式 + key=value 风格
     *
     * @param testJSONString
     * @param testEntity
     * @return
     */
    @RequestLine("POST /testBody/postKeyValueParametersBody")
    @Headers("Content-Type: application/json")
    @Body("{testJSONString}")
    CommonResult postKeyValueParametersBody(@Param("testJSONString") String testJSONString, @QueryMap TestEntity testEntity);
}

package com.chaim.consumerserver.feignclien;

import com.chaim.feignserver.config.FooConfiguration;
import com.chaim.feignserver.service.BodyService;
import org.springframework.cloud.openfeign.FeignClient;

/**
 * 如果报错: Request method ‘POST‘ not supported
 * 参考: https://blog.csdn.net/qq_38637558/article/details/115913345
 * <p>
 * 当我们将契约改为 feign 原生的默认契约, 就无法使用类似 @RequestMapping 等注解.
 *
 * @author Chaim
 * @date 2021/4/19 20:50
 */
@FeignClient(name = "provider", contextId = "bodyProvider", configuration = FooConfiguration.class)
public interface BodyFeignClient extends BodyService {
}

8、注意点

1、呕心沥血之作, 这里只是罗列了几种方法, 具体的实现, 大概可以到查看我上传的代码, 都有详细的说明

2、代码中涉及到的一些问题, 已经在注释中, 以及MD文件中进行了说明, 大家可以将代码下载下来进行查看

3、代码地址: https://gitee.com/xmaxm/test-code

4、因为我是采用的继承的特性, 虽然官方有明确的说明, 不推荐使用这种方法, 但是这种方法真的很香, 故@FeignClient注解都在对应的实现类, 大家可以下载代码查看, 很详细

5、openfeign对应的其余文章:

代码地址以及对应的postman文件
Feign的使用示列–呕心沥血之作(1)
Feign的@FeignClient详解–呕心沥血之作(2)
Feign的默认契约注解详解–呕心沥血之作(3)
Feign异常–Request method ‘POST‘ not supported
Feign异常–A bean with that name | HTTP method type (ex. GET, POST)

你可能感兴趣的:(Spring,Cloud,+,Nacos,java,spring,feign,openfeign,spring,cloud)