openfeign在单体项目用法
公司项目需要与其他系统对接,常规的httpClient写法,不符合我大道至简的理念,于是研究了一下openfeign,本文只是提供一个思路,具体还需要根据实际场景进行完善。
一、加入依赖
我使用的spring boot 为2.7.9 ,openfeign使用3.1.8,版本匹配不上会导致应用启动时候报错,错误大概意思是配置什么有问题
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> <version>3.1.8</version> </dependency>
二、普通用法
注解上将url参数给上
package com.xx.module.memberinfo.openfeign; import com.xx.module.memberinfo.openfeign.dto.UserInfoDTO; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.stereotype.Service; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; @Service //这里的url一定要给,不然会被当成微服务去请求名为test的服务 @FeignClient(name = "test", url = "http://xxx.com") public interface MemberInfoApi { @GetMapping("/profile") UserInfoDTO getUser(); @GetMapping("/list") List<UserInfoDTO> getUserList(); }
三、自定义用法
给定拦截器配置
1、创建请求拦截器
package com.xx.module.memberinfo.openfeign.interceptor; import feign.RequestInterceptor; import feign.RequestTemplate; public class CommonFeignRequestInterceptor implements RequestInterceptor { @Override public void apply(RequestTemplate requestTemplate) { /*** 自定义request解析逻辑 ***/ requestTemplate.target("http://a.b.com"); //修改请求地址,请求地址可以从配置,缓存,数据库啥的读取 // 这里就是你请求前要进行的各种操作,比如设置一下header 添加点其他料 /*** 自定义request解析逻辑 ***/ } }
2、创建响应拦截器
package com.xx.module.memberinfo.openfeign.interceptor; import com.fasterxml.jackson.databind.ObjectMapper; import feign.FeignException; import feign.Response; import feign.codec.Decoder; import org.apache.commons.io.IOUtils; import java.io.IOException; import java.lang.reflect.Type; import java.nio.charset.StandardCharsets; import java.util.Collection; import java.util.Map; public class CommonFeignResponseInterceptor implements Decoder { private static final ObjectMapper objectMapper = new ObjectMapper(); @Override public Object decode(final Response response, Type type) throws FeignException, IOException { /*** 自定义response解析逻辑 ***/ Map<String, Collection<String>> headers = response.headers(); Response.Body body = response.body(); String bodyString = IOUtils.toString(body.asReader(StandardCharsets.UTF_8)); Object result = objectMapper.readValue(bodyString, objectMapper.constructType(type)); //解开之后这里继续处理逻辑 /*** 自定义response解析逻辑 ***/ return result; } }
3、创建一个配置
package com.xx.module.memberinfo.openfeign.config; import com.xx.module.memberinfo.openfeign.interceptor.CommonFeignResponseInterceptor; import com.xx.module.memberinfo.openfeign.interceptor.CommonFeignRequestInterceptor; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; //@Configuration //这一行如果加了 就对整个openfeign生效,可以根据实际情况添加 public class MemberFeignClientConfiguration { @Bean public CommonFeignRequestInterceptor commonFeignRequestInterceptor(){ return new CommonFeignRequestInterceptor(); } @Bean public CommonFeignResponseInterceptor commonFeignResponseInterceptor(){ return new CommonFeignResponseInterceptor(); } }
4、注解使用
package com.xx.module.memberinfo.openfeign; import com.xx.module.memberinfo.openfeign.dto.UserInfoDTO; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.stereotype.Service; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; @Service @FeignClient(name = "test", url = "http://xx.com", configuration = {MemberFeignClientConfiguration.class}) public interface MemberInfoApi { @GetMapping("/profile") UserInfoDTO getUser(); @GetMapping("/list") List<UserInfoDTO> getUserList(); }
四、一把梭用法
1、前置步骤参考 【自定义用法】的 创建两个拦截器、创建配置文件
新增步骤
2、创建一个注解
package com.xx.module.memberinfo.openfeign.annotations; import com.xx.module.memberinfo.openfeign.config.MemberFeignClientConfiguration; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.core.annotation.AliasFor; import java.lang.annotation.*; @FeignClient @Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface MemberFeignClient { @AliasFor(annotation = FeignClient.class) String name() default "MemberFeignClient"; //todo 务必注意 这个url一定要填一个,后面通过request拦截器再修改 // 不填写的话,openfeign会认为这是微服务模式,会通过name去请求,然后这个单体项目启动就提示没有引入负载均衡依赖 @AliasFor(annotation = FeignClient.class) String url() default "http://localhost"; @AliasFor(annotation = FeignClient.class) String path() default ""; @AliasFor(annotation = FeignClient.class) Class<?>[] configuration() default {MemberFeignClientConfiguration.class}; }
3、注解使用
package com.xx.module.memberinfo.openfeign; import com.xx.module.memberinfo.openfeign.dto.UserInfoDTO; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.stereotype.Service; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; @Service @MemberFeignClient public interface MemberInfoApi { @GetMapping("/profile") UserInfoDTO getUser(); @GetMapping("/list") List<UserInfoDTO> getUserList(); }