Spring Boot 2关于http接口调用5
使用FeignClient
Feign是一个声明式的Web服务客户端,使用Feign可使得Web服务客户端的写入更加方便。只需要几个注解就可以实现基本的http调用功能,减少了许多重复的代码。这里只介绍其单独使用的场景,跟微服务其他组件的使用不做介绍。
包引用
不同版本需要引入的包不一样,这里spring boot 2引入的是
compile group: ‘org.springframework.cloud’, name: ‘spring-cloud-starter-openfeign’, version: ‘2.0.2.RELEASE’
启用FeignClient
这里需要在入口类使用注解EnableFeignClients
@EnableFeignClients(basePackages = {"org.ghost.springboot2.demo.test.service"})
public class Application {
}
配置文件修改
feign:
httpclient:
enabled: false
okhttp:
enabled: false
compression:
request:
enabled: true
mime-types: text/xml,application/xml,application/json
min-request-size: 2048
response:
enabled: true
hystrix:
enabled: false
定义接口使用注解
@FeignClient(name = "helloApi", url = "http://localhost:9999")
public interface ITestHelloService {
@RequestMapping(value = "demo/hello", method = RequestMethod.GET)
HttpRspDTO<String> getTestHello(@RequestParam(value = " msg") String msg);
@RequestMapping(value = "demo/hello", method = RequestMethod.POST)
HttpRspDTO<String> postTestHello(@RequestBody Map<String, Object> reqBody);
}
其他的RequestMapping等注解都是Spring中的注解。
针对FeignClient里面有很多参数,可以灵活运用
url参数
这里可以写死具体的地址,也可以是动态参数,例如:${serviceClient.config.helloServiceApiPath}
${serviceClient.config.helloServiceApiPath}可以application.yml里面配置的参数
configuration参数
这个参数可以配置一些编解码、拦截、日志等信息,可以继承FeignClientsConfiguration
public class HelloServiceApiConfig extends FeignClientsConfiguration {
@Override
public Feign.Builder feignBuilder(Retryer retryer) {
Feign.Builder builder = super.feignBuilder(retryer);
builder.requestInterceptor(new CommonInterceptor());
return builder;
}
@Override
public Decoder feignDecoder() {
return new JacksonDecoder(JacksonUtil.useDefaultMapper().getMapper());
}
@Override
public Encoder feignEncoder() {
return new JacksonEncoder(JacksonUtil.nonEmptyMapper().getMapper());
}
@Bean
Logger.Level feignLogLevel() {
return Logger.Level.FULL;
}
}
// 自定义拦截器
public class CommonInterceptor implements RequestInterceptor {
@Override
public void apply(RequestTemplate template) {
Map<String, Collection<String>> headerMap = template.headers();
if (MapUtils.isNotEmpty(headerMap) && CollectionUtils.isNotEmpty(headerMap.get("Content-Type"))) {
//
} else {
template.header("Content-Type", "application/json; charset=utf-8");
}
template.header("uuid", UUID.randomUUID().toString());
}
}
单元测试
在入口类使用了EnableFeignClients注解,那么使用了FeignClient注解的接口会自动生成bean。在使用的时候只需要自动注入就可以了。
@RunWith(SpringRunner.class)
@SpringBootTest(classes = Application.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class, DataSourceTransactionManagerAutoConfiguration.class, HibernateJpaAutoConfiguration.class})
@EnableFeignClients(basePackages = {"org.ghost.springboot2.demo.test.service"})
public class FeignTest {
@Autowired
private ITestHelloService testHelloService;
@Test
public void test1() {
long begin = System.currentTimeMillis();
HttpRspDTO<String> rspDTO = testHelloService.getTestHello("这是一条测试数据");
long end = System.currentTimeMillis();
System.out.println("*****消耗时间(秒):" + (end - begin) / 1000.0);
System.out.println(rspDTO);
}
@Test
public void test2() {
long begin = System.currentTimeMillis();
Map<String, Object> paraMap = new HashMap<String, Object>();
paraMap.put("msg", "这是一条测试数据");
HttpRspDTO<String> rspDTO = testHelloService.postTestHello(paraMap);
long end = System.currentTimeMillis();
System.out.println("*****消耗时间(秒):" + (end - begin) / 1000.0);
System.out.println(rspDTO);
}
}
源码位置
https://gitee.com/ceclar123/spring-boot-demo/tree/master/ch01