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();
}