diff --git a/sf-vertx/src/main/java/com/sf/vertx/handle/AppConfigHandler.java b/sf-vertx/src/main/java/com/sf/vertx/handle/AppConfigHandler.java index 8ecd781..242174d 100644 --- a/sf-vertx/src/main/java/com/sf/vertx/handle/AppConfigHandler.java +++ b/sf-vertx/src/main/java/com/sf/vertx/handle/AppConfigHandler.java @@ -31,6 +31,7 @@ import com.sf.vertx.enums.GatewayServiceType; import com.sf.vertx.httpproxy.HttpProxy; import com.sf.vertx.init.SacVertxConfig; import com.sf.vertx.pojo.ClusterEventMsg; +import com.sf.vertx.pojo.SacCircuitBreaker; import com.sf.vertx.pojo.SacCurrentLimiting; import com.sf.vertx.security.MainSecurity; import com.sf.vertx.utils.ProxyTool; @@ -96,7 +97,7 @@ public class AppConfigHandler { private static ConcurrentHashMap> APICODE_CONFIG_HEADER_ROUTERCONENT_MAP = new ConcurrentHashMap<>(); // apiCode熔断配置 appCode:apiCode - CircuitBreaker - private static ConcurrentHashMap APICODE_CONFIG_CIRCUIT_BREAKER_MAP = new ConcurrentHashMap<>(); + private static ConcurrentHashMap APICODE_CONFIG_CIRCUIT_BREAKER_MAP = new ConcurrentHashMap<>(); // apicode uri = * - appConfig private static ConcurrentHashMap APICODE_APPCONFIG_MAP = new ConcurrentHashMap<>(); @@ -118,14 +119,14 @@ public class AppConfigHandler { public static Boolean isServiceTypeOpen(String key) { return APICODE_CONFIG_SERVICE_TYPE_MAP.get(key) != null - && StringUtils.equals(APICODE_CONFIG_SERVICE_TYPE_MAP.get(key), "OPEN"); + && StringUtils.equals(APICODE_CONFIG_SERVICE_TYPE_MAP.get(key), GatewayServiceType.OPEN.getCode()); } public static Boolean isServiceTypeSac(String key) { return APICODE_CONFIG_SERVICE_TYPE_MAP.get(key) != null - && StringUtils.equals(APICODE_CONFIG_SERVICE_TYPE_MAP.get(key), "SAC"); + && StringUtils.equals(APICODE_CONFIG_SERVICE_TYPE_MAP.get(key), GatewayServiceType.SAC.getCode()); } - + public static String getServiceType(String key) { return APICODE_CONFIG_SERVICE_TYPE_MAP.get(key); } @@ -171,7 +172,7 @@ public class AppConfigHandler { return APICODE_CONFIG_CIRCUIT_BREAKER_MAP.get(key) != null; } - public static CircuitBreaker getApiCodeCircuitBreaker(String key) { + public static SacCircuitBreaker getApiCodeCircuitBreaker(String key) { return APICODE_CONFIG_CIRCUIT_BREAKER_MAP.get(key); } @@ -273,9 +274,11 @@ public class AppConfigHandler { APICODE_CONFIG_CURRENT_LIMITING_MAP.remove(key); APICODE_APPCONFIG_MAP.remove(apiConfig.getApiCode()); String keyCircuitBreaker = key + ":" + "CIRCUIT_BREAKER"; - CircuitBreaker circuitBreaker = APICODE_CONFIG_CIRCUIT_BREAKER_MAP.get(keyCircuitBreaker); - if (circuitBreaker != null) { - circuitBreaker.close(); + SacCircuitBreaker sacCircuitBreaker = APICODE_CONFIG_CIRCUIT_BREAKER_MAP.get(key); + if (sacCircuitBreaker != null) { + if(sacCircuitBreaker.getCircuitBreaker() != null) { + sacCircuitBreaker.getCircuitBreaker().close(); + } APICODE_CONFIG_CIRCUIT_BREAKER_MAP.remove(keyCircuitBreaker); } } @@ -351,7 +354,7 @@ public class AppConfigHandler { } // OPEN模式, 域名映射 - if (isServiceTypeOpen(key) && StringUtils.equals(apiConfig.getUri(), "*")) { + if (isServiceTypeOpen(key)) { APICODE_APPCONFIG_MAP.put(apiConfig.getApiCode(), appConfig); } @@ -402,11 +405,14 @@ public class AppConfigHandler { ).openHandler(v -> { log.info(keyCircuitBreaker + " Circuit open"); }).halfOpenHandler(v -> { - log.info(keyCircuitBreaker + "Circuit halfOpen"); + log.info(keyCircuitBreaker + " Circuit halfOpen"); }).closeHandler(v -> { - log.info(keyCircuitBreaker + "Circuit close"); + log.info(keyCircuitBreaker + " Circuit close"); }); - APICODE_CONFIG_CIRCUIT_BREAKER_MAP.put(keyCircuitBreaker, circuitBreaker); + SacCircuitBreaker sacCircuitBreaker = new SacCircuitBreaker(); + sacCircuitBreaker.setCircuitBreaker(circuitBreaker); + sacCircuitBreaker.setStrategy(strategy); + APICODE_CONFIG_CIRCUIT_BREAKER_MAP.put(key, sacCircuitBreaker); } } } @@ -565,19 +571,27 @@ public class AppConfigHandler { Route routeSac = mainHttpRouter.post(rpcUri()); routeSac.handler(CorsHandler.create().addRelativeOrigin(".*")) .handler(ParameterCheckHandler.create(GatewayServiceType.SAC)) - .handler(AppRateLimitHandler.create(rateLimitModel)).handler(ApiRateLimitHandler.create(rateLimitModel)) - .handler(BodyPreCheckHandler.create()).handler(BodyHandler.create().setHandleFileUploads(false)) - .handler(BodyPostAnalysisHandler.create()).handler(BodyPostCheckHandler.create()) - .handler(SacRouteRequestHandler.create(mainWebClient)).handler(ProxyHandler.create(proxy)) + .handler(AppRateLimitHandler.create(rateLimitModel)) + .handler(ApiRateLimitHandler.create(rateLimitModel)) + .handler(BodyPreCheckHandler.create()) + .handler(BodyHandler.create().setHandleFileUploads(false)) + .handler(BodyPostAnalysisHandler.create()) + .handler(BodyPostCheckHandler.create()) + .handler(SacRouteRequestHandler.create(mainWebClient)) + .handler(ProxyHandler.create(mainWebClient, proxy)) .failureHandler(RestfulFailureHandler.create()); Route routeOpen = mainHttpRouter.route(); routeOpen.handler(CorsHandler.create().addRelativeOrigin(".*")) .handler(ParameterCheckHandler.create(GatewayServiceType.OPEN)) - .handler(AppRateLimitHandler.create(rateLimitModel)).handler(ApiRateLimitHandler.create(rateLimitModel)) - .handler(BodyPreCheckHandler.create()).handler(BodyHandler.create().setHandleFileUploads(false)) - .handler(BodyPostCheckHandler.create()).handler(SacRouteRequestHandler.create(mainWebClient)) - .handler(ProxyHandler.create(proxy)).failureHandler(RestfulFailureHandler.create()); + .handler(AppRateLimitHandler.create(rateLimitModel)) + .handler(ApiRateLimitHandler.create(rateLimitModel)) + .handler(BodyPreCheckHandler.create()) + .handler(BodyHandler.create().setHandleFileUploads(false)) + .handler(BodyPostCheckHandler.create()) + .handler(SacRouteRequestHandler.create(mainWebClient)) + .handler(ProxyHandler.create(mainWebClient, proxy)) + .failureHandler(RestfulFailureHandler.create()); } private static void loadVertxOptions(VertxOptions vertxOptions) { @@ -590,7 +604,7 @@ public class AppConfigHandler { } // TODO - blockedThreadCheckInterval = 1000000L; + // blockedThreadCheckInterval = 1000000L; if (blockedThreadCheckInterval != -1) { vertxOptions.setBlockedThreadCheckInterval(blockedThreadCheckInterval); // 不打印Thread blocked 阻塞日志 } diff --git a/sf-vertx/src/main/java/com/sf/vertx/handle/BodyHandlerImpl.java b/sf-vertx/src/main/java/com/sf/vertx/handle/BodyHandlerImpl.java index 88df115..c478349 100644 --- a/sf-vertx/src/main/java/com/sf/vertx/handle/BodyHandlerImpl.java +++ b/sf-vertx/src/main/java/com/sf/vertx/handle/BodyHandlerImpl.java @@ -134,8 +134,9 @@ public class BodyHandlerImpl implements BodyHandler { // TODO 改造了这个地方 在真正解析body之前验证是否需要继续解析 AppConfig appConfig = AppUtils.getAppConfigFromRoutingContext(context); ApiConfig apiConfig = AppUtils.getApiConfigFromRoutingContext(context); + String contentType = context.request().headers().get(HttpHeaders.CONTENT_TYPE); String apiServiceType = context.get(API_SERVICE_TYPE); - if (!AppUtils.isAnalysisBody(appConfig, apiConfig, apiServiceType)){ + if (!AppUtils.isAnalysisBody(appConfig, apiConfig, apiServiceType, contentType)){ context.next(); return; } diff --git a/sf-vertx/src/main/java/com/sf/vertx/handle/ProxyHandler.java b/sf-vertx/src/main/java/com/sf/vertx/handle/ProxyHandler.java index 11d9a7e..994420f 100644 --- a/sf-vertx/src/main/java/com/sf/vertx/handle/ProxyHandler.java +++ b/sf-vertx/src/main/java/com/sf/vertx/handle/ProxyHandler.java @@ -1,14 +1,3 @@ -/* - * Copyright (c) 2011-2021 Contributors to the Eclipse Foundation - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License 2.0 which is available at - * http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 - * which is available at https://www.apache.org/licenses/LICENSE-2.0. - * - * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 - */ - package com.sf.vertx.handle; import com.sf.vertx.httpproxy.HttpProxy; @@ -16,6 +5,7 @@ import com.sf.vertx.httpproxy.HttpProxy; import io.vertx.codegen.annotations.VertxGen; import io.vertx.core.Handler; import io.vertx.ext.web.RoutingContext; +import io.vertx.ext.web.client.WebClient; /** * @author Emad Alblueshi @@ -24,11 +14,15 @@ import io.vertx.ext.web.RoutingContext; @VertxGen public interface ProxyHandler extends Handler { - static ProxyHandler create(HttpProxy httpProxy) { - return new ProxyHandlerImpl(httpProxy); - } + static ProxyHandler create(WebClient mainWebClient, HttpProxy httpProxy) { + return new ProxyHandlerImpl(mainWebClient, httpProxy); + } - static ProxyHandler create(HttpProxy httpProxy, int port, String host) { - return new ProxyHandlerImpl(httpProxy, port, host); - } + static ProxyHandler create(HttpProxy httpProxy) { + return new ProxyHandlerImpl(httpProxy); + } + + static ProxyHandler create(HttpProxy httpProxy, int port, String host) { + return new ProxyHandlerImpl(httpProxy, port, host); + } } diff --git a/sf-vertx/src/main/java/com/sf/vertx/handle/ProxyHandlerImpl.java b/sf-vertx/src/main/java/com/sf/vertx/handle/ProxyHandlerImpl.java index 9a751c1..e2051dc 100644 --- a/sf-vertx/src/main/java/com/sf/vertx/handle/ProxyHandlerImpl.java +++ b/sf-vertx/src/main/java/com/sf/vertx/handle/ProxyHandlerImpl.java @@ -3,25 +3,34 @@ package com.sf.vertx.handle; import com.sf.vertx.httpproxy.HttpProxy; import io.vertx.ext.web.RoutingContext; +import io.vertx.ext.web.client.WebClient; /** * @author Emad Alblueshi */ - public class ProxyHandlerImpl implements ProxyHandler { - private final HttpProxy httpProxy; + private final HttpProxy httpProxy; + private WebClient mainWebClient; - public ProxyHandlerImpl(HttpProxy httpProxy) { - this.httpProxy = httpProxy; - } + public ProxyHandlerImpl(WebClient mainWebClient, HttpProxy httpProxy) { + this.httpProxy = httpProxy; + this.mainWebClient = mainWebClient; + } - public ProxyHandlerImpl(HttpProxy httpProxy, int port, String host) { - this.httpProxy = httpProxy.origin(port, host); - } + public ProxyHandlerImpl(HttpProxy httpProxy) { + this.httpProxy = httpProxy; + } - @Override - public void handle(RoutingContext ctx) { - httpProxy.handle(ctx.request()); - } -} + public ProxyHandlerImpl(HttpProxy httpProxy, int port, String host) { + this.httpProxy = httpProxy.origin(port, host); + } + + @Override + public void handle(RoutingContext ctx) { + // TODO 改造了这个地方 + httpProxy.handle(mainWebClient, ctx); + // 原始代码只有如下一句 + // httpProxy.handle(ctx.request()); + } +} \ No newline at end of file diff --git a/sf-vertx/src/main/java/com/sf/vertx/handle/SacRouteRequestHandlerImpl.java b/sf-vertx/src/main/java/com/sf/vertx/handle/SacRouteRequestHandlerImpl.java index 580bbbb..b711fdc 100644 --- a/sf-vertx/src/main/java/com/sf/vertx/handle/SacRouteRequestHandlerImpl.java +++ b/sf-vertx/src/main/java/com/sf/vertx/handle/SacRouteRequestHandlerImpl.java @@ -1,8 +1,9 @@ package com.sf.vertx.handle; import static com.sf.vertx.constans.SACConstants.API_SERVICE_TYPE; +import static com.sf.vertx.constans.SACConstants.CACHE_KEY_CONNECTOR; import static org.apache.commons.lang3.StringUtils.EMPTY; -import static com.sf.vertx.constans.SACConstants.API_SERVICE_TYPE_SAC; + import java.util.HashMap; import java.util.Map; @@ -13,13 +14,16 @@ import com.sf.vertx.api.pojo.AppConfig; import com.sf.vertx.enums.GatewayError; import com.sf.vertx.enums.RequestMethod; import com.sf.vertx.exception.ServiceException; +import com.sf.vertx.pojo.SacCircuitBreaker; import com.sf.vertx.utils.AppUtils; import com.sf.vertx.utils.ProxyTool; import cn.hutool.core.util.StrUtil; import io.vertx.circuitbreaker.CircuitBreaker; +import io.vertx.circuitbreaker.OpenCircuitException; import io.vertx.core.buffer.Buffer; import io.vertx.core.http.HttpHeaders; +import io.vertx.core.impl.NoStackTraceThrowable; import io.vertx.core.json.JsonObject; import io.vertx.core.net.SocketAddress; import io.vertx.ext.web.RoutingContext; @@ -36,10 +40,10 @@ public class SacRouteRequestHandlerImpl implements SacRouteRequestHandler { this.mainWebClient = mainWebClient; } - private void breakerCall(RoutingContext ctx, CircuitBreaker circuitBreaker, HttpRequest requestBuffer, + private void breakerCall(RoutingContext ctx, SacCircuitBreaker sacCircuitBreaker, HttpRequest requestBuffer, String body) { String appCode = AppUtils.getAppConfigFromRoutingContext(ctx).getAppCode(); - circuitBreaker.executeWithFallback(promise -> { + sacCircuitBreaker.getCircuitBreaker().executeWithFallback(promise -> { requestBuffer.sendJson(body, h -> { if (h.succeeded()) { log.info("==========uri:{},response http code:{}", ctx.request().uri(), h.result().statusCode()); @@ -52,18 +56,25 @@ public class SacRouteRequestHandlerImpl implements SacRouteRequestHandler { promise.fail("2"); } JsonObject responseData = h.result().bodyAsJsonObject(); - log.info("responseData:{}", responseData); + //log.info("responseData:{}", responseData); Buffer buffer; // 加密 if (AppConfigHandler.isDataSecurity(appCode)) { String dataStr = AppConfigHandler.bodyEncrypt(responseData.toString(), appCode); - log.info("encrypt dataStr:{}", dataStr); + //log.info("encrypt dataStr:{}", dataStr); buffer = Buffer.buffer(dataStr); } else { buffer = responseData.toBuffer(); } - ctx.response().setChunked(true).setStatusCode(200).putHeader("Content-Type", "application/json") - .end(buffer); + + Integer statusCode = h.result().statusCode() > 0 ? h.result().statusCode() : 200; + // TODO 和客户端组件沟通 +// String contentType = h.result().headers().get(HttpHeaders.CONTENT_TYPE) != null +// ? h.result().headers().get(HttpHeaders.CONTENT_TYPE) +// : "application/json"; + String contentType = "application/json"; + ctx.response().setChunked(true).setStatusCode(statusCode) + .putHeader(HttpHeaders.CONTENT_TYPE, contentType).end(buffer); } else { // end(proxyRequest, 502); // Throwable throwable = new Throwable("error port"); @@ -72,18 +83,27 @@ public class SacRouteRequestHandlerImpl implements SacRouteRequestHandler { } }); }, v -> { - // 需要传递当前状态half-open , close, 还是统计失败次数 - log.info(circuitBreaker.name() + " executed when the circuit is opened:{}", v.getMessage()); + log.info(sacCircuitBreaker.getCircuitBreaker().name() + " executed when the circuit is opened:{}", v); + if (v instanceof OpenCircuitException) { + // v value is null, default return 3 + log.info(sacCircuitBreaker.getCircuitBreaker().name() + " open circuit"); + } else if (v instanceof NoStackTraceThrowable) { + log.info(sacCircuitBreaker.getCircuitBreaker().name() + " close circuit"); + return v.getMessage(); + } else { + log.info(sacCircuitBreaker.getCircuitBreaker().name() + " half open circuit"); + return v.getMessage(); + } return "3"; }, ar -> { - log.info(circuitBreaker.name() + " interface failed result.{} ", ar); + log.info(sacCircuitBreaker.getCircuitBreaker().name() + " interface failed result.{} ", ar); if (StringUtils.equals(ar.result(), "3")) { // 全开,熔断 - ctx.fail(new ServiceException(GatewayError.BAD_GATEWAY)); + ctx.fail(new ServiceException(GatewayError.REQUEST_URL_IS_BROKEN, sacCircuitBreaker.getStrategy().getDefaultResponse())); } }); } - private void jsonCall(RoutingContext ctx, HttpRequest requestBuffer, String body) { + private void normalCall(RoutingContext ctx, HttpRequest requestBuffer, String body) { String appCode = AppUtils.getAppConfigFromRoutingContext(ctx).getAppCode(); requestBuffer.sendJson(body, h -> { if (h.succeeded()) { @@ -131,7 +151,7 @@ public class SacRouteRequestHandlerImpl implements SacRouteRequestHandler { } requestBuffer.timeout(apiConfig.getTimeout()); // 超时 requestBuffer.putHeaders(ctx.request().headers()); - // 处理sac请求方式 + // 处理sac请求方式/{a}/{b} RequestMethod requestMethod = RequestMethod.getByCode(ctx.request().method().name()); if (RequestMethod.GET.equals(requestMethod) || RequestMethod.DELETE.equals(requestMethod) || RequestMethod.HEAD.equals(requestMethod)) { @@ -154,19 +174,20 @@ public class SacRouteRequestHandlerImpl implements SacRouteRequestHandler { // 判断body是否解析 AppConfig appConfig = AppUtils.getAppConfigFromRoutingContext(ctx); ApiConfig apiConfig = AppUtils.getApiConfigFromRoutingContext(ctx); + String apiServiceType = ctx.get(API_SERVICE_TYPE); String contentType = ctx.request().headers().get(HttpHeaders.CONTENT_TYPE); - if (AppUtils.isAnalysisBody(appConfig, apiConfig, contentType)) { - String keyCircuitBreaker = appConfig.getAppCode() + ":" + apiConfig.getApiCode() + ":" + "CIRCUIT_BREAKER"; - CircuitBreaker circuitBreaker = AppConfigHandler.getApiCodeCircuitBreaker(keyCircuitBreaker); + if (AppUtils.isAnalysisBody(appConfig, apiConfig, apiServiceType, contentType)) { + String keyCircuitBreaker = appConfig.getAppCode() + CACHE_KEY_CONNECTOR + apiConfig.getApiCode(); + SacCircuitBreaker sacCircuitBreaker = AppConfigHandler.getApiCodeCircuitBreaker(keyCircuitBreaker); String body = AppUtils.isEnableDataSecurity(appConfig) ? AppConfigHandler.bodyDecrypt(ctx.body().asString(), appConfig.getAppCode()) : ctx.body().asString(); HttpRequest requestBuffer = buildCallRequestBuffer(ctx, body, apiConfig); try { - if (circuitBreaker != null) { - breakerCall(ctx, circuitBreaker, requestBuffer, body); + if (sacCircuitBreaker != null && sacCircuitBreaker.getCircuitBreaker() != null) { + breakerCall(ctx, sacCircuitBreaker, requestBuffer, body); } else { - jsonCall(ctx, requestBuffer, body); + normalCall(ctx, requestBuffer, body); } } catch (Exception e) { e.printStackTrace(); diff --git a/sf-vertx/src/main/java/com/sf/vertx/httpproxy/HttpProxy.java b/sf-vertx/src/main/java/com/sf/vertx/httpproxy/HttpProxy.java index 1979174..10b6af3 100644 --- a/sf-vertx/src/main/java/com/sf/vertx/httpproxy/HttpProxy.java +++ b/sf-vertx/src/main/java/com/sf/vertx/httpproxy/HttpProxy.java @@ -10,6 +10,11 @@ */ package com.sf.vertx.httpproxy; +import java.util.function.BiFunction; +import java.util.function.Function; + +import com.sf.vertx.httpproxy.impl.ReverseProxy; + import io.vertx.codegen.annotations.Fluent; import io.vertx.codegen.annotations.GenIgnore; import io.vertx.codegen.annotations.VertxGen; @@ -20,13 +25,11 @@ import io.vertx.core.http.HttpClientRequest; import io.vertx.core.http.HttpServerRequest; import io.vertx.core.http.RequestOptions; import io.vertx.core.net.SocketAddress; +import io.vertx.ext.web.RoutingContext; +import io.vertx.ext.web.client.WebClient; import io.vertx.httpproxy.ProxyInterceptor; import io.vertx.httpproxy.ProxyOptions; -import com.sf.vertx.httpproxy.impl.ReverseProxy; -import java.util.function.BiFunction; -import java.util.function.Function; - /** * Handles the HTTP reverse proxy logic between the user agent and the origin. *

@@ -118,4 +121,5 @@ public interface HttpProxy extends Handler { */ void handle(HttpServerRequest request); + void handle(WebClient mainWebClient, RoutingContext ctx); } diff --git a/sf-vertx/src/main/java/com/sf/vertx/httpproxy/impl/ReverseProxy.java b/sf-vertx/src/main/java/com/sf/vertx/httpproxy/impl/ReverseProxy.java index 4cfa5e5..9f73446 100644 --- a/sf-vertx/src/main/java/com/sf/vertx/httpproxy/impl/ReverseProxy.java +++ b/sf-vertx/src/main/java/com/sf/vertx/httpproxy/impl/ReverseProxy.java @@ -10,6 +10,8 @@ */ package com.sf.vertx.httpproxy.impl; +import static org.apache.commons.lang3.StringUtils.EMPTY; + import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -17,11 +19,21 @@ import java.util.ListIterator; import java.util.Map; import java.util.function.BiFunction; +import org.apache.commons.lang3.StringUtils; + +import com.sf.vertx.enums.GatewayError; +import com.sf.vertx.enums.RequestMethod; import com.sf.vertx.handle.AppConfigHandler; import com.sf.vertx.httpproxy.HttpProxy; +import com.sf.vertx.utils.AppUtils; +import com.sf.vertx.utils.ProxyTool; +import cn.hutool.core.util.StrUtil; +import io.vertx.circuitbreaker.CircuitBreaker; +import io.vertx.circuitbreaker.OpenCircuitException; import io.vertx.core.Future; import io.vertx.core.Promise; +import io.vertx.core.buffer.Buffer; import io.vertx.core.http.HttpClient; import io.vertx.core.http.HttpClientRequest; import io.vertx.core.http.HttpClientResponse; @@ -29,7 +41,14 @@ import io.vertx.core.http.HttpHeaders; import io.vertx.core.http.HttpMethod; import io.vertx.core.http.HttpServerRequest; import io.vertx.core.http.HttpServerResponse; +import io.vertx.core.impl.NoStackTraceThrowable; +import io.vertx.core.json.JsonObject; import io.vertx.core.net.NetSocket; +import io.vertx.core.net.SocketAddress; +import io.vertx.ext.web.RoutingContext; +import io.vertx.ext.web.client.HttpRequest; +import io.vertx.ext.web.client.WebClient; +import io.vertx.httpproxy.Body; import io.vertx.httpproxy.ProxyContext; import io.vertx.httpproxy.ProxyInterceptor; import io.vertx.httpproxy.ProxyOptions; @@ -37,223 +56,410 @@ import io.vertx.httpproxy.ProxyRequest; import io.vertx.httpproxy.ProxyResponse; import io.vertx.httpproxy.cache.CacheOptions; import io.vertx.httpproxy.spi.cache.Cache; +import lombok.extern.slf4j.Slf4j; +@Slf4j public class ReverseProxy implements HttpProxy { - private final HttpClient client; - private final boolean supportWebSocket; - private BiFunction> selector = (req, client) -> Future.failedFuture("No origin available"); - private final List interceptors = new ArrayList<>(); + private final HttpClient client; + private final boolean supportWebSocket; + private BiFunction> selector = (req, client) -> Future + .failedFuture("No origin available"); + private final List interceptors = new ArrayList<>(); + private RoutingContext ctx; + private WebClient mainWebClient; - public ReverseProxy(ProxyOptions options, HttpClient client) { - CacheOptions cacheOptions = options.getCacheOptions(); - if (cacheOptions != null) { - Cache cache = cacheOptions.newCache(); - addInterceptor(new CachingFilter(cache)); - } - this.client = client; - this.supportWebSocket = options.getSupportWebSocket(); - } + public ReverseProxy(ProxyOptions options, HttpClient client) { + CacheOptions cacheOptions = options.getCacheOptions(); + if (cacheOptions != null) { + Cache cache = cacheOptions.newCache(); + addInterceptor(new CachingFilter(cache)); + } + this.client = client; + this.supportWebSocket = options.getSupportWebSocket(); + } - @Override - public HttpProxy originRequestProvider(BiFunction> provider) { - selector = provider; - return this; - } + @Override + public HttpProxy originRequestProvider( + BiFunction> provider) { + selector = provider; + return this; + } - @Override - public HttpProxy addInterceptor(ProxyInterceptor interceptor) { - interceptors.add(interceptor); - return this; - } + @Override + public HttpProxy addInterceptor(ProxyInterceptor interceptor) { + interceptors.add(interceptor); + return this; + } + @Override + public void handle(WebClient mainWebClient, RoutingContext ctx) { + // TODO 改造了这个地方 + this.ctx = ctx; + this.mainWebClient = mainWebClient; + handle(ctx.request()); + } - @Override - public void handle(HttpServerRequest request) { - ProxyRequest proxyRequest = ProxyRequest.reverseProxy(request); + @Override + public void handle(HttpServerRequest request) { + ProxyRequest proxyRequest = ProxyRequest.reverseProxy(request); - // Encoding sanity check - Boolean chunked = HttpUtils.isChunked(request.headers()); - if (chunked == null) { - end(proxyRequest, 400); - return; - } + // Encoding sanity check + Boolean chunked = HttpUtils.isChunked(request.headers()); + if (chunked == null) { + end(proxyRequest, 400); + return; + } - // WebSocket upgrade tunneling - if (supportWebSocket && io.vertx.core.http.impl.HttpUtils.canUpgradeToWebSocket(request)) { - handleWebSocketUpgrade(proxyRequest); - return; - } + // WebSocket upgrade tunneling + if (supportWebSocket && io.vertx.core.http.impl.HttpUtils.canUpgradeToWebSocket(request)) { + handleWebSocketUpgrade(proxyRequest); + return; + } - Proxy proxy = new Proxy(proxyRequest); - proxy.filters = interceptors.listIterator(); - proxy.sendRequest().compose(proxy::sendProxyResponse); - } + Proxy proxy = new Proxy(proxyRequest); + proxy.filters = interceptors.listIterator(); + proxy.sendRequest().compose(proxy::sendProxyResponse); + } - private void handleWebSocketUpgrade(ProxyRequest proxyRequest) { - HttpServerRequest proxiedRequest = proxyRequest.proxiedRequest(); - resolveOrigin(proxiedRequest).onComplete(ar -> { - if (ar.succeeded()) { - HttpClientRequest request = ar.result(); - request.setMethod(HttpMethod.GET); - request.setURI(proxiedRequest.uri()); - request.headers().addAll(proxiedRequest.headers()); - Future fut2 = request.connect(); - proxiedRequest.handler(request::write); - proxiedRequest.endHandler(v -> request.end()); - proxiedRequest.resume(); - fut2.onComplete(ar2 -> { - if (ar2.succeeded()) { - HttpClientResponse proxiedResponse = ar2.result(); - if (proxiedResponse.statusCode() == 101) { - HttpServerResponse response = proxiedRequest.response(); - response.setStatusCode(101); - response.headers().addAll(proxiedResponse.headers()); - Future otherso = proxiedRequest.toNetSocket(); - otherso.onComplete(ar3 -> { - if (ar3.succeeded()) { - NetSocket responseSocket = ar3.result(); - NetSocket proxyResponseSocket = proxiedResponse.netSocket(); - responseSocket.handler(proxyResponseSocket::write); - proxyResponseSocket.handler(responseSocket::write); - responseSocket.closeHandler(v -> proxyResponseSocket.close()); - proxyResponseSocket.closeHandler(v -> responseSocket.close()); - } else { - // Find reproducer - System.err.println("Handle this case"); - ar3.cause().printStackTrace(); - } - }); - } else { - // Rejection - proxiedRequest.resume(); - end(proxyRequest, proxiedResponse.statusCode()); - } - } else { - proxiedRequest.resume(); - end(proxyRequest, 502); - } - }); - } else { - proxiedRequest.resume(); - end(proxyRequest, 502); - } - }); - } + private void handleWebSocketUpgrade(ProxyRequest proxyRequest) { + HttpServerRequest proxiedRequest = proxyRequest.proxiedRequest(); + resolveOrigin(proxiedRequest).onComplete(ar -> { + if (ar.succeeded()) { + HttpClientRequest request = ar.result(); + request.setMethod(HttpMethod.GET); + request.setURI(proxiedRequest.uri()); + request.headers().addAll(proxiedRequest.headers()); + Future fut2 = request.connect(); + proxiedRequest.handler(request::write); + proxiedRequest.endHandler(v -> request.end()); + proxiedRequest.resume(); + fut2.onComplete(ar2 -> { + if (ar2.succeeded()) { + HttpClientResponse proxiedResponse = ar2.result(); + if (proxiedResponse.statusCode() == 101) { + HttpServerResponse response = proxiedRequest.response(); + response.setStatusCode(101); + response.headers().addAll(proxiedResponse.headers()); + Future otherso = proxiedRequest.toNetSocket(); + otherso.onComplete(ar3 -> { + if (ar3.succeeded()) { + NetSocket responseSocket = ar3.result(); + NetSocket proxyResponseSocket = proxiedResponse.netSocket(); + responseSocket.handler(proxyResponseSocket::write); + proxyResponseSocket.handler(responseSocket::write); + responseSocket.closeHandler(v -> proxyResponseSocket.close()); + proxyResponseSocket.closeHandler(v -> responseSocket.close()); + } else { + // Find reproducer + System.err.println("Handle this case"); + ar3.cause().printStackTrace(); + } + }); + } else { + // Rejection + proxiedRequest.resume(); + end(proxyRequest, proxiedResponse.statusCode()); + } + } else { + proxiedRequest.resume(); + end(proxyRequest, 502); + } + }); + } else { + proxiedRequest.resume(); + end(proxyRequest, 502); + } + }); + } - private void end(ProxyRequest proxyRequest, int sc) { - proxyRequest - .response() - .release() - .setStatusCode(sc) - .putHeader(HttpHeaders.CONTENT_LENGTH, "0") - .setBody(null) - .send(); - } + /*** + * 返回错误 + * + * @param proxyRequest + * @param sc + */ + private void end(ProxyRequest proxyRequest, int sc) { + JsonObject json = AppUtils.getResponseJsonByGatewayError(GatewayError.getByCode(sc)); + proxyRequest.response().release().setStatusCode(500).putHeader("content-type", "application/json") + .putHeader(AppConfigHandler.sacResponseHeaderKey(), String.valueOf(sc)) + .putHeader(HttpHeaders.CONTENT_LENGTH, String.valueOf(json.size())).setBody(Body.body(json.toBuffer())) + .send(); + } - private Future resolveOrigin(HttpServerRequest proxiedRequest) { - return selector.apply(proxiedRequest, client); - } + private Future resolveOrigin(HttpServerRequest proxiedRequest) { + return selector.apply(proxiedRequest, client); + } - private class Proxy implements ProxyContext { + private class Proxy implements ProxyContext { - private final ProxyRequest request; - private ProxyResponse response; - private final Map attachments = new HashMap<>(); - private ListIterator filters; + private final ProxyRequest request; + private ProxyResponse response; + private final Map attachments = new HashMap<>(); + private ListIterator filters; - private Proxy(ProxyRequest request) { - this.request = request; - } + private Proxy(ProxyRequest request) { + this.request = request; + } - @Override - public void set(String name, Object value) { - attachments.put(name, value); - } + @Override + public void set(String name, Object value) { + attachments.put(name, value); + } - @Override - public T get(String name, Class type) { - Object o = attachments.get(name); - return type.isInstance(o) ? type.cast(o) : null; - } + @Override + public T get(String name, Class type) { + Object o = attachments.get(name); + return type.isInstance(o) ? type.cast(o) : null; + } - @Override - public ProxyRequest request() { - return request; - } + @Override + public ProxyRequest request() { + return request; + } - @Override - public Future sendRequest() { - if (filters.hasNext()) { - ProxyInterceptor next = filters.next(); - return next.handleProxyRequest(this); - } else { - return sendProxyRequest(request); - } - } + @Override + public Future sendRequest() { + if (filters.hasNext()) { + ProxyInterceptor next = filters.next(); + return next.handleProxyRequest(this); + } else { + return sendProxyRequest(request); + } + } - @Override - public ProxyResponse response() { - return response; - } + @Override + public ProxyResponse response() { + return response; + } - @Override - public Future sendResponse() { - if (filters.hasPrevious()) { - ProxyInterceptor filter = filters.previous(); - return filter.handleProxyResponse(this); - } else { - return response.send(); - } - } + @Override + public Future sendResponse() { + if (filters.hasPrevious()) { + ProxyInterceptor filter = filters.previous(); + return filter.handleProxyResponse(this); + } else { + return response.send(); + } + } - private Future sendProxyRequest(ProxyRequest proxyRequest) { - Future f = resolveOrigin(proxyRequest.proxiedRequest()); - f.onFailure(err -> { - // Should this be done here ? I don't think so - HttpServerRequest proxiedRequest = proxyRequest.proxiedRequest(); - proxiedRequest.resume(); - Promise promise = Promise.promise(); - proxiedRequest.exceptionHandler(promise::tryFail); - proxiedRequest.endHandler(promise::tryComplete); - promise.future().onComplete(ar2 -> { - end(proxyRequest, 502); - }); - }); - return f.compose(a -> sendProxyRequest(proxyRequest, a)); - } + private Future breakerCall(CircuitBreaker circuitBreaker, ProxyRequest proxyRequest, + HttpRequest requestBuffer, String body) { + String appCode = proxyRequest.headers().get(AppConfigHandler.getAppCodeHeaderKey()); + return Future.future(p -> { + circuitBreaker.executeWithFallback(promise -> { + requestBuffer.sendJson(body, h -> { + if (h.succeeded()) { + log.info("==========uri:{},response http code:{}", proxyRequest.getURI(), + h.result().statusCode()); + if (h.result().statusCode() == 200) { + // promise.complete(); + promise.complete("1"); + } else { + // Throwable throwable = new Throwable("error port"); + // promise.fail(throwable); + promise.fail("2"); + } + // 释放资源 + proxyRequest.release(); + JsonObject responseData = h.result().bodyAsJsonObject(); + log.info("responseData:{}", responseData); + Buffer buffer; + // 加密 + if (AppConfigHandler.isDataSecurity(appCode)) { + String dataStr = AppConfigHandler.bodyEncrypt(responseData.toString(), appCode); + log.info("encrypt dataStr:{}", dataStr); + buffer = Buffer.buffer(dataStr); + } else { + buffer = responseData.toBuffer(); + } + ProxyResponse proxyResponse = proxyRequest.response().setStatusCode(200) + .putHeader("content-type", "application/json").setBody(Body.body(buffer)); + p.complete(proxyResponse); + } else { + // end(proxyRequest, 502); + // Throwable throwable = new Throwable("error port"); + // promise.fail(throwable); + promise.fail("3"); + } + }); + }, v -> { + log.info(circuitBreaker.name() + " executed when the circuit is opened:{}", v); + if (v instanceof OpenCircuitException) { + log.info(circuitBreaker.name() + " open circuit"); + } else if (v instanceof NoStackTraceThrowable) { + log.info(circuitBreaker.name() + " close circuit"); + return v.getMessage(); + } else { + log.info(circuitBreaker.name() + " half open circuit"); + return v.getMessage(); + } + return "3"; + }, ar -> { + log.info(circuitBreaker.name() + " interface failed result.{} ", ar); + if (StringUtils.equals(ar.result(), "3")) { // 全开,熔断 + end(proxyRequest, 10016); + } + }); + }); + } - private void setConnectionTimeout(ProxyRequest proxyRequest, HttpClientRequest request) { - String appCode = proxyRequest.headers().get(AppConfigHandler.getAppCodeHeaderKey()); - String apiCode = proxyRequest.headers().get(AppConfigHandler.getApiCodeHeaderKey()); - String key = appCode + ":" + apiCode; - request.idleTimeout(AppConfigHandler.getApicodeConfigTimeOut(key)); - } - - private Future sendProxyRequest(ProxyRequest proxyRequest, HttpClientRequest request) { - Future fut = proxyRequest.send(request); - // 超时 - setConnectionTimeout(proxyRequest, request); - fut.onFailure(err -> { - proxyRequest.proxiedRequest().response().setStatusCode(502).end(); - }); - return fut; - } + private Future normalCall(ProxyRequest proxyRequest, HttpRequest requestBuffer, + String body) { + String appCode = proxyRequest.headers().get(AppConfigHandler.getAppCodeHeaderKey()); + return Future.future(p -> { + requestBuffer.sendJson(body, h -> { + if (h.succeeded()) { + log.info("==========uri:{},response http code:{}", proxyRequest.getURI(), + h.result().statusCode()); + if (h.result().statusCode() == 200) { + // 释放资源 + proxyRequest.release(); + JsonObject responseData = h.result().bodyAsJsonObject(); + log.info("responseData:{}", responseData); + Buffer bodyBuffer = responseData.toBuffer(); + // 加密 + if (AppConfigHandler.isDataSecurity(appCode)) { + String dataStr = AppConfigHandler.bodyEncrypt(responseData.toString(), appCode); + log.info("encrypt dataStr:{}", dataStr); + bodyBuffer = Buffer.buffer(dataStr); + } + ProxyResponse proxyResponse = proxyRequest.response().setStatusCode(200) + .putHeader("content-type", "application/json").setBody(Body.body(bodyBuffer)); + p.complete(proxyResponse); + } + } else { + log.info("interface retrun error.{}", proxyRequest.getURI()); + end(proxyRequest, 502); + } + }); + }); + } - private Future sendProxyResponse(ProxyResponse response) { + private HttpRequest buildCallRequestBuffer(ProxyRequest proxyRequest, String body) { + String appCode = proxyRequest.headers().get(AppConfigHandler.getAppCodeHeaderKey()); + String apiCode = proxyRequest.headers().get(AppConfigHandler.getApiCodeHeaderKey()); + String key = appCode + ":" + apiCode; + SocketAddress socketAddress = ProxyTool.resolveOriginAddress(proxyRequest.proxiedRequest()); + HttpRequest requestBuffer; + String requestURI = proxyRequest.getURI(); + switch (proxyRequest.getMethod().name()) { + case "PUT": + requestBuffer = mainWebClient.put(socketAddress.port(), socketAddress.host(), requestURI); + break; + case "DELETE": + requestBuffer = mainWebClient.delete(socketAddress.port(), socketAddress.host(), requestURI); + break; + case "HEAD": + requestBuffer = mainWebClient.head(socketAddress.port(), socketAddress.host(), requestURI); + break; + case "GET": + requestBuffer = mainWebClient.get(socketAddress.port(), socketAddress.host(), requestURI); + break; + default: + requestBuffer = mainWebClient.post(socketAddress.port(), socketAddress.host(), requestURI); + break; + } + requestBuffer.timeout(AppConfigHandler.getApicodeConfigTimeOut(key)); + requestBuffer.putHeaders(proxyRequest.headers()); + // 处理sac请求方式 + RequestMethod requestMethod = RequestMethod.getByCode(proxyRequest.getMethod().name()); + if (RequestMethod.GET.equals(requestMethod) || RequestMethod.DELETE.equals(requestMethod) + || RequestMethod.HEAD.equals(requestMethod)) { + JsonObject jsonBody = new JsonObject(body); + Map queryParams = new HashMap<>(); + for (Map.Entry entry : jsonBody) { + String val = entry.getValue() != null ? entry.getValue().toString() : EMPTY; + queryParams.put(entry.getKey(), val); + requestURI = StrUtil.replace(requestURI, "{" + entry.getKey() + "}", val); + } + requestBuffer.uri(requestURI); + requestBuffer.queryParams().addAll(queryParams); + } + return requestBuffer; + } - this.response = response; + private Future sendProxyRequest(ProxyRequest proxyRequest) { + // 判断
+ // 1、是否配置全局加解密.
+ // 2、apiCode 配置熔断 +// AppConfig appConfig = AppUtils.getAppConfigFromRoutingContext(ctx); +// ApiConfig apiConfig = AppUtils.getApiConfigFromRoutingContext(ctx); +// String apiServiceType = ctx.get(API_SERVICE_TYPE); +// String contentType = ctx.request().headers().get(HttpHeaders.CONTENT_TYPE); +// String keyCircuitBreaker = appConfig.getAppCode() + ":" + apiConfig.getApiCode() + ":" + "CIRCUIT_BREAKER"; +// CircuitBreaker circuitBreaker = AppConfigHandler.getApiCodeCircuitBreaker(keyCircuitBreaker); +// if (AppUtils.isAnalysisBody(appConfig, apiConfig, apiServiceType, contentType)) { +// String body = AppConfigHandler.isDataSecurity(appConfig.getAppCode()) +// ? AppConfigHandler.bodyDecrypt(ctx.body().asString(), appConfig.getAppCode()) +// : ctx.body().asString(); +// HttpRequest requestBuffer = buildCallRequestBuffer(proxyRequest, body); +// try { +// if (circuitBreaker != null) { +// return breakerCall(circuitBreaker, proxyRequest, requestBuffer, body); +// } else { +// return normalCall(proxyRequest, requestBuffer, body); +// } +// } catch (Exception e) { +// e.printStackTrace(); +// int errorCode = 10014; +// if (e instanceof HttpException) { +// errorCode = ((HttpException) e).getStatusCode(); +// } +// throw new HttpException(errorCode); +// } +// } else { + Future f = resolveOrigin(proxyRequest.proxiedRequest()); + f.onFailure(err -> { + log.info("error:", err); + // Should this be done here ? I don't think so + HttpServerRequest proxiedRequest = proxyRequest.proxiedRequest(); + proxiedRequest.resume(); + Promise promise = Promise.promise(); + proxiedRequest.exceptionHandler(promise::tryFail); + proxiedRequest.endHandler(promise::tryComplete); + promise.future().onComplete(ar2 -> { + end(proxyRequest, 502); + }); + }); + return f.compose(a -> sendProxyRequest(proxyRequest, a)); +// } - // Check validity - Boolean chunked = HttpUtils.isChunked(response.headers()); - if (chunked == null) { - // response.request().release(); // Is it needed ??? - end(response.request(), 501); - return Future.succeededFuture(); // should use END future here ??? - } + } - return sendResponse(); - } - } + private Future sendProxyRequest(ProxyRequest proxyRequest, HttpClientRequest request) { + String appCode = proxyRequest.headers().get(AppConfigHandler.getAppCodeHeaderKey()); + String apiCode = proxyRequest.headers().get(AppConfigHandler.getApiCodeHeaderKey()); + String key = appCode + ":" + apiCode; + request.setTimeout(AppConfigHandler.getApicodeConfigTimeOut(key)); + Future fut = proxyRequest.send(request); + fut.onFailure(err -> { + JsonObject errorJson = AppUtils.getResponseJsonByGatewayError(GatewayError.BAD_GATEWAY); + proxyRequest.response().release().setStatusCode(500).putHeader("content-type", "application/json") + .putHeader(AppConfigHandler.sacResponseHeaderKey(), + String.valueOf(GatewayError.BAD_GATEWAY.getCode())) + .putHeader(HttpHeaders.CONTENT_LENGTH, String.valueOf(errorJson.size())) + .setBody(Body.body(errorJson.toBuffer())).send(); + // proxyRequest.proxiedRequest().response().setStatusCode(502).end(); + }); + return fut; + } + + private Future sendProxyResponse(ProxyResponse response) { + + this.response = response; + + // Check validity + Boolean chunked = HttpUtils.isChunked(response.headers()); + if (chunked == null) { + // response.request().release(); // Is it needed ??? + end(response.request(), 501); + return Future.succeededFuture(); // should use END future here ??? + } + + return sendResponse(); + } + + } } diff --git a/sf-vertx/src/main/java/com/sf/vertx/pojo/SacCircuitBreaker.java b/sf-vertx/src/main/java/com/sf/vertx/pojo/SacCircuitBreaker.java new file mode 100644 index 0000000..537ebd8 --- /dev/null +++ b/sf-vertx/src/main/java/com/sf/vertx/pojo/SacCircuitBreaker.java @@ -0,0 +1,13 @@ +package com.sf.vertx.pojo; + +import com.sf.vertx.api.pojo.Strategy; + +import io.vertx.circuitbreaker.CircuitBreaker; +import lombok.Data; + +@Data +public class SacCircuitBreaker { + + private CircuitBreaker circuitBreaker; + private Strategy strategy; +} diff --git a/sf-vertx/src/main/java/com/sf/vertx/security/MainSecurity.java b/sf-vertx/src/main/java/com/sf/vertx/security/MainSecurity.java index 5068206..1285299 100644 --- a/sf-vertx/src/main/java/com/sf/vertx/security/MainSecurity.java +++ b/sf-vertx/src/main/java/com/sf/vertx/security/MainSecurity.java @@ -74,5 +74,5 @@ public class MainSecurity { // + " }\n" // + "}", "dadddsdfadfadsfa33323223")); // System.out.println(aesDecrypt("59A69B6BBCF046C3CF9953C5CC078CC638602D454BBCE8CF8F0DA6AF1F3A4707686263C834A612C5C6F22D9F897B13B434A53E32AAD4036E12A5098565AB1AD352B400FC23354ECE977DDC670F793992D7F884264A9689B000E37157B4D41351", "dadddsdfadfadsfa33323223")); - } + } } diff --git a/sf-vertx/src/main/java/com/sf/vertx/security/RSAUtil.java b/sf-vertx/src/main/java/com/sf/vertx/security/RSAUtil.java index 44b1059..118c2f2 100644 --- a/sf-vertx/src/main/java/com/sf/vertx/security/RSAUtil.java +++ b/sf-vertx/src/main/java/com/sf/vertx/security/RSAUtil.java @@ -26,123 +26,129 @@ import lombok.extern.slf4j.Slf4j; @Slf4j public class RSAUtil { - // RSA最大加密明文大小 - private static final int MAX_ENCRYPT_BLOCK = 117; + // RSA最大加密明文大小 + private static final int MAX_ENCRYPT_BLOCK = 117; - // RSA最大解密密文大小 - private static final int MAX_DECRYPT_BLOCK = 128; + // RSA最大解密密文大小 + private static final int MAX_DECRYPT_BLOCK = 128; - private RSAUtil() { - } + private RSAUtil() { + } - /** - * 获取公钥和私钥对,key为公钥,value为私钥 - * - * @return - * @throws NoSuchAlgorithmException - */ - public static Map genKeyPair() throws NoSuchAlgorithmException { - KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA"); - keyPairGen.initialize(1024, new SecureRandom()); - KeyPair keyPair = keyPairGen.generateKeyPair(); - RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate(); - RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic(); - String publicKeyString = null; - String privateKeyString = null; + /** + * 获取公钥和私钥对,key为公钥,value为私钥 + * + * @return + * @throws NoSuchAlgorithmException + */ + public static Map genKeyPair() throws NoSuchAlgorithmException { + KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA"); + keyPairGen.initialize(1024, new SecureRandom()); + KeyPair keyPair = keyPairGen.generateKeyPair(); + RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate(); + RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic(); + String publicKeyString = null; + String privateKeyString = null; - try { - publicKeyString = new String(Base64.encodeBase64(publicKey.getEncoded()), "UTF-8"); - privateKeyString = new String(Base64.encodeBase64(privateKey.getEncoded()), "UTF-8"); - } catch (UnsupportedEncodingException var7) { - var7.printStackTrace(); - } + try { + publicKeyString = new String(Base64.encodeBase64(publicKey.getEncoded()), "UTF-8"); + privateKeyString = new String(Base64.encodeBase64(privateKey.getEncoded()), "UTF-8"); + } catch (UnsupportedEncodingException var7) { + var7.printStackTrace(); + } - Map keyPairMap = new HashMap<>(); - keyPairMap.put("publicKey", publicKeyString); - keyPairMap.put("privateKey", privateKeyString); - return keyPairMap; - } + Map keyPairMap = new HashMap<>(); + keyPairMap.put("publicKey", publicKeyString); + keyPairMap.put("privateKey", privateKeyString); + return keyPairMap; + } - public static String encrypt(String str, String publicKey) throws Exception { - byte[] decoded = Base64.decodeBase64(publicKey); - RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance("RSA") - .generatePublic(new X509EncodedKeySpec(decoded)); - Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); - cipher.init(1, pubKey); - // 分段加密 - // URLEncoder编码解决中文乱码问题 - byte[] data = URLEncoder.encode(str, "UTF-8").getBytes("UTF-8"); - // 加密时超过117字节就报错。为此采用分段加密的办法来加密 - byte[] enBytes = null; - for (int i = 0; i < data.length; i += MAX_ENCRYPT_BLOCK) { - // 注意要使用2的倍数,否则会出现加密后的内容再解密时为乱码 - byte[] doFinal = cipher.doFinal(ArrayUtils.subarray(data, i, i + MAX_ENCRYPT_BLOCK)); - enBytes = ArrayUtils.addAll(enBytes, doFinal); - } - return Base64.encodeBase64String(enBytes); - } + public static String encrypt(String str, String publicKey) throws Exception { + byte[] decoded = Base64.decodeBase64(publicKey); + RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance("RSA") + .generatePublic(new X509EncodedKeySpec(decoded)); + Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); + cipher.init(1, pubKey); + // 分段加密 + // URLEncoder编码解决中文乱码问题 + byte[] data = URLEncoder.encode(str, "UTF-8").getBytes("UTF-8"); + // 加密时超过117字节就报错。为此采用分段加密的办法来加密 + byte[] enBytes = null; + for (int i = 0; i < data.length; i += MAX_ENCRYPT_BLOCK) { + // 注意要使用2的倍数,否则会出现加密后的内容再解密时为乱码 + byte[] doFinal = cipher.doFinal(ArrayUtils.subarray(data, i, i + MAX_ENCRYPT_BLOCK)); + enBytes = ArrayUtils.addAll(enBytes, doFinal); + } + String outStr = Base64.encodeBase64String(enBytes); + return outStr; + } - /** - * 公钥分段解密 - * - * @param str - * @param privateKey - * @return - * @throws Exception - */ - public static String decrypt(String str, String privateKey) throws Exception { - // 获取公钥 - byte[] decoded = Base64.decodeBase64(privateKey); - RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance("RSA") - .generatePrivate(new PKCS8EncodedKeySpec(decoded)); - Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); - cipher.init(2, priKey); - byte[] data = Base64.decodeBase64(str.getBytes("UTF-8")); + /** + * 公钥分段解密 + * + * @param str + * @param privateKey + * @return + * @throws Exception + */ + public static String decrypt(String str, String privateKey) throws Exception { + // 获取公钥 + byte[] decoded = Base64.decodeBase64(privateKey); + RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance("RSA") + .generatePrivate(new PKCS8EncodedKeySpec(decoded)); + Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); + cipher.init(2, priKey); + byte[] data = Base64.decodeBase64(str.getBytes("UTF-8")); - // 返回UTF-8编码的解密信息 - int inputLen = data.length; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - int offSet = 0; - byte[] cache; - int i = 0; - // 对数据分段解密 - while (inputLen - offSet > 0) { - if (inputLen - offSet > MAX_DECRYPT_BLOCK) { - cache = cipher.doFinal(data, offSet, MAX_DECRYPT_BLOCK); - } else { - cache = cipher.doFinal(data, offSet, inputLen - offSet); - } - out.write(cache, 0, cache.length); - i++; - offSet = i * 128; - } - byte[] decryptedData = out.toByteArray(); - out.close(); - return URLDecoder.decode(new String(decryptedData, "UTF-8"), "UTF-8"); - } + // 返回UTF-8编码的解密信息 + int inputLen = data.length; + ByteArrayOutputStream out = new ByteArrayOutputStream(); + int offSet = 0; + byte[] cache; + int i = 0; + // 对数据分段解密 + while (inputLen - offSet > 0) { + if (inputLen - offSet > MAX_DECRYPT_BLOCK) { + cache = cipher.doFinal(data, offSet, MAX_DECRYPT_BLOCK); + } else { + cache = cipher.doFinal(data, offSet, inputLen - offSet); + } + out.write(cache, 0, cache.length); + i++; + offSet = i * 128; + } + byte[] decryptedData = out.toByteArray(); + out.close(); + return URLDecoder.decode(new String(decryptedData, "UTF-8"), "UTF-8"); + } public static void main(String[] args) throws Exception { - Map keyMap = genKeyPair(); + Map keyMap = genKeyPair(); String publicKey = keyMap.get("publicKey"); String privateKey = keyMap.get("privateKey"); - privateKey = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAIBjjfp2vkdIDzw9vTzei9S1Gg8KLfPWNYfESwgqGvPY/ps3rIfgPH4na3qy957AY/zHExjaPGbbBRBRPV3xg1vrccr0oZLPiC5n7+4Z5TR6wYiPOn3osSjCweUJ7LttOTAr8sqvaHlrDbpZD+ZoOiB0TEWWD9TvI4pK0sVs7JYRAgMBAAECgYAJ08T3c80Y/u2mnGmunfC5U3LnDY4KpN30Uky1d2aYfWawqhRnUp1CwUDvc4EzajHFFJZUP8khjNhwgS1nsk+t9fnz/GJSS2ZYIOn/i1WEKCJvCILuFpx9tqQM1I9EdueeW1VQgm24o6vbBTP6JzoRXN/l/dAGldluY+Y2JclVeQJBAIyZdxIo1G7qs2nbKkynQaPY/ogmn7VLTWwowri1bhWt0zzcDu3/TgLLPldWVwYUuRChyVvX3cuQB0ICwiKTB3kCQQDpxGufjUgalAZwe+RCxIDriKVvYmB/krk/escAR39Ya6Od7nHSbmdBUmc7vjLbVN3BsYWZrlxHnGelEetebqVZAkBJrxvR7of2YRYJwgxXA8jIv64VWHiWoJJAvtPdzWeWAPUVjhZc8FHH8RAI4XzV+QJMDx3h/i2Ew0SqeZuYVwmxAkBh2T3TQyfzOBKZ8sHQ0L/F1ySoQt1xiNDRqWqyyzqaoDOUX8J0+pFt3jgn4a0X8aYA9XWepkUqFGWtyppipJ3BAkEAigeRnLS/J4Z6inWy4XJfFrggYvtQvWQnGfjHNQijm7+c8Nb+gs2EjbkEHg13yFUpBa3sVPN+aOhP2R41t4EywA=="; - publicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCAY436dr5HSA88Pb083ovUtRoPCi3z1jWHxEsIKhrz2P6bN6yH4Dx+J2t6sveewGP8xxMY2jxm2wUQUT1d8YNb63HK9KGSz4guZ+/uGeU0esGIjzp96LEowsHlCey7bTkwK/LKr2h5aw26WQ/maDogdExFlg/U7yOKStLFbOyWEQIDAQAB"; + privateKey = "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAK4gHFgxhaAhq7UEqNOkz/0mEgdGc7hChqI6tUmT44VYAkWkWtmgOPclhAXjLAPy5Y7HbwQF/6D5TxQgTSlL3cgS+b87jtU7BKpK9zm2leavEdNWAdKpxepeSbj6rrhznbk3luFRtF5cj8JIpTrYQfsxZqmMcPu88oZULCODxEcJAgMBAAECgYAA+yU4/xgPny6Sm97ChoD80k6pzpubAP6URKJMXSQcFBaxtPnZivfU005qNY7qGApXBj69Otw8pC8YvsP+KEsHAmPS78AmzAlh6rojkwl+A1F3a23CyxWKDik/HWsXJ1WSl5ljw/+rW6/38YVfPEKZSOWOTwfYxFWI553j05CVKQJBALkhR60uwGaGpV1ApHwcuaSN6rVQ46D67qmkKG3rLkZJyDziFBabl685UCKiDXqwRoX3UWI0FDqDUhSqoBo/LJUCQQDwyGJiUIAI8bTj6q4+1LxeHMlcJWXaRvOK0BocH+6KpybMKf0R478ziYTtNiaSY45syaDQKofVyE8kzTN37J+lAkAs9EHdcd7ShpudG1dVs/v4U2XNBYlgy84sb2pJ1rPz6XKwJg3Ot5WLvRUSc9tmEWvul/GxMQhAdSb3Ub9y4ChJAkEA7Wj3MO8kvyzr6gpcklEaBkWl+TharBVnTwiPpgmKH6ZeZ9JC2B/SR9OhgG7zK0YEiZlo+bflxVHDT4sQ438pjQJBALIQpdg34BQwWMTx4MxP0Wji51JDZM7h24SReb0RktfsY9s6ZU6mbu3oJNnInD+GQkRJkYNkK4DPrczIxnMpddE="; + publicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCuIBxYMYWgIau1BKjTpM/9JhIHRnO4QoaiOrVJk+OFWAJFpFrZoDj3JYQF4ywD8uWOx28EBf+g+U8UIE0pS93IEvm/O47VOwSqSvc5tpXmrxHTVgHSqcXqXkm4+q64c525N5bhUbReXI/CSKU62EH7MWapjHD7vPKGVCwjg8RHCQIDAQAB"; log.info("publicKey = " + publicKey); log.info("privateKey = " + privateKey); String originValue = "{\n" - + " \"data\": \"1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说\",\n" - + " \"data1\": \"11是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说\",\n" - + " \"data2\": \"11是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说1是发送到发送到发哈都是开发计划署的环境封建社会的大是大非上对方哈史蒂芬霍金啊说\"\n" - + "}"; + + " \"data\": {\n" + + " \"a\": 1,\n" + + " \"b\": \"dd\"\n" + + " },\n" + + " \"divideHttpUrl\": {\n" + + " \"company\": {\n" + + " \"aesKey\": \"dadddsdfadfadsfa33323223\"\n" + + " }\n" + + " }\n" + + "}"; // 加密前:原数据123456,测试一下 System.out.println("加密前:" + originValue); String encrypt = encrypt(originValue, publicKey); log.info("加密后:" + encrypt); - encrypt = "HxlTvNpgMBj3tcqcXWQc1SFvn8c4nv0HYBlvuVy07BUa1ynQXhhNoT9o7iX5/edJ9xLGITsWRMUfQvuND9ttsyQS44oRmbkRBAdLZQOxaS4hkMDGleWMZII0VgQbULeOd7SEq5Ba2UU7TDySg0VLRgRRgnxt2qUig9Gx/3quQY19Ts9Wu+NBRi1JvCQD5bKi+9BW+jMKIjZ5hx2MwsVVIQDkoQKLcRTV6lejrXdPP7fFo6rG3/OULM7+U/rw2EoC+F+2NRIoEIQj2jclmM8kqAspNJH2NmP/0lsgjay7/nK2nU1Gz/zeQsSVgJmggTUxTImKk5eoqckuNdPD2mwyRQ=="; + encrypt = "Rk3UOW4UG+a/MmnddEvv03mdcv5B2+Rhu7A7mRuu9MgBTBTYrX8RVRgLwXkQq5Wuo8O33/b9n6qGhLX/GDWQ4unuO0IR4wkYwbL5EOXkOmozxScfSyiypu1zD+hSw+B4uMO5LZql+jRJeCtEjph9RZK5EFD186qktUWP1QcKHzGGIM7Ex1YZogWdn6g2I3iyYTStJrofWfUtMQzEj2UUbaAJ/KuCKSXBAJ1oBjmfT856R9TZrHxVXLf5+jNgoUQrSit6ca/hZ8HSZ+rRLf9r+pgAsU0zYLmifRVDc+F819I3XIdi/FNNm9fwNuX7ZpXyKAGP93j8V35uQ6p1ZMw+xQ=="; String decrypt = decrypt(encrypt, privateKey); log.info("解密后:" + decrypt); } } - diff --git a/sf-vertx/src/main/java/com/sf/vertx/utils/AppUtils.java b/sf-vertx/src/main/java/com/sf/vertx/utils/AppUtils.java index c1b3529..ba0de10 100644 --- a/sf-vertx/src/main/java/com/sf/vertx/utils/AppUtils.java +++ b/sf-vertx/src/main/java/com/sf/vertx/utils/AppUtils.java @@ -1,5 +1,6 @@ package com.sf.vertx.utils; +import static com.sf.vertx.constans.SACConstants.CACHE_KEY_CONNECTOR; import static com.sf.vertx.constans.SACConstants.API_CONFIG; import static com.sf.vertx.constans.SACConstants.API_SERVICE_TYPE; import static com.sf.vertx.constans.SACConstants.APP_CONFIG; @@ -18,10 +19,14 @@ import com.sf.vertx.api.pojo.MockResponse; import com.sf.vertx.enums.GatewayError; import com.sf.vertx.enums.GatewayServiceType; import com.sf.vertx.enums.MatchType; +import com.sf.vertx.enums.RequestMethod; import com.sf.vertx.exception.ServiceException; +import com.sf.vertx.handle.AppConfigHandler; +import com.sf.vertx.pojo.SacCircuitBreaker; import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.util.NumberUtil; +import io.vertx.circuitbreaker.CircuitBreaker; import io.vertx.core.json.JsonObject; import io.vertx.ext.web.RoutingContext; import lombok.experimental.UtilityClass; @@ -250,7 +255,12 @@ public class AppUtils { return getResponseJsonByGatewayError(GatewayError.DEFAULT_SERVICE_ERROR); } - public static boolean isAnalysisBody(AppConfig appConfig, ApiConfig apiConfig, String contentType) { + public static boolean isAnalysisBody(AppConfig appConfig, ApiConfig apiConfig,String apiServiceType, String contentType) { + // 不是Mock(是mock模式的话,存在body就解析。) + if (AppUtils.isEnableMockApi(apiConfig)) { + return true; + } + // 文件上传不走加解密 if (StringUtils.startsWith(contentType, "multipart")) { return false; } @@ -260,6 +270,20 @@ public class AppUtils { return false; } - return isEnableDataSecurity(appConfig); + // SAC模式,实际API请求方式GET,DELETE,HEAD请求需要解析body,可能需要二次处理。(SAC模式请求方式参数统一使用body传递) + // SAC模式,如果是POST或者PUT,并且没有设置数据加密则跳过 + if (AppUtils.isSACServiceType(apiServiceType)) { + RequestMethod requestMethod = RequestMethod.getByCode(apiConfig.getMethod()); + if (RequestMethod.GET.equals(requestMethod) + || RequestMethod.DELETE.equals(requestMethod) + || RequestMethod.HEAD.equals(requestMethod)) { + return true; + } + } + + String keyCircuitBreaker = appConfig.getAppCode() + CACHE_KEY_CONNECTOR + apiConfig.getApiCode(); + SacCircuitBreaker sacCircuitBreaker = AppConfigHandler.getApiCodeCircuitBreaker(keyCircuitBreaker); + boolean isDataSecurity = AppUtils.isEnableDataSecurity(appConfig); + return (isDataSecurity || sacCircuitBreaker != null); } }