implements Contex
@Override
public void serialize(final String origin, final JsonGenerator jsonGenerator,
final SerializerProvider serializerProvider) throws IOException {
- Preconditions.checkNotNull(type, "Sensitive type enum should not be null.");
switch (type) {
case CHINESE_NAME:
jsonGenerator.writeString(DesensitizedUtils.chineseName(origin));
diff --git a/pigx-common/pigx-common-core/src/main/java/com/pig4cloud/pigx/common/core/util/DesensitizedUtils.java b/pigx-common/pigx-common-core/src/main/java/com/pig4cloud/pigx/common/core/util/DesensitizedUtils.java
index 3724496e2..ce9d83a8b 100644
--- a/pigx-common/pigx-common-core/src/main/java/com/pig4cloud/pigx/common/core/util/DesensitizedUtils.java
+++ b/pigx-common/pigx-common-core/src/main/java/com/pig4cloud/pigx/common/core/util/DesensitizedUtils.java
@@ -18,7 +18,7 @@
package com.pig4cloud.pigx.common.core.util;
-import org.apache.commons.lang.StringUtils;
+import cn.hutool.core.util.StrUtil;
/**
* 脱敏工具类
@@ -120,7 +120,7 @@ public class DesensitizedUtils {
if (email == null) {
return null;
}
- int index = StringUtils.indexOf(email, "@");
+ int index = StrUtil.indexOf(email, '@');
if (index <= 1) {
return email;
}
diff --git a/pigx-common/pigx-common-core/src/main/java/com/pig4cloud/pigx/common/core/util/WebUtils.java b/pigx-common/pigx-common-core/src/main/java/com/pig4cloud/pigx/common/core/util/WebUtils.java
index 6d600d9aa..300e5cb0f 100644
--- a/pigx-common/pigx-common-core/src/main/java/com/pig4cloud/pigx/common/core/util/WebUtils.java
+++ b/pigx-common/pigx-common-core/src/main/java/com/pig4cloud/pigx/common/core/util/WebUtils.java
@@ -20,12 +20,12 @@
package com.pig4cloud.pigx.common.core.util;
import cn.hutool.core.codec.Base64;
+import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.pig4cloud.pigx.common.core.exception.CheckedException;
import lombok.SneakyThrows;
import lombok.experimental.UtilityClass;
import lombok.extern.slf4j.Slf4j;
-import org.apache.commons.lang.StringUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.ServerHttpRequest;
@@ -179,25 +179,25 @@ public class WebUtils extends org.springframework.web.util.WebUtils {
public String getIP(HttpServletRequest request) {
Assert.notNull(request, "HttpServletRequest is null");
String ip = request.getHeader("X-Requested-For");
- if (StringUtils.isBlank(ip) || UNKNOWN.equalsIgnoreCase(ip)) {
+ if (StrUtil.isBlank(ip) || UNKNOWN.equalsIgnoreCase(ip)) {
ip = request.getHeader("X-Forwarded-For");
}
- if (StringUtils.isBlank(ip) || UNKNOWN.equalsIgnoreCase(ip)) {
+ if (StrUtil.isBlank(ip) || UNKNOWN.equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
- if (StringUtils.isBlank(ip) || UNKNOWN.equalsIgnoreCase(ip)) {
+ if (StrUtil.isBlank(ip) || UNKNOWN.equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
- if (StringUtils.isBlank(ip) || UNKNOWN.equalsIgnoreCase(ip)) {
+ if (StrUtil.isBlank(ip) || UNKNOWN.equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_CLIENT_IP");
}
- if (StringUtils.isBlank(ip) || UNKNOWN.equalsIgnoreCase(ip)) {
+ if (StrUtil.isBlank(ip) || UNKNOWN.equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_X_FORWARDED_FOR");
}
- if (StringUtils.isBlank(ip) || UNKNOWN.equalsIgnoreCase(ip)) {
+ if (StrUtil.isBlank(ip) || UNKNOWN.equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
- return StringUtils.isBlank(ip) ? null : ip.split(",")[0];
+ return StrUtil.isBlank(ip) ? null : ip.split(",")[0];
}
/**
diff --git a/pigx-common/pigx-common-security/src/main/java/org/springframework/cloud/openfeign/PigxFallbackFactory.java b/pigx-common/pigx-common-security/src/main/java/org/springframework/cloud/openfeign/PigxFallbackFactory.java
deleted file mode 100644
index 1cecb1537..000000000
--- a/pigx-common/pigx-common-security/src/main/java/org/springframework/cloud/openfeign/PigxFallbackFactory.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (c) 2018-2025, lengleng All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * Neither the name of the pig4cloud.com developer nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * Author: lengleng (wangiegie@gmail.com)
- */
-
-package org.springframework.cloud.openfeign;
-
-import feign.Target;
-import feign.hystrix.FallbackFactory;
-import lombok.AllArgsConstructor;
-import org.springframework.cglib.proxy.Enhancer;
-
-/**
- * @author 冷冷
- *
- * 默认 Fallback,避免写过多fallback类
- */
-@AllArgsConstructor
-public class PigxFallbackFactory implements FallbackFactory {
- private final Target target;
-
- @Override
- @SuppressWarnings("unchecked")
- public T create(Throwable cause) {
- final Class targetType = target.type();
- final String targetName = target.name();
- Enhancer enhancer = new Enhancer();
- enhancer.setSuperclass(targetType);
- enhancer.setUseCache(true);
- enhancer.setCallback(new PigxFeignFallback<>(targetType, targetName, cause));
- return (T) enhancer.create();
- }
-}
diff --git a/pigx-common/pigx-common-security/src/main/java/org/springframework/cloud/openfeign/PigxFeignFallback.java b/pigx-common/pigx-common-security/src/main/java/org/springframework/cloud/openfeign/PigxFeignFallback.java
deleted file mode 100644
index 76f52c408..000000000
--- a/pigx-common/pigx-common-security/src/main/java/org/springframework/cloud/openfeign/PigxFeignFallback.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (c) 2018-2025, lengleng All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * Neither the name of the pig4cloud.com developer nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * Author: lengleng (wangiegie@gmail.com)
- */
-
-package org.springframework.cloud.openfeign;
-
-import cn.hutool.core.util.StrUtil;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.pig4cloud.pigx.common.core.util.R;
-import com.pig4cloud.pigx.common.core.util.SpringContextHolder;
-import feign.FeignException;
-import lombok.AllArgsConstructor;
-import lombok.SneakyThrows;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.cglib.proxy.MethodInterceptor;
-import org.springframework.cglib.proxy.MethodProxy;
-import org.springframework.lang.Nullable;
-
-import java.lang.reflect.Method;
-import java.nio.charset.StandardCharsets;
-import java.util.Objects;
-
-/**
- * @author lengleng
- *
- * fallback 代理处理
- */
-@Slf4j
-@AllArgsConstructor
-public class PigxFeignFallback implements MethodInterceptor {
- private final Class targetType;
- private final String targetName;
- private final Throwable cause;
-
- @Nullable
- @Override
- @SneakyThrows
- public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) {
- Class> returnType = method.getReturnType();
- if (R.class != returnType) {
- return null;
- }
- FeignException exception = (FeignException) cause;
-
- byte[] content = exception.content();
-
- String str = StrUtil.str(content, StandardCharsets.UTF_8);
-
- log.error("PigxFeignFallback:[{}.{}] serviceId:[{}] message:[{}]", targetType.getName(), method.getName(), targetName, str);
- ObjectMapper objectMapper = SpringContextHolder.getBean(ObjectMapper.class);
- return objectMapper.readValue(str, R.class);
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) {
- return true;
- }
- if (o == null || getClass() != o.getClass()) {
- return false;
- }
- PigxFeignFallback> that = (PigxFeignFallback>) o;
- return targetType.equals(that.targetType);
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(targetType);
- }
-}
diff --git a/pigx-common/pigx-common-security/src/main/java/org/springframework/cloud/openfeign/PigxHystrixTargeter.java b/pigx-common/pigx-common-security/src/main/java/org/springframework/cloud/openfeign/PigxHystrixTargeter.java
deleted file mode 100644
index 4246a9368..000000000
--- a/pigx-common/pigx-common-security/src/main/java/org/springframework/cloud/openfeign/PigxHystrixTargeter.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Copyright (c) 2018-2025, lengleng All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * Neither the name of the pig4cloud.com developer nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * Author: lengleng (wangiegie@gmail.com)
- */
-
-package org.springframework.cloud.openfeign;
-
-import feign.Feign;
-import feign.Target;
-import feign.hystrix.FallbackFactory;
-import feign.hystrix.HystrixFeign;
-import feign.hystrix.SetterFactory;
-import org.springframework.lang.Nullable;
-
-/**
- * @author lengleng
- *
- * 注入默认的 fallbackFactory
- */
-@SuppressWarnings("unchecked")
-class PigxHystrixTargeter implements Targeter {
-
- @Override
- public T target(FeignClientFactoryBean factory, Feign.Builder feign, FeignContext context,
- Target.HardCodedTarget target) {
- if (!(feign instanceof HystrixFeign.Builder)) {
- return feign.target(target);
- }
- HystrixFeign.Builder builder = (HystrixFeign.Builder) feign;
- SetterFactory setterFactory = getOptional(factory.getName(), context, SetterFactory.class);
- if (setterFactory != null) {
- builder.setterFactory(setterFactory);
- }
- Class> fallback = factory.getFallback();
- if (fallback != void.class) {
- return targetWithFallback(factory.getName(), context, target, builder, fallback);
- }
- Class> fallbackFactory = factory.getFallbackFactory();
- if (fallbackFactory != void.class) {
- return targetWithFallbackFactory(factory.getName(), context, target, builder, fallbackFactory);
- }
-
- PigxFallbackFactory pigxFallbackFactory = new PigxFallbackFactory(target);
- return (T) builder.target(target, pigxFallbackFactory);
- }
-
- private T targetWithFallbackFactory(String feignClientName, FeignContext context,
- Target.HardCodedTarget target,
- HystrixFeign.Builder builder,
- Class> fallbackFactoryClass) {
- FallbackFactory extends T> fallbackFactory = (FallbackFactory extends T>)
- getFromContext("fallbackFactory", feignClientName, context, fallbackFactoryClass, FallbackFactory.class);
- return builder.target(target, fallbackFactory);
- }
-
-
- private T targetWithFallback(String feignClientName, FeignContext context,
- Target.HardCodedTarget target,
- HystrixFeign.Builder builder, Class> fallback) {
- T fallbackInstance = getFromContext("fallback", feignClientName, context, fallback, target.type());
- return builder.target(target, fallbackInstance);
- }
-
- private T getFromContext(String fallbackMechanism, String feignClientName, FeignContext context, Class> beanType,
- Class targetType) {
- Object fallbackInstance = context.getInstance(feignClientName, beanType);
- if (fallbackInstance == null) {
- throw new IllegalStateException(String.format("No " + fallbackMechanism +
- " instance of type %s found for feign client %s", beanType, feignClientName));
- }
-
- if (!targetType.isAssignableFrom(beanType)) {
- throw new IllegalStateException(String.format(
- "Incompatible " + fallbackMechanism + " instance. Fallback/fallbackFactory of " +
- "type %s is not assignable to %s for feign client %s", beanType, targetType, feignClientName));
- }
- return (T) fallbackInstance;
- }
-
- @Nullable
- private T getOptional(String feignClientName, FeignContext context, Class beanType) {
- return context.getInstance(feignClientName, beanType);
- }
-}
diff --git a/pigx-common/pigx-common-security/src/main/resources/META-INF/spring.factories b/pigx-common/pigx-common-security/src/main/resources/META-INF/spring.factories
index aaa6823bd..7908386a5 100644
--- a/pigx-common/pigx-common-security/src/main/resources/META-INF/spring.factories
+++ b/pigx-common/pigx-common-security/src/main/resources/META-INF/spring.factories
@@ -1,5 +1,4 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
- org.springframework.cloud.openfeign.PigxHystrixFeignTargeterConfiguration,\
com.pig4cloud.pigx.common.security.component.GlobalExceptionHandlerResolver,\
com.pig4cloud.pigx.common.security.component.PigxTokenEnhancer,\
com.pig4cloud.pigx.common.security.service.PigxUserDetailsServiceImpl
diff --git a/pigx-common/pigx-common-sentinel/pom.xml b/pigx-common/pigx-common-sentinel/pom.xml
new file mode 100755
index 000000000..213c65540
--- /dev/null
+++ b/pigx-common/pigx-common-sentinel/pom.xml
@@ -0,0 +1,30 @@
+
+
+
+ com.pig4cloud
+ pigx-common
+ 3.4.0
+
+
+ 4.0.0
+ jar
+ pigx-common-sentinel
+ sentinel服务降级熔断、限流组件
+
+
+ com.pig4cloud
+ pigx-common-core
+
+
+ com.alibaba.cloud
+ spring-cloud-starter-alibaba-sentinel
+
+
+
+ org.springframework.cloud
+ spring-cloud-starter-openfeign
+
+
+
diff --git a/pigx-common/pigx-common-security/src/main/java/org/springframework/cloud/openfeign/PigxHystrixFeignTargeterConfiguration.java b/pigx-common/pigx-common-sentinel/src/main/java/com/pig4cloud/pigx/common/sentinel/SentinelAutoConfigure.java
old mode 100644
new mode 100755
similarity index 60%
rename from pigx-common/pigx-common-security/src/main/java/org/springframework/cloud/openfeign/PigxHystrixFeignTargeterConfiguration.java
rename to pigx-common/pigx-common-sentinel/src/main/java/com/pig4cloud/pigx/common/sentinel/SentinelAutoConfigure.java
index 23430c455..29a4919e9
--- a/pigx-common/pigx-common-security/src/main/java/org/springframework/cloud/openfeign/PigxHystrixFeignTargeterConfiguration.java
+++ b/pigx-common/pigx-common-sentinel/src/main/java/com/pig4cloud/pigx/common/sentinel/SentinelAutoConfigure.java
@@ -15,28 +15,27 @@
* Author: lengleng (wangiegie@gmail.com)
*/
-package org.springframework.cloud.openfeign;
+package com.pig4cloud.pigx.common.sentinel;
-import feign.hystrix.HystrixFeign;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
-import org.springframework.context.annotation.Bean;
+import com.alibaba.csp.sentinel.adapter.servlet.callback.WebCallbackManager;
+import com.pig4cloud.pigx.common.sentinel.handle.PigxUrlBlockHandler;
+import com.pig4cloud.pigx.common.sentinel.parser.PigxHeaderRequestOriginParser;
import org.springframework.context.annotation.Configuration;
-import org.springframework.context.annotation.Primary;
+
+import javax.annotation.PostConstruct;
/**
* @author lengleng
*
- * HystrixFeignTargeter 配置
+ * sentinel 配置
*/
@Configuration
-@ConditionalOnClass(HystrixFeign.class)
-@ConditionalOnProperty("feign.hystrix.enabled")
-public class PigxHystrixFeignTargeterConfiguration {
+public class SentinelAutoConfigure {
- @Bean
- @Primary
- public Targeter pigxFeignTargeter() {
- return new PigxHystrixTargeter();
+ @PostConstruct
+ public void initWebCallbackManager() {
+ WebCallbackManager.setUrlBlockHandler(new PigxUrlBlockHandler());
+ WebCallbackManager.setRequestOriginParser(new PigxHeaderRequestOriginParser());
}
+
}
diff --git a/pigx-common/pigx-common-sentinel/src/main/java/com/pig4cloud/pigx/common/sentinel/handle/PigxUrlBlockHandler.java b/pigx-common/pigx-common-sentinel/src/main/java/com/pig4cloud/pigx/common/sentinel/handle/PigxUrlBlockHandler.java
new file mode 100644
index 000000000..0cdd8115c
--- /dev/null
+++ b/pigx-common/pigx-common-sentinel/src/main/java/com/pig4cloud/pigx/common/sentinel/handle/PigxUrlBlockHandler.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2018-2025, lengleng All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * Neither the name of the pig4cloud.com developer nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ * Author: lengleng (wangiegie@gmail.com)
+ */
+
+package com.pig4cloud.pigx.common.sentinel.handle;
+
+import cn.hutool.http.ContentType;
+import cn.hutool.json.JSONUtil;
+import com.alibaba.csp.sentinel.adapter.servlet.callback.UrlBlockHandler;
+import com.alibaba.csp.sentinel.slots.block.BlockException;
+import com.pig4cloud.pigx.common.core.util.R;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.http.HttpStatus;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
+/**
+ * @author lengleng
+ * @date 2019-10-11
+ *
+ * 降级 限流策略
+ */
+@Slf4j
+public class PigxUrlBlockHandler implements UrlBlockHandler {
+ @Override
+ public void blocked(HttpServletRequest request, HttpServletResponse response, BlockException e) throws IOException {
+
+ log.error("sentinel 降级 资源名称{}", e.getRule().getResource(), e);
+
+ response.setContentType(ContentType.JSON.toString());
+ response.setStatus(HttpStatus.TOO_MANY_REQUESTS.value());
+ response.getWriter().print(
+ JSONUtil.toJsonStr(R.failed(e.getMessage())));
+ }
+}
diff --git a/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/util/package-info.java b/pigx-common/pigx-common-sentinel/src/main/java/com/pig4cloud/pigx/common/sentinel/parser/PigxHeaderRequestOriginParser.java
similarity index 56%
rename from pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/util/package-info.java
rename to pigx-common/pigx-common-sentinel/src/main/java/com/pig4cloud/pigx/common/sentinel/parser/PigxHeaderRequestOriginParser.java
index 62490d11e..efcc91c60 100644
--- a/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/util/package-info.java
+++ b/pigx-common/pigx-common-sentinel/src/main/java/com/pig4cloud/pigx/common/sentinel/parser/PigxHeaderRequestOriginParser.java
@@ -15,16 +15,32 @@
* Author: lengleng (wangiegie@gmail.com)
*/
-/**
- * Hystrix 默认 fallback
- *
- * DefaultProperties: https://github.com/Netflix/Hystrix/issues/1446
- *
- * @author L.cm
- */
-@NonNullApi
-@NonNullFields
-package com.pig4cloud.pigx.common.security.util;
+package com.pig4cloud.pigx.common.sentinel.parser;
-import org.springframework.lang.NonNullApi;
-import org.springframework.lang.NonNullFields;
+import com.alibaba.csp.sentinel.adapter.servlet.callback.RequestOriginParser;
+
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * @author lengleng
+ * @date 2019-10-11
+ *
+ * sentinel 请求头解析判断
+ */
+public class PigxHeaderRequestOriginParser implements RequestOriginParser {
+ /**
+ * 请求头获取allow
+ */
+ private static final String ALLOW = "Allow";
+
+ /**
+ * Parse the origin from given HTTP request.
+ *
+ * @param request HTTP request
+ * @return parsed origin
+ */
+ @Override
+ public String parseOrigin(HttpServletRequest request) {
+ return request.getHeader(ALLOW);
+ }
+}
diff --git a/pigx-common/pigx-common-sentinel/src/main/resources/META-INF/spring.factories b/pigx-common/pigx-common-sentinel/src/main/resources/META-INF/spring.factories
new file mode 100755
index 000000000..c396f293f
--- /dev/null
+++ b/pigx-common/pigx-common-sentinel/src/main/resources/META-INF/spring.factories
@@ -0,0 +1,2 @@
+org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
+ com.pig4cloud.pigx.common.sentinel.SentinelAutoConfigure
diff --git a/pigx-common/pom.xml b/pigx-common/pom.xml
index c2a49742d..fbbb12ef3 100644
--- a/pigx-common/pom.xml
+++ b/pigx-common/pom.xml
@@ -42,6 +42,7 @@
pigx-common-log
pigx-common-minio
pigx-common-security
+ pigx-common-sentinel
pigx-common-sequence
pigx-common-swagger
pigx-common-transaction
diff --git a/pigx-gateway/pom.xml b/pigx-gateway/pom.xml
index f6a4a9d89..0d7a119b2 100644
--- a/pigx-gateway/pom.xml
+++ b/pigx-gateway/pom.xml
@@ -73,6 +73,11 @@
org.springframework.boot
spring-boot-starter-data-redis