diff --git a/src/main/java/quant/rich/emoney/EmoneyAutoApplication.java b/src/main/java/quant/rich/emoney/EmoneyAutoApplication.java index 5f839cb..5422ce6 100644 --- a/src/main/java/quant/rich/emoney/EmoneyAutoApplication.java +++ b/src/main/java/quant/rich/emoney/EmoneyAutoApplication.java @@ -11,7 +11,6 @@ import org.springframework.scheduling.annotation.EnableScheduling; @EnableScheduling @EnableFeignClients @SpringBootApplication -@EnableCaching(proxyTargetClass=true) public class EmoneyAutoApplication { public static void main(String[] args) { diff --git a/src/main/java/quant/rich/emoney/component/RequireAuthAndProxyAspect.java b/src/main/java/quant/rich/emoney/component/RequireAuthAndProxyAspect.java index 77b48c7..1a72341 100644 --- a/src/main/java/quant/rich/emoney/component/RequireAuthAndProxyAspect.java +++ b/src/main/java/quant/rich/emoney/component/RequireAuthAndProxyAspect.java @@ -1,7 +1,7 @@ package quant.rich.emoney.component; import org.apache.commons.lang3.StringUtils; -import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.*; import org.aspectj.lang.reflect.MethodSignature; import org.springframework.beans.factory.annotation.Autowired; @@ -20,9 +20,19 @@ import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import java.lang.reflect.Method; +/** + * 注解在受 Spring 管理的类的成员方法上,使其在执行前校验代理状态、鉴权状态 + *
需要开启 AOP:在任意配置类上增加注解: 需要开启 AOP:在任意配置类上增加注解:
+ * 由于 AOP 特性使然, 必须为 public 方法才能生效
+ *
+ * 为防止反复重登录验证, 在同一调用链中的校验, 仅在首次调用时进行检查, 如:
+ * A、B 和 C 方法都添加了本注解, A 中调用 B, B 中调用 C, 则仅在 A 方法执行时才进行检查。
+ *
+ * 为了安全起见, 无论 autoLogin 是否为 true, 只要添加了本注解, 在执行方法前, 最终都会进行
+ * EmoneyClient.reloginCheck(), 如果检查重鉴权失败, 被注解的方法将不会执行,
+ * 并由切片方法抛出异常。如果某个方法并不需要严格控制鉴权的, 可以不用本注解,
+ * 而是由在方法内自行编写逻辑来替代。
+ *
* @see RequireAuthAndProxyAspect
*/
@Target(ElementType.METHOD)
@@ -74,7 +113,8 @@ public class RequireAuthAndProxyAspect {
@Documented
public static @interface RequireAuthAndProxy {
/**
- * 当存在默认请求配置但未鉴权时,是否自动鉴权
+ * 当存在默认请求配置但未鉴权时,是否自动鉴权。由于某些场景下,
+ * 鉴权信息需要系统统一维护,故此区分
* @return
*/
boolean autoLogin() default false;
diff --git a/src/main/java/quant/rich/emoney/config/EmoneyAutoConfig.java b/src/main/java/quant/rich/emoney/config/EmoneyAutoConfig.java
index ff0903d..5212dee 100644
--- a/src/main/java/quant/rich/emoney/config/EmoneyAutoConfig.java
+++ b/src/main/java/quant/rich/emoney/config/EmoneyAutoConfig.java
@@ -1,9 +1,11 @@
package quant.rich.emoney.config;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.context.annotation.Import;
+import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@@ -17,8 +19,10 @@ import quant.rich.emoney.service.ConfigService;
* @author Doghole
*
*/
-@EnableAspectJAutoProxy
@Configuration
+@EnableAsync(proxyTargetClass=true)
+@EnableCaching(proxyTargetClass=true)
+@EnableAspectJAutoProxy(exposeProxy = true, proxyTargetClass = true)
@Import(ConfigAutoRegistrar.class)
public class EmoneyAutoConfig implements WebMvcConfigurer {
diff --git a/src/main/java/quant/rich/emoney/pojo/MultiIndexPlanDetail.java b/src/main/java/quant/rich/emoney/pojo/dto/MultiIndexPlanDetail.java
similarity index 82%
rename from src/main/java/quant/rich/emoney/pojo/MultiIndexPlanDetail.java
rename to src/main/java/quant/rich/emoney/pojo/dto/MultiIndexPlanDetail.java
index 0b9e55e..8c79c49 100644
--- a/src/main/java/quant/rich/emoney/pojo/MultiIndexPlanDetail.java
+++ b/src/main/java/quant/rich/emoney/pojo/dto/MultiIndexPlanDetail.java
@@ -1,4 +1,4 @@
-package quant.rich.emoney.pojo;
+package quant.rich.emoney.pojo.dto;
import java.util.ArrayList;
import java.util.Collections;
@@ -8,10 +8,14 @@ import java.util.Map;
import java.util.Set;
import org.springframework.util.CollectionUtils;
+import org.springframework.validation.annotation.Validated;
+import jakarta.validation.Valid;
+import jakarta.validation.constraints.NotEmpty;
import lombok.Data;
import lombok.experimental.Accessors;
+@Validated
@Data
@Accessors(chain=true)
public class MultiIndexPlanDetail {
@@ -19,11 +23,14 @@ public class MultiIndexPlanDetail {
/**
* 指标
*/
+ @Valid
+ @NotEmpty
List 本例用到的 requestInfo 不需要 PatchOkHttp 覆写,但要求鉴权参数拼接到 url 中,故要求鉴权
* 会一并尝试获取其他在本地未有的无参指标 由于本例需要鉴权, 故在方法上开启了 {@code @RequireAuthAndProxy}, 而本方法被类内其他方法调用, 需要 proxy 才能使 AOP 生效,
+ * 为了使 self 调用成功, 需要在任意配置类上添加 {@code @EnableAspectJAutoProxy(exposeProxy = true)}
* @param indexCode
* @see RequestInfo#getWebviewUserAgent()
* @see RequestInfoService#getDefaultRequestInfo()
* @return
*/
- private NonParamsIndexDetail getNonParamsIndexDetailOnline(Serializable indexCode) {
- String url = buildNonParamsIndexUrl(indexCode);
+ @RequireAuthAndProxy(autoLogin = true)
+ public NonParamsIndexDetail getNonParamsIndexDetailOnline(Serializable indexCode) {
+ String url = self.buildNonParamsIndexUrl(indexCode);
Request request = new Request.Builder()
.url(url)
.header("Host", "appstatic.emoney.cn")
@@ -370,7 +378,7 @@ public class IndexDetailService {
String path = getIndexDetailPath(detail);
// 判断是否是需求的 detail
if (indexCode.toString().equals(detail.getIndexCode())) {
- loadImages(detail);
+ self.loadImages(detail);
targetDetail = detail;
}
// 清洗内容:凡是文本类型的内容的,都要清洗一遍,判断是否有脚本、
@@ -434,7 +442,8 @@ public class IndexDetailService {
* @return
* @see RequestInfo
*/
- private NonParamsIndexDetail loadImages(NonParamsIndexDetail detail) {
+ @RequireAuthAndProxy(autoLogin = true)
+ public NonParamsIndexDetail loadImages(NonParamsIndexDetail detail) {
OkHttpClient client = OkHttpClientProvider.getInstance();
for (NonParamsIndexDetailData data : detail.getData()) {
String imageUrl = data.getImage();
@@ -465,7 +474,7 @@ public class IndexDetailService {
.header("Sec-Fetch-Mode", "no-cors")
.header("Sec-Fetch-Dest", "image")
.header("Accept-Encoding", "gzip, deflate")
- .header("Referer", buildNonParamsIndexUrl(detail.getIndexCode()))
+ .header("Referer", self.buildNonParamsIndexUrl(detail.getIndexCode()))
.header("Accept-Language", "zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7")
.build();
@@ -567,7 +576,8 @@ public class IndexDetailService {
* @return
* @see RequestInfo
*/
- private String buildNonParamsIndexUrl(Serializable indexCode) {
+ @RequireAuthAndProxy(autoLogin = true)
+ public String buildNonParamsIndexUrl(Serializable indexCode) {
RequestInfo requestInfo = requestInfoService.getDefaultRequestInfo();
if (requestInfo == null || StringUtils.isBlank(requestInfo.getAuthorization())) {
diff --git a/src/main/java/quant/rich/emoney/validator/ProxySettingValidator.java b/src/main/java/quant/rich/emoney/validator/ProxySettingValidator.java
index 798d35f..e036719 100644
--- a/src/main/java/quant/rich/emoney/validator/ProxySettingValidator.java
+++ b/src/main/java/quant/rich/emoney/validator/ProxySettingValidator.java
@@ -7,6 +7,7 @@ import org.apache.commons.lang3.StringUtils;
import jakarta.validation.ConstraintValidator;
import jakarta.validation.ConstraintValidatorContext;
import quant.rich.emoney.entity.sqlite.ProxySetting;
+import quant.rich.emoney.interfaces.IValidator;
public class ProxySettingValidator implements IValidator, ConstraintValidator@EnableAspectJAutoProxy
+ */
@Component
@Aspect
public class RequireAuthAndProxyAspect {
+
+ /**
+ * 调用链深度,用以判断同线程同类型切点命中的次数
+ */
+ private static final ThreadLocal@EnableAspectJAutoProxy
+ *