Browse Source

Merge remote-tracking branch 'remotes/origin/developer' into developerA

Aslee 3 years ago
parent
commit
7143faa429

+ 1 - 1
pom.xml

@@ -32,7 +32,7 @@
     <dependencies>
 		<dependency>
 			<groupId>org.springframework.boot</groupId>
-			<artifactId>spring-boot-starter-web</artifactId>
+			<artifactId>spring-boot-starter-webflux</artifactId>
 		</dependency>
 		<dependency>
 			<groupId>org.springframework.cloud</groupId>

+ 21 - 0
src/main/java/com/caimei365/commodity/config/LoadBalanceConfiguration.java

@@ -0,0 +1,21 @@
+package com.caimei365.commodity.config;
+
+import org.springframework.cloud.client.loadbalancer.LoadBalanced;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.reactive.function.client.WebClient;
+
+/**
+ * Description
+ *
+ * @author : Charles
+ * @date : 2021/2/23
+ */
+@Configuration
+public class LoadBalanceConfiguration {
+    @Bean
+    @LoadBalanced
+    public WebClient.Builder builder() {
+        return WebClient.builder();
+    }
+}

+ 37 - 0
src/main/java/com/caimei365/commodity/controller/TestWebClientApi.java

@@ -0,0 +1,37 @@
+package com.caimei365.commodity.controller;
+
+import io.swagger.annotations.Api;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.reactive.function.client.WebClient;
+import reactor.core.publisher.Mono;
+
+import javax.annotation.Resource;
+
+
+/**
+ * Description
+ *
+ * @author : Charles
+ * @date : 2021/02/20
+ */
+@Api(tags="测试WebClient")
+@RequestMapping("/commodity")
+@RestController
+public class TestWebClientApi {
+
+    @GetMapping("/test")
+    public String getTestString() {
+        return "test product";
+    }
+
+    @Resource
+    private WebClient.Builder clientBuilder;
+    private static final String BASE_URL = "http://caimei365-cloud-user";
+    @GetMapping("/user")
+    public Mono<String> getServerString() {
+        return clientBuilder.baseUrl(BASE_URL).build().get().uri("/user/").retrieve().bodyToMono(String.class);
+    }
+
+}

+ 187 - 0
src/main/java/com/caimei365/commodity/utils/WebClientUtils.java

@@ -0,0 +1,187 @@
+package com.caimei365.commodity.utils;
+
+import io.netty.handler.ssl.SslContextBuilder;
+import io.netty.handler.ssl.util.InsecureTrustManagerFactory;
+import org.springframework.http.ResponseCookie;
+import org.springframework.http.client.reactive.ReactorClientHttpConnector;
+import org.springframework.util.LinkedMultiValueMap;
+import org.springframework.util.MultiValueMap;
+import org.springframework.web.reactive.function.client.WebClient;
+import reactor.netty.http.client.HttpClient;
+
+import java.time.Duration;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Description
+ *
+ * @author : Charles
+ * @date : 2021/2/23
+ */
+public class WebClientUtils {
+    /**
+     * 默认3分钟超时时间
+     */
+    private final static Duration DEFAULT_REQUEST_TIMEOUT = Duration.ofMinutes(3L);
+
+    /**
+     * 默认代理超时时间
+     */
+    private final static Long DEFAULT_PROXY_TIMEOUT_MILLIS = DEFAULT_REQUEST_TIMEOUT.toMillis();
+
+    //region 生成WebClient.Builder的方法
+
+    /**
+     * 给了一个默认的WebClient,这个Client里面配置了默认请求超时时间
+     *
+     * @return 返回一个带超时时间的{@link WebClient.Builder}
+     */
+    public static WebClient.Builder getDefaultWebClientBuilder() {
+        return getWebClientBuilder(DEFAULT_REQUEST_TIMEOUT);
+    }
+
+    /**
+     * [基础创建方法]
+     * 给了一个默认的WebClient,这个Client里面配置了指定了请求超时时间
+     *
+     * @param requestTimeOut 请求超时时间
+     * @return 返回一个带超时时间的{@link WebClient.Builder}
+     */
+    public static WebClient.Builder getWebClientBuilder(Duration requestTimeOut) {
+        if (requestTimeOut == null) {
+            requestTimeOut = DEFAULT_REQUEST_TIMEOUT;
+        }
+        return WebClient.builder().clientConnector(new ReactorClientHttpConnector(HttpClient
+                .create()
+                //重新定向开启
+                .followRedirect(true)
+                .responseTimeout(requestTimeOut)));
+    }
+
+    /**
+     * 给到一个带默认超时时间,并带有不校验任何SSL整数的WebClient
+     *
+     * @return 返回一个带默认超时时间和默认全局信任的SSL请求校验器{@link WebClient.Builder}
+     */
+    public static WebClient.Builder getWebClientBuilderWithSslTrust() {
+        return getWebClientBuilderWithSslTrust(DEFAULT_REQUEST_TIMEOUT);
+    }
+
+    /**
+     * 给到一个带超时时间,并带有不校验任何SSL整数的WebClient
+     *
+     * @param requestTimeOut 超时时间
+     * @return 返回一个带超时时间和默认全局信任的SSL请求校验器{@link WebClient.Builder}
+     */
+    public static WebClient.Builder getWebClientBuilderWithSslTrust(Duration requestTimeOut) {
+        return getWebClientBuilderWithSslTrust(requestTimeOut, false);
+    }
+
+    /**
+     * [基础创建方法]
+     * 给到一个带超时时间,并带有不校验任何SSL整数的WebClient
+     *
+     * @param requestTimeOut     超时时间
+     * @param compressionEnabled 开启压缩?默认关闭
+     * @return 返回一个带超时时间和默认全局信任的SSL请求校验器{@link WebClient.Builder}
+     */
+    public static WebClient.Builder getWebClientBuilderWithSslTrust(Duration requestTimeOut, boolean compressionEnabled) {
+        if (requestTimeOut == null) {
+            requestTimeOut = DEFAULT_REQUEST_TIMEOUT;
+        }
+        return WebClient.builder().clientConnector(new ReactorClientHttpConnector(HttpClient
+                .create()
+                //重新定向开启
+                .followRedirect(true)
+                //这里注入了一个抛弃一切SSL认证的sslContext
+                .secure(sslContextSpec -> sslContextSpec.sslContext(SslContextBuilder.forClient().trustManager(InsecureTrustManagerFactory.INSTANCE)))
+                .responseTimeout(requestTimeOut)
+                .compress(compressionEnabled)
+        ));
+    }
+
+    /**
+     * 给到一个带超时时间,带代理,并带有不校验任何SSL整数的WebClient
+     *
+     * @param requestTimeOut 超时时间
+     * @param proxyDO        代理实体
+     * @return 返回一个带超时时间和默认全局信任的SSL请求校验器{@link WebClient.Builder}
+     */
+    /*public static WebClient.Builder getWebClientBuilderWithSslTrustAndPolicy(Duration requestTimeOut, ProxyDO proxyDO) {
+        return getWebClientBuilderWithSslTrustAndPolicy(requestTimeOut, proxyDO, false);
+    }*/
+
+    /**
+     * [基础创建方法]
+     * 给到一个带超时时间,带代理,并带有不校验任何SSL整数的WebClient
+     *
+     * @param requestTimeOut     超时时间
+     * @param proxyDO            代理实体
+     * @param compressionEnabled 开启压缩?默认关闭
+     * @return 返回一个带超时时间和默认全局信任的SSL请求校验器{@link WebClient.Builder}
+     */
+    /*public static WebClient.Builder getWebClientBuilderWithSslTrustAndPolicy(Duration requestTimeOut, ProxyDO proxyDO, boolean compressionEnabled) {
+        if (requestTimeOut == null) {
+            requestTimeOut = DEFAULT_REQUEST_TIMEOUT;
+        }
+        return WebClient.builder().clientConnector(new ReactorClientHttpConnector(HttpClient
+                .create()
+                //这里注入了一个抛弃一切SSL认证的sslContext
+                .secure(sslContextSpec -> sslContextSpec.sslContext(SslContextBuilder.forClient().trustManager(InsecureTrustManagerFactory.INSTANCE)))
+                .responseTimeout(requestTimeOut)
+                .compress(compressionEnabled)
+                //重新定向开启
+                .followRedirect(true)
+                .tcpConfiguration(tcpClient -> tcpClient.proxy(
+                        p -> {
+                            ProxyProvider.Builder pb = p.type(ProxyProvider.Proxy.HTTP)
+                                    .address(InetSocketAddress.createUnresolved(proxyDO.getServiceAddress(), Integer.parseInt(proxyDO.getPort())));
+                            if (StringUtils.isNotEmpty(proxyDO.getUserName())) {
+                                pb.username(proxyDO.getUserName())
+                                        .password(v -> proxyDO.getPassword());
+                            }
+                            Long proxyTimeOutMillis = proxyDO.getProxyTimeOutMillis();
+                            if (proxyTimeOutMillis != null && proxyTimeOutMillis > 0) {
+                                pb.connectTimeoutMillis(proxyTimeOutMillis);
+                            } else {
+                                pb.connectTimeoutMillis(DEFAULT_PROXY_TIMEOUT_MILLIS);
+                            }
+                        }
+                ))
+        ));
+    }*/
+
+    //endregion
+
+    /**
+     * 将http相应中的Cookie转换为用于http请求中的cookie
+     * 方法中仅进行简单转换,不会对Cookie有效期等进行判断
+     *
+     * @param responseCookie 需要被转换的cookie
+     * @return 返回可以用于请求的Cookies
+     */
+    public static MultiValueMap<String, String> transformResponseCookiesToRequestCookies(MultiValueMap<String, ResponseCookie> responseCookie) {
+        MultiValueMap<String, String> ret = new LinkedMultiValueMap<>();
+        if (responseCookie == null || responseCookie.size() == 0) {
+            return ret;
+        }
+
+
+        for (Map.Entry<String, List<ResponseCookie>> entity : responseCookie.entrySet()) {
+            String key = entity.getKey();
+            List<ResponseCookie> value = entity.getValue();
+            int size = value.size();
+            if (size == 0) {
+                continue;
+            }
+            List<String> cookies = new ArrayList<>(size);
+            for (ResponseCookie cookie : value) {
+                cookies.add(cookie.getValue());
+            }
+            ret.addAll(key, cookies);
+        }
+        return ret;
+    }
+}