fix: mock功能缓存

This commit is contained in:
2026-02-04 13:48:35 +08:00
parent c179c0cc11
commit a24e254fc9
6 changed files with 79 additions and 19 deletions

View File

@@ -1,24 +1,10 @@
/*
* Copyright [2022] [https://www.xiaonuo.vip]
*
* Snowy采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
*
* 1.请不要删除和修改根目录下的LICENSE文件。
* 2.请不要删除和修改Snowy源码头部的版权声明。
* 3.本项目代码可免费商业使用,商业使用请保留源码和相关描述文件的项目出处,作者声明等。
* 4.分发源码时候,请注明软件出处 https://www.xiaonuo.vip
* 5.不可二次分发开源参与同类竞品如有想法可联系团队xiaonuobase@qq.com商议合作。
* 6.若您的项目无法满足以上几点需要更多功能代码获取Snowy商业授权许可请在官网购买授权地址为 https://www.xiaonuo.vip
*/
package org.nl.common.annotation; package org.nl.common.annotation;
import java.lang.annotation.*; import java.lang.annotation.*;
/** /**
* 自定义节流防抖注解 * 自定义节流防抖注解
*
* @author xuyuxiang
* @date 2022/6/20 14:25
**/ **/
@Target(ElementType.METHOD) @Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)

View File

@@ -122,6 +122,7 @@ public class MockConfigController {
return CommonResult.data(mockConfigService.detail(mockConfigIdParam)); return CommonResult.data(mockConfigService.detail(mockConfigIdParam));
} }
@SaIgnore
@GetMapping("/test") @GetMapping("/test")
public String test() { public String test() {
return "WELCOME"; return "WELCOME";

View File

@@ -62,4 +62,14 @@ public class MockConfig {
@Schema(description = "更新时间") @Schema(description = "更新时间")
@TableField(fill = FieldFill.UPDATE) @TableField(fill = FieldFill.UPDATE)
private Date updateTime; private Date updateTime;
/**
* 领域方法:生成缓存键
* 缓存键由API路径和方法组合而成用于在缓存中唯一标识配置
*
* @return 格式为 "apiPath:apiMethod" 的缓存键
*/
public String getCacheKey() {
return apiPath + ":" + apiMethod;
}
} }

View File

@@ -52,4 +52,14 @@ public class MockConfigEditParam {
@Schema(description = "是否启用true-启用false-禁用") @Schema(description = "是否启用true-启用false-禁用")
private Boolean isEnabled; private Boolean isEnabled;
/**
* 领域方法:生成缓存键
* 缓存键由API路径和方法组合而成用于在缓存中唯一标识配置
*
* @return 格式为 "apiPath:apiMethod" 的缓存键
*/
public String getCacheKey() {
return apiPath + ":" + apiMethod;
}
} }

View File

@@ -20,6 +20,10 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.nl.tool.mock.core.handle.MockCacheService;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.nl.common.enums.CommonSortOrderEnum; import org.nl.common.enums.CommonSortOrderEnum;
@@ -42,9 +46,19 @@ import java.util.Optional;
* @author liyongde * @author liyongde
* @date 2026/01/28 17:50 * @date 2026/01/28 17:50
**/ **/
@Slf4j
@Service @Service
public class MockConfigServiceImpl extends ServiceImpl<MockConfigMapper, MockConfig> implements MockConfigService { public class MockConfigServiceImpl extends ServiceImpl<MockConfigMapper, MockConfig> implements MockConfigService {
@Resource
private MockCacheService cacheService;
private final ObjectMapper objectMapper;
public MockConfigServiceImpl(ObjectMapper objectMapper) {
this.objectMapper = objectMapper;
}
@Override @Override
public Page<MockConfig> page(MockConfigPageParam mockConfigPageParam) { public Page<MockConfig> page(MockConfigPageParam mockConfigPageParam) {
QueryWrapper<MockConfig> queryWrapper = new QueryWrapper<MockConfig>().checkSqlInjection(); QueryWrapper<MockConfig> queryWrapper = new QueryWrapper<MockConfig>().checkSqlInjection();
@@ -71,6 +85,8 @@ public class MockConfigServiceImpl extends ServiceImpl<MockConfigMapper, MockCon
@Override @Override
public void add(MockConfigAddParam mockConfigAddParam) { public void add(MockConfigAddParam mockConfigAddParam) {
MockConfig mockConfig = BeanUtil.toBean(mockConfigAddParam, MockConfig.class); MockConfig mockConfig = BeanUtil.toBean(mockConfigAddParam, MockConfig.class);
// 更新缓存
cacheService.put(mockConfig.getCacheKey(), mockConfig);
this.save(mockConfig); this.save(mockConfig);
} }
@@ -78,13 +94,33 @@ public class MockConfigServiceImpl extends ServiceImpl<MockConfigMapper, MockCon
@Override @Override
public void edit(MockConfigEditParam mockConfigEditParam) { public void edit(MockConfigEditParam mockConfigEditParam) {
MockConfig mockConfig = this.queryEntity(mockConfigEditParam.getId()); MockConfig mockConfig = this.queryEntity(mockConfigEditParam.getId());
// 记录旧的缓存键(如果路径或方法被更新,需要失效旧缓存)
String oldCacheKey = mockConfig.getCacheKey();
// 验证JSON格式如果提供
if (mockConfigEditParam.getResponseJson() != null) {
validateJson(mockConfigEditParam.getResponseJson());
}
// 如果路径或方法改变了,也要失效新的缓存键
String newCacheKey = mockConfigEditParam.getCacheKey();
if (!oldCacheKey.equals(newCacheKey)) {
cacheService.invalidate(newCacheKey);
}
BeanUtil.copyProperties(mockConfigEditParam, mockConfig); BeanUtil.copyProperties(mockConfigEditParam, mockConfig);
// 更新缓存
cacheService.put(newCacheKey, mockConfig);
this.updateById(mockConfig); this.updateById(mockConfig);
} }
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
@Override @Override
public void delete(List<MockConfigIdParam> mockConfigIdParamList) { public void delete(List<MockConfigIdParam> mockConfigIdParamList) {
for (MockConfigIdParam configIdParam : mockConfigIdParamList) {
MockConfig mockConfig = this.queryEntity(configIdParam.getId());
// 失效缓存
cacheService.invalidate(mockConfig.getCacheKey());
}
// 执行删除 // 执行删除
this.removeByIds(CollStreamUtil.toList(mockConfigIdParamList, MockConfigIdParam::getId)); this.removeByIds(CollStreamUtil.toList(mockConfigIdParamList, MockConfigIdParam::getId));
} }
@@ -110,4 +146,25 @@ public class MockConfigServiceImpl extends ServiceImpl<MockConfigMapper, MockCon
.eq(MockConfig::getApiMethod, apiMethod); .eq(MockConfig::getApiMethod, apiMethod);
return Optional.ofNullable(getOne(wrapper)); return Optional.ofNullable(getOne(wrapper));
} }
/**
* 验证JSON格式
*
* @param json JSON字符串
* @throws IllegalArgumentException 如果JSON格式无效
*/
private void validateJson(String json) {
if (json == null || json.trim().isEmpty()) {
log.error("JSON string is null or empty");
throw new IllegalArgumentException("Response JSON cannot be null or empty");
}
try {
objectMapper.readTree(json);
log.debug("JSON validation passed");
} catch (Exception e) {
log.error("Invalid JSON format: {}", e.getMessage());
throw new IllegalArgumentException("Invalid JSON format: " + e.getMessage(), e);
}
}
} }

View File

@@ -714,12 +714,8 @@ public class GlobalConfigure implements WebMvcConfigurer {
*/ */
@Override @Override
public void addInterceptors(InterceptorRegistry registry) { public void addInterceptors(InterceptorRegistry registry) {
// log.info("Registering MockInterceptor");
registry.addInterceptor(mockInterceptor) registry.addInterceptor(mockInterceptor)
.addPathPatterns("/**") // 拦截所有路径 .addPathPatterns("/**") // 拦截所有路径
.excludePathPatterns(CollectionUtil.newArrayList(NO_CHECK_MOCK)); .excludePathPatterns(CollectionUtil.newArrayList(NO_CHECK_MOCK));
// log.info("MockInterceptor registered successfully");
} }
} }