OpenFeign支持
微服务场景下,如需调用平台的Feign接口,请确保依赖了以下组件:
Maven坐标
xml
<dependency>
<groupId>com.ikingtech.framework</groupId>
<artifactId>sdk-rpc</artifactId>
</dependency>
自定义ErrorDecoder
当FeignClient调用失败时,平台将失败信息包装为自定义异常FrameworkException向外抛出。
java
@RequiredArgsConstructor
public class FeignErrorDecoder implements ErrorDecoder {
private final FeignErrorReason feignErrorReason;
@Override
public Exception decode(String methodKey, Response response) {
return new FrameworkException(feignErrorReason.is(methodKey, response));
}
}
错误信息扩展
当FeignClient调用失败时,平台默认将远程接口返回的信息作为异常信息进行抛出,业务方如需自定义返回结果,可实现FeignErrorReason接口,自行返回错误信息。
java
public interface FeignErrorReason {
/**
* 获取失败原因
*
* @param methodKey 方法名
* @param response 响应体
* @return 失败原因
*/
String is(String methodKey, Response response);
}
java
public class DefaultFeignReason implements FeignErrorReason {
@Override
public String is(String methodKey, Response response) {
try {
return null == response.body() ?
response.reason() :
Util.toString(response.body().asReader(StandardCharsets.UTF_8));
} catch (IOException e) {
return "未知错误";
}
}
}
请求头透传
微服务的场景下,一次用户行为可能涉及多个服务之间的远程调用,因此需要确保每个服务都可以获取当前发起请求的用户的身份信息。而OpenFeign底层基于RestTemplate实现,每次调用相当于发起了一次新的Http请求,因此,需要将前一个服务接收到的用户信息透传至下一个服务内。
平台通过OpenFeign提供的请求拦截器来实现请求头透传,具体如下:
java
@Slf4j
@RequiredArgsConstructor
public class FeignClientInterceptor implements RequestInterceptor {
@Override
public void apply(RequestTemplate requestTemplate) {
//feign接口默认设置为内部调用,方便security模块鉴权通过
requestTemplate.header(HEADER_CALLER, INNER_CALLER);
// 获取请求中的请求头
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
if (null == attributes) {
//内部调用设置默认用户信息
try {
requestTemplate.header(HEADER_IDENTITY, URLEncoder.encode(Tools.Json.toJsonStr(Identity.defaultUser()), Charset.defaultCharset().name()));
} catch (UnsupportedEncodingException e) {
log.error("[N/A]set default user error[{}]", e.getMessage());
}
return;
}
requestTemplate.header(HEADER_IDENTITY, attributes.getRequest().getHeader(HEADER_IDENTITY));
}
}