Feign使用
1、Client
public interface EngineConfigClient {
@RequestMapping(method = RequestMethod.GET, value = "/xxxConfig/cluster/config/sync/{engineId}/detail")
EngineConfigResponse getEngineConfig(@PathVariable(value = "engineId") String engineId);
}
2、实例化
package com.dtdream.emr.flink.service.impl;
import com.dtdream.emr.flink.engine.api.EngineConfigClient;
import com.dtdream.emr.flink.facade.model.ResultInfo;
import com.dtdream.emr.flink.common.util.IOUtil;
import com.dtdream.emr.flink.gateway.api.GatewayClient;
import com.dtdream.emr.flink.gateway.api.common.GatewayException;
import com.dtdream.emr.flink.service.WebServiceConfig;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.RuntimeJsonMappingException;
import feign.Contract;
import feign.Feign;
import feign.Request;
import feign.Response;
import feign.Retryer;
import feign.Util;
import feign.auth.BasicAuthRequestInterceptor;
import feign.codec.Decoder;
import feign.codec.Encoder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.cloud.openfeign.FeignClientsConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.Reader;
import java.lang.reflect.Type;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.TimeUnit;
@Import(FeignClientsConfiguration.class)
@Configuration
@EnableFeignClients()
public class FeignClientConfig {
@Autowired
private WebServiceConfig webServiceConfig;
@Bean
public EngineConfigClient getEngineConfigClient(Encoder feignEncoder, Contract contract) {
return Feign.builder()
.encoder(feignEncoder)
.decoder(new WrappedJacksonDecoder(IOUtil.getCommonObjectMapper()))
.contract(contract)
.options(new Request.Options(5, TimeUnit.SECONDS, 600, TimeUnit.SECONDS, true))
.retryer(new Retryer.Default(5000, 5000, 3))
.requestInterceptor(new BasicAuthRequestInterceptor(webServiceConfig.getGatewayUsername(),
webServiceConfig.getGatewayPassword()))
.target(EngineConfigClient.class, webServiceConfig.getEngineConfigUrl());
}
private static class WrappedJacksonDecoder implements Decoder {
private final ObjectMapper objectMapper;
WrappedJacksonDecoder(ObjectMapper objectMapper) {
this.objectMapper = objectMapper;
}
public Object decode(Response response, Type type) throws IOException {
if (response.status() == 404) {
return Util.emptyValueOf(type);
}
if (response.body() == null) {
return null;
}
Reader reader = response.body().asReader(StandardCharsets.UTF_8);
if (!reader.markSupported()) {
reader = new BufferedReader(reader, 1);
}
try {
// Read the first byte to see if we have any data
reader.mark(1);
if (reader.read() == -1) {
// Eagerly returning null avoids "No content to map due to end-of-input"
return null;
}
reader.reset();
ResultInfo resultInfo = objectMapper.readValue(reader, ResultInfo.class);
if (!resultInfo.isSuccess()) {
throw new GatewayException("error info: " + resultInfo.getMessage(), resultInfo.getErrorCode());
}
return objectMapper.convertValue(resultInfo.getData(), objectMapper.constructType(type));
} catch (RuntimeJsonMappingException e) {
if (e.getCause() instanceof IOException) {
throw IOException.class.cast(e.getCause());
}
throw e;
}
}
}
}
遇到的问题
1、
target values must be absolute.
开始以为代码问题,后来灵机一动,发现是URL不通,我犯的错是hrl没有加http前缀,修改即可
2、
feign.codec.DecodeException: error info: null
at feign.AsyncResponseHandler.decode(AsyncResponseHandler.java:119)
at feign.AsyncResponseHandler.handleResponse(AsyncResponseHandler.java:87)
at feign.SynchronousMethodHandler.executeAndDecode(SynchronousMethodHandler.java:138)
at feign.SynchronousMethodHandler.invoke(SynchronousMethodHandler.java:89)
at feign.ReflectiveFeign$FeignInvocationHandler.invoke(ReflectiveFeign.java:100)
at com.sun.proxy.$Proxy168.getEngineConfig(Unknown Source)
at com.dtdream.emr.flink.service.impl.EngineConfigServiceImpl.syncEngineConfig(EngineConfigServiceImpl.java:58)
at com.dtdream.emr.flink.controller.EngineController.syncEngineConfig(EngineController.java:118)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
原因:Client中用到的对象未序列化,序列化即可