1. 程式人生 > >Spring Boot 2關於http介面呼叫(5)

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

原始碼位置