最近项目需要搭建一个项目,需求是使用已经存在的上传接口,使用fegin实现功能。现在可以把步骤分享一下,经测试可用。
Springboot2.5整合openFegin客户端(文件上传)
1、配置pom.xml文件
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
<version>2.2.5.RELEASE</version>
</dependency>
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-okhttp</artifactId>
<version>10.2.3</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
2、支持文件上传的config文件
import feign.form.spring.SpringFormEncoder;
import feign.slf4j.Slf4jLogger;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
import org.springframework.cloud.openfeign.support.SpringEncoder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.context.annotation.Scope;
/**
* @Author: Liu Yue
* @Descripition:
* @Date; Create in 2021/1/23 16:36
**/
@Configuration
public class FeignMultipartSupportConfig {
@Autowired
private ObjectFactory<HttpMessageConverters> messageConverters;
@Bean
@Primary
@Scope("prototype")
public SpringFormEncoder multipartFormEncoder() {
return new SpringFormEncoder(new SpringEncoder(messageConverters));
}
@Bean
public feign.Logger.Level multipartLoggerLevel() {
return Slf4jLogger.Level.FULL;
}
}
3、fegin使用的okhttp的配置
import feign.Feign;
import okhttp3.ConnectionPool;
import okhttp3.OkHttpClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.cloud.openfeign.FeignAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.concurrent.TimeUnit;
/**
* @Author: Liu Yue
* @Descripition:
* @Date; Create in 2020/8/18 11:27
**/
@Configuration
@ConditionalOnClass(Feign.class)
@AutoConfigureBefore(FeignAutoConfiguration.class)
public class OkHttpConfiguration {
@Value("${ok.http.connect-timeout}")
private Integer connectTimeout;
@Value("${ok.http.read-timeout}")
private Integer readTimeout;
@Value("${ok.http.write-timeout}")
private Integer writeTimeout;
@Value("${ok.http.max-idle-connections}")
private Integer maxIdleConnections;
@Value("${ok.http.keep-alive-duration}")
private Long keepAliveDuration;
@Bean
public OkHttpClient okHttpClient() {
return new OkHttpClient.Builder()
.sslSocketFactory(sslSocketFactory(), x509TrustManager())
// 是否开启缓存
.retryOnConnectionFailure(false)
.connectionPool(pool())
.connectTimeout(connectTimeout, TimeUnit.SECONDS)
.readTimeout(readTimeout, TimeUnit.SECONDS)
.writeTimeout(writeTimeout,TimeUnit.SECONDS)
.hostnameVerifier((hostname, session) -> true)
.build();
}
@Bean
public X509TrustManager x509TrustManager() {
return new X509TrustManager() {
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
}
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
};
}
@Bean
public SSLSocketFactory sslSocketFactory() {
try {
// 信任任何链接
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, new TrustManager[]{x509TrustManager()}, new SecureRandom());
return sslContext.getSocketFactory();
} catch (NoSuchAlgorithmException | KeyManagementException e) {
e.printStackTrace();
}
return null;
}
@Bean
public ConnectionPool pool() {
return new ConnectionPool(maxIdleConnections, keepAliveDuration, TimeUnit.SECONDS);
}
}
4、代理类配置
import com.hake.smart.base.BaseResponse;
import com.hake.smart.configration.FeignMultipartSupportConfig;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
/**
* @Author: Liu Yue
* @Descripition:
* @Date; Create in 2021/1/23 12:08
**/
@FeignClient(name = "feignFileClientProxy",configuration = FeignMultipartSupportConfig.class,url = "http://localhost:8088/hakesmart/fileUpDown/")
public interface FeignFileClientProxy {
@PostMapping(value = "/fegin/upFile" ,consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
@ResponseBody
BaseResponse invoke(@RequestPart("uploadFile") MultipartFile file, @RequestParam("fileTypeId") String fileTypeId);
/* *
* 容错处理类,当调用失败时 返回空字符串*/
@Component
class DefaultFallback implements FeignFileClientProxy {
@Override
public BaseResponse invoke(@RequestPart("uploadFile") MultipartFile file, @RequestParam("fileTypeId") String fileTypeId){
return new BaseResponse("401","失败","远程调用失败");
}
}
}
5、调用的rest
/**
* 普通上传
* @param file
* @return
*/
@PostMapping("/api/fileUpDown/upFile")
@ResponseBody
public BaseResponse upFile(@RequestPart("uploadFile") MultipartFile file, @RequestParam("fileTypeId") String fileTypeId) {
return feignFileClientProxy.invoke(file,fileTypeId);
}
6、测试
已经通过测试。