/*************** 1、pom引入openfeign**********************/
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
/*************** 2、定义FeignConfig配置文件及类**********************/
feign:
opion:
connectTimeoutMillis: 30000
readTimeoutMillis: 30000
retry:
period: 5000
maxPeriod: 5000
maxAttempts: 3
url.xx: http://10.10.10.1:8088/
@Configuration
@Data
public class FeignConfig {
@Value("${feign.opion.connectTimeoutMillis}")
private int opionConn;
@Value("${feign.opion.readTimeoutMillis}")
private int opionRead;
@Value("${feign.retry.period}")
private long retryPeriod;
@Value("${feign.retry.maxPeriod}")
private long retryMaxPeriod;
@Value("${feign.retry.maxAttempts}")
private int retryMaxAttempts;
}
/*************** 3、定义FeignConfig用fastjson编解码**********************/
/**
* Feign client编解码定义
*/
@Configuration
public class FastJsonConverterConfig {
@Bean(name = "feignDecoder")
public ResponseEntityDecoder feignDecoder() {
HttpMessageConverter fastJsonConverter = getFastJsonConverter();
ObjectFactory<HttpMessageConverters> objectFactory = () -> new HttpMessageConverters(fastJsonConverter);
return new ResponseEntityDecoder(new SpringDecoder(objectFactory));
}
@Bean(name = "feignEncoder")
public SpringEncoder feignEncoder(){
HttpMessageConverter fastJsonConverter = getFastJsonConverter();
ObjectFactory<HttpMessageConverters> objectFactory = () -> new HttpMessageConverters(fastJsonConverter);
return new SpringEncoder(objectFactory);
}
private FastJsonHttpMessageConverter getFastJsonConverter() {
FastJsonHttpMessageConverter converter =
new FastJsonHttpMessageConverter();
List<MediaType> supportedMediaTypes = new ArrayList<>();
supportedMediaTypes.add(MediaType.APPLICATION_JSON);
supportedMediaTypes.add(MediaType.APPLICATION_JSON_UTF8);
supportedMediaTypes.add(MediaType.APPLICATION_ATOM_XML);
supportedMediaTypes.add(MediaType.APPLICATION_FORM_URLENCODED);
supportedMediaTypes.add(MediaType.APPLICATION_OCTET_STREAM);
supportedMediaTypes.add(MediaType.APPLICATION_PDF);
supportedMediaTypes.add(MediaType.APPLICATION_RSS_XML);
supportedMediaTypes.add(MediaType.APPLICATION_XHTML_XML);
supportedMediaTypes.add(MediaType.APPLICATION_XML);
supportedMediaTypes.add(MediaType.IMAGE_GIF);
supportedMediaTypes.add(MediaType.IMAGE_JPEG);
supportedMediaTypes.add(MediaType.IMAGE_PNG);
supportedMediaTypes.add(MediaType.TEXT_EVENT_STREAM);
supportedMediaTypes.add(MediaType.TEXT_HTML);
supportedMediaTypes.add(MediaType.TEXT_MARKDOWN);
supportedMediaTypes.add(MediaType.TEXT_PLAIN);
supportedMediaTypes.add(MediaType.TEXT_XML);
converter.setSupportedMediaTypes(supportedMediaTypes);
FastJsonConfig config = new FastJsonConfig();
//修改配置返回内容的过滤
//WriteNullListAsEmpty :List字段如果为null,输出为[],而非null
//WriteNullStringAsEmpty : 字符类型字段如果为null,输出为"",而非null
//DisableCircularReferenceDetect :消除对同一对象循环引用的问题,默认为false(如果不配置有可能会进入死循环)
//WriteNullBooleanAsFalse:Boolean字段如果为null,输出为false,而非null
//WriteMapNullValue:是否输出值为null的字段,默认为false
config.setSerializerFeatures(
SerializerFeature.DisableCircularReferenceDetect,
SerializerFeature.WriteMapNullValue
);
converter.setFastJsonConfig(config);
return converter;
}
}
/*************** 4、定义FeignConfig用动态Build基类**********************/
@Component
@Import(FeignClientsConfiguration.class)
public class BaseScheduled {
@Autowired
public FeignConfig feignConfig;
@Resource(name = "feignDecoder")
public ResponseEntityDecoder decoder;
@Resource(name = "feignEncoder")
public SpringEncoder encoder;
protected Feign.Builder getFeignBuilder() {
Feign.Builder builder = Feign.builder();
// // 设置http basic验证
// builder = builder.contract(new feign.Contract.Default()).requestInterceptor(
// new BasicAuthRequestInterceptor(feignBean.getAdminName(), feignBean.getAdminPassword()));
builder = builder
// .logger(new Slf4jLogger())
.logLevel(Logger.Level.FULL);
// 【3】设置编码,不然会报错feign.codec.EncodeException
builder = builder.encoder(encoder)
.decoder(decoder);
// options方法指定连接超时时长及响应超时时长,retryer方法指定重试策略
builder = builder.options(new Request.Options(feignConfig.getOpionConn(), feignConfig.getOpionRead()))
.retryer(new Retryer.Default(feignConfig.getRetryPeriod(), feignConfig.getRetryMaxPeriod(),
feignConfig.getRetryMaxAttempts()));
return builder;
}
}
/*************** 5、定义FeignConfig接口**********************/
//参考: https://segmentfault.com/a/1190000018313243
@FeignClient(name = "feign-test")
@Headers("Accept: application/json")
public interface TestFeignClient {
@RequestLine("POST /test")
@Headers("Content-Type: application/json")
boolean test123(String deviceType);
/**
* 注意,header使用'content-type':'application/x-www-form-urlencoded'
*/
@RequestLine("POST /api/test1")
@Headers("Content-Type:"+MediaType.APPLICATION_FORM_URLENCODED_VALUE)
long sendMessage(Map<String, ?> msg);
}
/*************** 6、定义Feign动态服务**********************/
@Service
@Slf4j
public class CmdExctScheduled extends BaseScheduled {
@Value("${feign.url.xx}")
private String xxUrl;
private TestFeignClient testFeignClient;
@PostConstruct
public void init(){
// options方法指定连接超时时长及响应超时时长,retryer方法指定重试策略
Feign.Builder builder = super.getFeignBuilder();
// 【4】 target 链接目标feing,并指定访问域名
testFeignClient = builder.target(TestFeignClient.class, xxUrl);
}
public void test123() {
boolean b = testFeignClient.test123("xxx");
Map<String, Object> req = new HashMap<>();
req.put("action", "2");
long iRet = testFeignClient.sendMessage(req);
}
}
/*************** 7、application入口增加注解**********************/
@EnableFeignClients