快速导航
[添加依赖]
添加依赖[添加核心配置类]
添加核心配置类TestFeignConfig[添加日志配置类]
添加日志配置类TestApiFeignLogger[添加远程调用服务类]
添加远程调用服务类TestApiFeignClient[请求返回的最外层对象]
请求返回的最外层对象[获取AccessToken返回对象]
获取AccessToken返回对象[调用示例]
调用示例[参考资料]
参考资料
添加依赖
Maven
Feign 声明式http请求调用轻量级框架
在项目的 pom.xml 的 dependencies 中加入以下内容:
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-core</artifactId>
<version>9.5.1</version>
</dependency>
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-slf4j</artifactId>
<version>9.5.1</version>
</dependency>
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-hystrix</artifactId>
<version>9.5.1</version>
</dependency>
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-jackson</artifactId>
<version>9.5.1</version>
</dependency>
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-okhttp</artifactId>
<version>9.5.1</version>
</dependency>
添加核心配置类
在项目中新增 TestFeignConfig 核心配置类,代码如下:
package com.boot.component.test.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.boot.component.test.client.TestApiFeignClient;
import com.boot.component.test.log.TestApiFeignLogger;
import feign.Feign;
import feign.Logger;
import feign.Request;
import feign.Retryer;
import feign.jackson.JacksonDecoder;
import feign.jackson.JacksonEncoder;
import feign.okhttp.OkHttpClient;
/**
* @Description: FeignClient的配置类
* @author Lord
* @date 2019年12月16日
*/
@Configuration
public class TestFeignConfig {
/**
* FeignClient 配置
* @return
*/
@Bean
TestApiFeignClient testApiFeignClient() {
return Feign.builder()
.client(new OkHttpClient())
.logger(new TestApiFeignLogger())
.logLevel(Logger.Level.FULL)
.encoder(new JacksonEncoder())
.decoder(new JacksonDecoder())
.options(new Request.Options(1000, 3500))
.retryer(new Retryer.Default(5000, 5000, 3))
.target(TestApiFeignClient.class, "http://127.0.0.1:8085");
}
}
添加日志配置类
在项目中新增 TestApiFeignLogger 日志配置类,代码如下:
package com.boot.component.test.log;
import java.io.IOException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import feign.Request;
import feign.Response;
public class TestApiFeignLogger extends feign.Logger {
private final Logger logger;
public TestApiFeignLogger() {
this(feign.Logger.class);
}
public TestApiFeignLogger(Class<?> clazz) {
this(LoggerFactory.getLogger(clazz));
}
public TestApiFeignLogger(String name) {
this(LoggerFactory.getLogger(name));
}
TestApiFeignLogger(Logger logger) {
this.logger = logger;
}
@Override
protected void logRequest(String configKey, Level logLevel, Request request) {
if (logger.isInfoEnabled()) {
super.logRequest(configKey, logLevel, request);
}
}
@Override
protected Response logAndRebufferResponse(String configKey, Level logLevel, Response response, long elapsedTime)
throws IOException {
if (logger.isInfoEnabled()) {
return super.logAndRebufferResponse(configKey, logLevel, response, elapsedTime);
}
return response;
}
@Override
protected void log(String configKey, String format, Object... args) {
// Not using SLF4J's support for parameterized messages (even though it
// would be more efficient) because it would
// require the incoming message formats to be SLF4J-specific.
if (logger.isInfoEnabled()) {
logger.info(String.format(methodTag(configKey) + format, args));
}
}
}
添加远程调用服务类
在项目中新增 TestApiFeignClient 远程调用服务类,代码如下:
package com.boot.component.test.client;
import java.util.List;
import java.util.Map;
import com.boot.component.test.common.CommonReturnType;
import com.boot.component.test.model.response.AccessTokenOutput;
import com.boot.component.test.model.response.area.AddressOutput;
import feign.Headers;
import feign.QueryMap;
import feign.RequestLine;
/**
* @Description: feignClient的接口(远程调用服务类)
* @author Lord
* @date 2019年12月16日
*/
@Headers("Content-Type:application/x-www-form-urlencoded")
public interface TestApiFeignClient {
@RequestLine("POST /oauth2/accessToken")
CommonReturnType<AccessTokenOutput> getAccessToken(@QueryMap Map<String, Object> params);
@RequestLine("POST /oauth2/refreshToken")
CommonReturnType<AccessTokenOutput> getRefreshToken(@QueryMap Map<String, Object> params);
}
请求返回的最外层对象
在项目中新增 CommonReturnType<T> 请求返回的最外层对象类,代码如下:
package com.boot.component.jd.common;
import java.io.Serializable;
/**
* @Description: 请求返回的最外层对象
* @author Lord
* @date 2019年12月13日
*/
public class CommonReturnType<T> implements Serializable {
private static final long serialVersionUID = -8797234859999337279L;
/** 执行结果成功,还是失败. */
private Boolean success;
/** 错误码. */
private String resultCode;
/** 提示信息. */
private String resultMessage;
private T result;
public Boolean getSuccess() {
return success;
}
public void setSuccess(Boolean success) {
this.success = success;
}
public String getResultCode() {
return resultCode;
}
public void setResultCode(String resultCode) {
this.resultCode = resultCode;
}
public String getResultMessage() {
return resultMessage;
}
public void setResultMessage(String resultMessage) {
this.resultMessage = resultMessage;
}
public T getResult() {
return result;
}
public void setResult(T result) {
this.result = result;
}
@Override
public String toString() {
return "CommonReturnType [success=" + success + ", resultCode=" + resultCode + ", resultMessage="
+ resultMessage + ", result=" + result + "]";
}
}
获取AccessToken返回对象
在项目中新增 AccessTokenOutput 获取AccessToken返回对象类,代码如下:
package com.boot.component.test.model.response;
import java.io.Serializable;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
/**
* @Description: 获取AccessToken返回对象
* @author Lord
* @date 2019年12月16日
*/
@JsonIgnoreProperties(ignoreUnknown = true)
public class AccessTokenOutput implements Serializable {
private static final long serialVersionUID = 388723550621265373L;
/**
* 业务id
*/
private String uid;
/**
* 访问令牌,用于业务接口调用。(有效期24小时)
*/
@JsonProperty("access_token")
private String accessToken;
/**
* 当access_token过期时,用于刷新access_token
*/
@JsonProperty("refresh_token")
private String refreshToken;
/**
* 当前时间,时间戳格式:1551663377887
*/
private Long time;
/**
* access_token的有效期,单位:秒,有效期24小时
*/
@JsonProperty("expires_in")
private Integer expiresIn;
/**
* refresh_token的过期时间,毫秒级别,时间戳
*/
@JsonProperty("refresh_token_expires")
private Long refreshTokenExpires;
public String getUid() {
return uid;
}
public void setUid(String uid) {
this.uid = uid;
}
public String getAccessToken() {
return accessToken;
}
public void setAccessToken(String accessToken) {
this.accessToken = accessToken;
}
public String getRefreshToken() {
return refreshToken;
}
public void setRefreshToken(String refreshToken) {
this.refreshToken = refreshToken;
}
public Long getTime() {
return time;
}
public void setTime(Long time) {
this.time = time;
}
public Integer getExpiresIn() {
return expiresIn;
}
public void setExpiresIn(Integer expiresIn) {
this.expiresIn = expiresIn;
}
public Long getRefreshTokenExpires() {
return refreshTokenExpires;
}
public void setRefreshTokenExpires(Long refreshTokenExpires) {
this.refreshTokenExpires = refreshTokenExpires;
}
}
调用示例
TestController
FeignTestController 测试Feign远程调用
FeignTestController 代码如下:
package com.boot.controller.test;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;
import javax.annotation.Resource;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.boot.component.test.client.TestApiFeignClient;
import com.boot.component.test.common.CommonReturnType;
import com.boot.component.test.model.response.AccessTokenOutput;
import com.xiaoleilu.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@RestController
@RequestMapping("/feign/test")
public class FeignTestController {
@Resource
private TestApiFeignClient testApiFeignClient;
@GetMapping
public CommonReturnType<AccessTokenOutput> test() {
String statDate = LocalDateTime.now().format(DateTimeFormatter.ISO_DATE_TIME);
log.info("进入Feign远程调用服务测试类,当前时间:[{}]", statDate);
Map<String, Object> params = new HashMap<>(2);
params.put("username", "admin");
params.put("password", "admin123");
CommonReturnType<AccessTokenOutput> accessTokenResult = testApiFeignClient.getAccessToken(params);
log.info("[测试] 获取 AccessToken 响应结果:[{}]", JSONUtil.toJsonStr(accessTokenResult));
return accessTokenResult;
}
}
参考资料
SpringBoot脱离SpringCloud使用Feign