springcloud 中的 feign 组件不仅能结合 eureka 实现springCloud内部的访问,还可以单独使用实现类似 httpClient 的功能,或者说 feign 其实就是一个简化版的 httpClient 。

-------   最后面附上源码 -------

 首先是 pom.xml 文件:

springboot 和 springcloud 的版本

<version>2.1.4.RELEASE</version>
.
.
.
<spring-cloud.version>Greenwich.SR1</spring-cloud.version>

 

关键引入:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

feign 接口:

package com.demo.carlton.feign;

import org.springframework.cloud.openfeign.FeignClient;
import com.demo.carlton.entity.User;

import feign.Param;
import feign.RequestLine;

/**
* 
* <p>Title: TestFeign.java</p>
* @author Carlton
* @date 2019年4月29日 上午9:26:36
*/
@FeignClient(name = "just-a-name")
public interface TestFeign {

	@RequestLine("POST /getUser2?id={id}")
	public User getUser(@Param("id") int id);

}

注意,接口上应使用 注解 @RequestLine,参数里应按指定格式,写明访问类型(POST/GET/...),以及url和参数

然后是调用方:

package com.demo.carlton.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.openfeign.FeignClientsConfiguration;
import org.springframework.context.annotation.Import;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.demo.carlton.entity.FeignBean;
import com.demo.carlton.entity.User;
import com.demo.carlton.feign.TestFeign;

import feign.Feign;
import feign.Feign.Builder;
import feign.Request.Options;
import feign.Retryer;
import feign.auth.BasicAuthRequestInterceptor;
import feign.codec.Decoder;
import feign.codec.Encoder;

/**
* 
* <p>Title: TestController.java</p>
* @author Carlton
* @date 2019年4月29日 上午9:38:01
*/
@RestController
// 【1】import FeignClientsConfiguration.class
@Import(FeignClientsConfiguration.class)
public class TestController {

	// 不需要 @Autowired
	TestFeign testFeign;

	// 【2】 构造函数添加 @Autowired ,注入encoder,decoder,构建 TestFeign
	@Autowired
	public TestController(FeignBean feignBean, Encoder encoder, Decoder decoder) {
		// options方法指定连接超时时长及响应超时时长,retryer方法指定重试策略
		Builder builder = Feign.builder();
		// 设置http basic验证
		builder = builder.contract(new feign.Contract.Default()).requestInterceptor(
				new BasicAuthRequestInterceptor(feignBean.getAdminName(), feignBean.getAdminPassword()));
		// 【3】设置编码,不然会报错feign.codec.EncodeException
		builder = builder.encoder(encoder).decoder(decoder);
		// options方法指定连接超时时长及响应超时时长,retryer方法指定重试策略
		builder = builder.options(new Options(feignBean.getOpion_conn(), feignBean.getOpion_read()))
				.retryer(new Retryer.Default(feignBean.getRetry_period(), feignBean.getRetry_maxPeriod(),
						feignBean.getRetry_maxAttempts()));
		// 【4】 target 链接目标feing,并指定访问域名
		testFeign = builder.target(TestFeign.class, feignBean.getUrl());
		System.out.println(000);
	}

	@PostMapping("/getUser")
	public User getUser(@RequestParam(defaultValue = "1") int id) {
		System.out.println("id=" + id);
		User user = testFeign.getUser(id);
		return user;
	}

	@PostMapping("/getUser2")
	public User getUser2(@RequestParam(defaultValue = "1") int id) {
		System.out.println("id=" + id);
		User user = new User(id, "my name " + id, (id * 10));
		return user;
	}

}

如上标注,要注意的几个关键点:

1. import feign配置类,FeignClientsConfiguration.class

2.构造函数中用 @Autowired 引入自定义参数和编解码器

3.如果有http访问验证的需求也是这里添加

4.用builder.target()方法连接目标接口和指定的url,当然这里也可以不指定url:

import feign.Target;

//不指定url
testFeign = builder.target(Target.EmptyTarget.create(TestFeign.class));

//在接口中指定
@RequestLine("POST /getUser2?id={id}")
public User getUser(URI uri, @Param("id") int id);

大功告成。

 

https://gitee.com/carltonq/test-feign.git

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐