/*************** 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