1. 回顾
上文讲解了手动创建Feign,比默认的使用更加灵活。
本文将讲解Feign对继承、压缩的支持以及日志和多参数请求的构造等。
2. Feign对继承的支持
Feign支持继承。使用继承,可将一些公共操作分组到一些父接口中,从而简化Feign的开发。
尽管Feign的继承可帮助我们进一步简化开发,但是Spring Cloud指出——通常情况下,
不建议服务器端和客户端之间共享接口,因为这种方式会造成服务器端和客户端代码的紧耦合。
并且,Feign本身并不使用Spring MVC的工作机制(方法参数映射不被继承)。
3. Feign对压缩的支持
在一些场景下,可能需要对请求或响应进行压缩,此时可使用启用Feign的压缩功能。
其中,feign.compression.request.mime-types 用于支持的媒体类型列表,默认是 text/xml,application/xml,application/json
feign.compression.request.min-request-size用于设置请求的最小阈值,默认是2048
4. Feign的日志
很多场景下,需要了解Feign处理请求的具体细节。
Feign对日志的处理非常灵活,可为每个Feign客户端指定日志记录策略,每个Feign客户端都会创建一个logger。
默认情况下,logger的名称是Feign接口的完整类名。需要注意的是,Feign的日志打印只会对DEBUG级别作出响应。
我们可为每个Feign客户端配置各自的Logger.Level对象,告诉Feign记录那些日志。Logger.Level的值有以下选择。
- NONE:不记录任何日志(默认值)
- BASIC:仅记录请求方法、URL、响应状态代码以及执行时间
- HEADERS:记录BASIC级别的基础上,记录请求和响应的header
- FULL:记录请求和响应的header,body和元数据
> 复制项目 microservice-consumer-movie-feign,将 ArtifactId 修改为 microservice-consumer-movie-feign-logging
> 创建Feign配置类
package com.itmuch.cloud.microserviceconsumermoviefeignlogging.config; import feign.Logger; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class FeignLogConfiguration { @Bean Logger.Level feignLoggerLevel() { return Logger.Level.FULL; } }
> 修改Feign的接口,指定其配置类
package com.itmuch.cloud.microserviceconsumermoviefeignlogging.feign; import com.itmuch.cloud.microserviceconsumermoviefeignlogging.config.FeignLogConfiguration; import com.itmuch.cloud.microserviceconsumermoviefeignlogging.pojo.User; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; @FeignClient(name = "microservice-provider-user", configuration = FeignLogConfiguration.class) public interface UserFeignClient { @GetMapping(value = "/{id}") User findById(@PathVariable("id") Long id); }
> 在 application.yml 中添加以下内容,指定Feign接口的日志级别为DEBUG(因为Feign的Logger.Level只对DEBUG级别作出响应)
logging: level: com.itmuch.cloud.microserviceconsumermoviefeignlogging.feign.UserFeignClient: DEBUG # 将Feign接口的日志级别设置为DEBUG,因为Feign的Logger.Level只对DEBUG作出响应
> 启动 microservice-discovery-eureka
> 启动 microservice-provider-user
> 启动 microservice-consumer-movie-feign-logging
> 访问 http://localhost:8010/user/1,可在电影微服务的控制台看见如下内容
5. 使用Feign构造多参数请求
5.1 GET请求多参数的URL
http://localhost:8001/get?id=1&username=张三
> 最直观的方法,URL有几个参数,Feign接口就有几个参数
package com.itmuch.cloud.microserviceconsumermoviefeignlogging.feign; import com.itmuch.cloud.microserviceconsumermoviefeignlogging.config.FeignLogConfiguration; import com.itmuch.cloud.microserviceconsumermoviefeignlogging.pojo.User; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestParam; @FeignClient(name = "microservice-provider-user", configuration = FeignLogConfiguration.class) public interface UserFeignClient { @GetMapping(value = "/get") User findUserByCondi(@RequestParam("id") Long id, @RequestParam("username") String username); }
> 使用 Map 构建。当目标URL参数非常多时,使用Map构建可简化Feign接口的编写
package com.itmuch.cloud.microserviceconsumermoviefeignlogging.feign; import com.itmuch.cloud.microserviceconsumermoviefeignlogging.config.FeignLogConfiguration; import com.itmuch.cloud.microserviceconsumermoviefeignlogging.pojo.User; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestParam; import java.util.Map; @FeignClient(name = "microservice-provider-user", configuration = FeignLogConfiguration.class) public interface UserFeignClient { @GetMapping(value = "/get") User findUserByCondi(@RequestParam Map<String, Object> map); }
5.2 POST请求包含多个参数
package com.itmuch.cloud.microserviceconsumermoviefeignlogging.feign; import com.itmuch.cloud.microserviceconsumermoviefeignlogging.config.FeignLogConfiguration; import com.itmuch.cloud.microserviceconsumermoviefeignlogging.pojo.User; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.*; @FeignClient(name = "microservice-provider-user", configuration = FeignLogConfiguration.class) public interface UserFeignClient { @PostMapping(value = "/post") User findUserByCondi(@RequestBody User user); }