栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Spring Cloud Open Feign系列【2】Feign原生注解

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Spring Cloud Open Feign系列【2】Feign原生注解

文章目录
  • 注解介绍
  • 使用案例
    • @RequestLine
      • 概述
      • 案例
    • @Param
      • 概述
    • @Headers
      • 概述
      • 案例
    • @QueryMap
      • 概述
      • 案例
    • @HeaderMap
      • 概述
      • 案例
    • @Body
      • 概述
      • 案例

注解介绍

之前介绍过,Feign 是通过接口+注解的方式声明一个HTTP 请求。

Feign 注解定义了接口和底层客户端应之间该如何工作的关系。Feign 的默认定义了以下注解:

注解作用位置用法
@RequestLine方法为请求定义HttpMethod和UriTemplate。 花括号{expression}中的值使用其相应的带@Param注解的参数解析。
@Param参数定义一个模板变量,其值将用于解析相应的表达式模板,通过作为注解值提供的名称。如果缺少值,它将尝试从字节码方法参数名称中获取名称(如果代码是用-parameters标志编译的)。
@Headers方法、类型定义一个HeaderTemplate。使用带@Param注释的值来解析相应的expressions. 在 Type上使用时,模板将应用于每个请求。
@QueryMap参数范围 定义一个Map名称-值对或 POJO,以扩展为查询字符串。
@HeaderMap参数范围 定义一个Map名称-值对,扩展为Http Headers
@Body方法定义 Template,类似于UriTemplateand、 HeaderTemplate,它使用带@Param注释的值来解析相应的expressions.
使用案例 @RequestLine 概述

RequestLine是请求行的意思,我们知道在HTTP 中,请求行一般由以下几部分构成。

@RequestLine注解只能标注在方法上,为请求定义HttpMethod(请求方式 GET、POST等)和UriTemplate(访问路径),然后可以将@Param注解中表示的参数,解析到表达式{ }对应的位置上。

@RequestLine注解有以下几个配置项,一般我们只需要配置value值就可以了。

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface RequestLine {
	// 请求行的值
    String value();
	// 斜杠转义,默认true
    boolean decodeSlash() default true;
	//  URL参数中编码方式,默认使用 &aa=aabb&bb=bb,不需要改
    CollectionFormat collectionFormat() default CollectionFormat.EXPLODED;
}
案例

接下来我们看下如何使用@RequestLine注解进行传参访问。

首先将接口改为需要一个name参数:

    @GetMapping("/test")
    @ApiOperation(value = "测试接口")
    @ApiOperationSupport(author = "xiaoymin@foxmail.com")
    public String test(String name) {
        return name;
    }

Feign 接口中,定义好请求行,使用@Param注解表示将请求参数赋值给表达式{name}。

public interface TestFeignClient {

    @RequestLine("GET /app1/test?name={name}")
    String test(@Param("name") String name);
}

然后创建客户端并远程访问:

    public static void main(String[] args) {
        // 1. 生成Feign 客户端
        TestFeignClient feignClient = Feign.builder()
                .logger(new Logger.ErrorLogger()).logLevel(Logger.Level.FULL) // 打印所有日志
                .retryer(Retryer.NEVER_RETRY) // 关闭重启
                .target(TestFeignClient.class, "http://127.0.0.1:9001"); // 接口及请求地址
        // 2. 打印结果
        String test = feignClient.test("张三");
        System.out.println(test);
    }

启动该工程,并执行Feign 请求,可以通过日志,看到当前请求的整个过程。

@Param 概述

@Param 只能做用于方法参数上,它的主要作用是,通过变量名,绑定一个参数值,然后可以将参数填充到模板表达式中。

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.PARAMETER, ElementType.FIELD, ElementType.METHOD})
public @interface Param {
	// Key,对应模板表达式中的变量
    String value() default "";
	// 填充方式,默认直接使用ToString方法,
    Class expander() default Param.ToStringExpander.class;
	// 是否转义,默认false
    
    boolean encoded() default false;
	// 内部类填充器  使用ToString方法填充
    public static final class ToStringExpander implements Param.Expander {
        public ToStringExpander() {
        }

        public String expand(Object value) {
            return value.toString();
        }
    }

    public interface Expander {
        String expand(Object var1);
    }
}

在上面的案例中,会将name参数,填充到{name} 表达式中。

    @RequestLine("GET /app1/test?name={name}")
    String test(@Param("name") String name);
@Headers 概述

@Headers可作用于方法或者类上,用于添加请求头。

它的属性很简单,是一个字符串数组。

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface Headers {
	// 请求头
    String[] value();
}
案例

注意添加的时候,消息头键值对使用冒号:分隔。

 @Headers({"Accept:**", "Accept-Language:zh-cn"})
    String testQueryMap(@QueryMap Map map);

可以看到在请求时,将Map中的键值对拼接到了URL后面。

@HeaderMap 概述

@HeaderMap注解只能做用于方法参数上,和@QueryMap差不多,是将Map中的键值对,添加到请求头中。

该注解没有配置项:

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.PARAMETER})
public @interface HeaderMap {
}
案例
    @RequestLine("GET /app1/test")
    String testQueryMap(@HeaderMap Map map);
@Body 概述

@Body 做用于方法上,会使用请求体来传递参数。可以传递字符串、Json数据,在传递Bean 对象时,会调用其toString方法再进行传递。

该注解只有一个属性值,可以写表达式,通过@Param传值。

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Body {
    String value();
}
案例

通过请求体传递一个实体类对象。

    @RequestLine("POST /app1/post")
    @Body("{user}")
    String post(@Param("user") User user);

可以看到在发送请求时,实际传递的是实体类的toString 字符串,如果在接口提供方用对象是接受不到的。。。具体怎么回事,后续会介绍

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/677784.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号