springboot项目中使用Feign调用远程服务
Spring Cloud Feign基于Netflix Feign实现,整合了Spring Cloud Riggon与Spring Cloud Hystrix,提供这两者的强大功能外,还提供了一种声明式的Web服务客户端定义方式。
创建feign 消费端项目
springcloud-feign-comsumer-demo
启动类添加@EnableFeignClients
@SpringBootApplication@EnableEurekaClient
@EnableFeignClients
public class FeignComsumerApplication {
public static void main(String[] args) {
SpringApplication.run(FeignComsumerApplication.class, args);
}
}
添加依赖包
<dependency> <groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
<version>2.2.2.RELEASE</version>
</dependency>
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-okhttp</artifactId>
<version>11.0</version>
</dependency>
添加配置项application.properties
feign.hystrix.enabled=truefeign.compression.request.enabled=true
feign.compression.request.mime-types=["text/xml","application/xml","application/json"]
feign.compression.request.min-request-size=2048
feign.compression.response.enabled=true
feign.client.config.default.logger-level=basic
feign.client.config.feign-provider-demo1.logger-level=full
创建feign配置类
import com.alibaba.fastjson.serializer.SerializerFeature;import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import feign.*;
import feign.codec.Decoder;
import feign.codec.Encoder;
import okhttp3.ConnectionPool;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
import org.springframework.cloud.openfeign.FeignAutoConfiguration;
import org.springframework.cloud.openfeign.support.ResponseEntityDecoder;
import org.springframework.cloud.openfeign.support.SpringDecoder;
import org.springframework.cloud.openfeign.support.SpringEncoder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
@Configuration
@ConditionalOnClass(Feign.class)
@AutoConfigureBefore(FeignAutoConfiguration.class)
public class FeignConfig {
/**
* 设置 Eureka Server的访问的用户名和密码
*
* @return
*/
/*@Bean
public BasicAuthRequestInterceptor basicAuthRequestInterceptor() {
return new BasicAuthRequestInterceptor("admin","admin123");
}*/
@Bean
public okhttp3.OkHttpClient okHttpClient(){
return new okhttp3.OkHttpClient.Builder()
.readTimeout(60, TimeUnit.SECONDS)
.connectTimeout(60, TimeUnit.SECONDS)
.writeTimeout(120, TimeUnit.SECONDS)
.connectionPool(new ConnectionPool())
.build();
}
@Bean
public Feign.Builder feignBuilder() {
return Feign.builder();
}
@Bean
public Contract feignContract() {
return new feign.Contract.Default();
}
@Bean
public Logger.Level feignLoggerLevel() {
return Logger.Level.FULL;
}
@Bean
public Request.Options feignRequestOptions() {
return new Request.Options(10000, 60000);
}
@Bean
public Retryer feignRetry() {
return new Retryer.Default();
}
@Bean
public ResponseEntityDecoder feignDecoder() {
ObjectFactory<HttpMessageConverters> objectFactory = () -> new HttpMessageConverters(this.createFastJsonConverter());
return new ResponseEntityDecoder(new SpringDecoder(objectFactory));
}
@Bean
public SpringEncoder feignEncoder(){
ObjectFactory<HttpMessageConverters> objectFactory = () -> new HttpMessageConverters(this.createFastJsonConverter());
return new SpringEncoder(objectFactory);
}
private HttpMessageConverter createFastJsonConverter() {
//创建fastJson消息转换器
FastJsonHttpMessageConverter fastConverter = new FastJsonHttpMessageConverter();
//升级最新版本需加=============================================================
List<MediaType> supportedMediaTypes = new ArrayList<>();
supportedMediaTypes.add(MediaType.APPLICATION_JSON);
supportedMediaTypes.add(MediaType.APPLICATION_PROBLEM_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);
fastConverter.setSupportedMediaTypes(supportedMediaTypes);
//创建配置类
FastJsonConfig fastJsonConfig = new FastJsonConfig();
//修改配置返回内容的过滤
//WriteNullListAsEmpty :List字段如果为null,输出为[],而非null
//WriteNullStringAsEmpty : 字符类型字段如果为null,输出为"",而非null
//DisableCircularReferenceDetect :消除对同一对象循环引用的问题,默认为false(如果不配置有可能会进入死循环)
//WriteNullBooleanAsFalse:Boolean字段如果为null,输出为false,而非null
//WriteMapNullValue:是否输出值为null的字段,默认为false
fastJsonConfig.setSerializerFeatures(
SerializerFeature.DisableCircularReferenceDetect,
SerializerFeature.WriteMapNullValue
);
fastConverter.setFastJsonConfig(fastJsonConfig);
return fastConverter;
}
//=======================================================
/*
@Bean
public Decoder feignDecoder() {
HttpMessageConverter jacksonConverter = new MappingJackson2HttpMessageConverter(customObjectMapper());
ObjectFactory<HttpMessageConverters> objectFactory = () -> new HttpMessageConverters(jacksonConverter);
return new ResponseEntityDecoder(new SpringDecoder(objectFactory));
}
@Bean
public Encoder feignEncoder(){
HttpMessageConverter jacksonConverter = new MappingJackson2HttpMessageConverter(customObjectMapper());
ObjectFactory<HttpMessageConverters> objectFactory = () -> new HttpMessageConverters(jacksonConverter);
return new SpringEncoder(objectFactory);
}
*/
private ObjectMapper customObjectMapper(){
ObjectMapper objectMapper = new ObjectMapper();
//Customize as much as you want
objectMapper.configure(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT, true);
return objectMapper;
}
}
创建Feign调用远程Api
@FeignClient(name = "SERVICE-PROVIDER-API-DEMO1", url = "http://localhost:8077",
configuration = FeignConfig.class,
fallback = DemoFeignApiFallback.class)
public interface DemoFeignApi {
@Headers(value={"Content-type:application/json;charset=UTF-8"})
@RequestLine(value = "POST /feign/provider/user/save")
@ResponseBody
String userSave(@RequestBody User user);
@Headers(value={"Content-type:application/json;charset=UTF-8"})
@RequestLine(value = "GET /feign/provider/user/{id}")
@ResponseBody
String getUserById(@Param("id") Integer id);
}
public class DemoFeignApiFallback implements DemoFeignApi {
@Override
public String userSave(User user) {
return null;
}
@Override
public String getUserById(Integer id) {
return null;
}
}
创建unit test测试类
@SpringBootTest(classes =FeignComsumerApplication.class)public class FeignDemoApplicationTests {
@Autowired
DemoFeignApi feignApi;
@Test
public void userSave() {
System.out.println(">>>>>>>>>>userSave");
String resp = feignApi.userSave(new User(1, "qwer", "12456", new Date()));
System.out.println(">>>>>>>>>>resp: {}" + resp);
}
@Test
public void getUserById() {
System.out.println(">>>>>>>>>>getUserById");
String resp = feignApi.getUserById(1);
System.out.println(">>>>>>>>>>resp: {}" + resp);
}
}
测试结果
启动服务提供端后,执行测试,结果如下
以上是 springboot项目中使用Feign调用远程服务 的全部内容, 来源链接: utcz.com/z/515887.html