org.springframework.cloud
spring-cloud-starter-openfeign
2. 开启 openFeign
配置类或者启动类上添加注解,自动扫描已经定义好的 FignClient
@EnableFeignClients({"package1", "package2"})
3. 全局处理
异常、编解码、重试、鉴权等。
@Configuration
@ConditionalOnClass({EnableFeignClients.class})
public class FeignConfiguration {
public FeignConfiguration() {
}
@Bean
public FeignBasicAuthRequestInterceptor basicAuthRequestInterceptor() {
return new FeignBasicAuthRequestInterceptor();
}
@Bean
public FeignExceptionAspect feignExceptionAspect() {
return new FeignExceptionAspect();
}
@Bean
public Retryer feignRetryer() {
return Retryer.NEVER_RETRY;
}
@Bean
public Decoder feignDecoder() {
final MappingJackson2HttpMessageConverter jackson2HttpMessageConverter = new MappingJackson2HttpMessageConverter();
ObjectMapper objectMapper = new ObjectMapper();
SimpleModule simpleModule = new SimpleModule();
simpleModule.addSerializer(Long.class, ToStringSerializer.instance);
simpleModule.addSerializer(Long.TYPE, ToStringSerializer.instance);
simpleModule.addDeserializer(BigDecimal.class, BigDecimalJsonDeserializer.instance);
simpleModule.addSerializer(BigDecimal.class, BigDecimal2Serializer.instance);
JavaTimeModule javaTimeModule = new JavaTimeModule();
javaTimeModule.addSerializer(Date.class, new DateSerializer(false, new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")));
javaTimeModule.addDeserializer(Date.class, new DateDeserializer());
javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
javaTimeModule.addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
javaTimeModule.addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern("HH:mm:ss")));
javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
javaTimeModule.addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
javaTimeModule.addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern("HH:mm:ss")));
objectMapper.registerModule(javaTimeModule);
objectMapper.registerModule(simpleModule);
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
List fastMediaTypes = new ArrayList();
fastMediaTypes.add(MediaType.ALL);
jackson2HttpMessageConverter.setSupportedMediaTypes(fastMediaTypes);
jackson2HttpMessageConverter.setObjectMapper(objectMapper);
ObjectFactory objectFactory = new ObjectFactory() {
public HttpMessageConverters getObject() throws BeansException {
return new HttpMessageConverters(new HttpMessageConverter[]{jackson2HttpMessageConverter});
}
};
return new ResponseEntityDecoder(new SpringDecoder(objectFactory));
}
}
4. 关键代码
鉴权:
public class FeignBasicAuthRequestInterceptor implements RequestInterceptor {
public FeignBasicAuthRequestInterceptor() {
}
public void apply(RequestTemplate template) {
// 1. 通过设置一个永久的 token 来鉴权
template.header("access-token", "xxxxx");
// 2. 也可以获取 requestAttributes 放入 header中,当然这个是大家提前约定好
ServletRequestAttributes attributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
if (attributes != null) {
HttpServletRequest request = attributes.getRequest();
Enumeration reqAttrbuteNames = request.getAttributeNames();
if (reqAttrbuteNames != null) {
while(reqAttrbuteNames.hasMoreElements()) {
String attrName = (String)reqAttrbuteNames.nextElement();
// isAuthorizationed 是约定好的自定义头,方便内部调用
if ("isAuthorizationed".equalsIgnoreCase(attrName)) {
Map requestHeaderMap = (Map)request.getAttribute(attrName);
Iterator var7 = requestHeaderMap.entrySet().iterator();
while(var7.hasNext()) {
Entry entry = (Entry)var7.next();
template.header((String)entry.getKey(), new String[]{(String)entry.getValue()});
}
return;
}
}
}
}
}
}
异常处理:
@Aspect
public class FeignExceptionAspect {
public FeignExceptionAspect() {
}
@Pointcut("@within(org.springframework.cloud.openfeign.FeignClient)")
public void feignClientPointCut() {
}
@Around("feignClientPointCut()")
public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
Object object = proceedingJoinPoint.proceed();
if (object == null) {
throw new BusinessException(ResponseCode.FAILED.getCode(), "服务间调用异常,请稍后重试!");
} else if (object instanceof HttpResult) {
HttpResult> httpResult = (HttpResult)object;
if (Objects.equals(ResponseCode.SUCCESS.getCode(), httpResult .getCode()) && httpResult .isSuccess()) {
return object;
} else {
throw new BusinessException(ResponseCode.FAILED.getCode(), httpResult .getMsg());
}
} else {
return object;
}
}
}
5. 使用
可以通过微服务的注册中新和 @EnableDiscoveryClient 注解来自动发现服务:
@FeignClient(value = "userCenter", path = "/userCenter")
public interface InternetusercenterServiceInterface {
/**
* 根据ID查询用户信息
*/
@RequestMapping(value = "/userCenter/getUserInfoById", method = RequestMethod.GET)
HttpResult getUserInfoById(@RequestParam Long id);
}
本文结束,做任何事情先把整体后局部, 使用 openFeign 步骤是什么,然后每一步去实现他就可以了。
如果觉得还不错的话,关注、分享、在看(关注不失联~), 原创不易,且看且珍惜~
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)