Compare commits

..

2 Commits

@ -5,7 +5,7 @@ import javax.servlet.http.HttpServletRequest;
/** /**
* @author heqijun * @author heqijun
* @ClassName: SmsService * @ClassName: SmsService
* @Description: TODO() * @Description: SmsService
* @date 2025/6/5 16:56 * @date 2025/6/5 16:56
*/ */

@ -12,7 +12,7 @@ import javax.servlet.http.HttpServletRequest;
/** /**
* @author heqijun * @author heqijun
* @ClassName: SmsServiceImpl * @ClassName: SmsServiceImpl
* @Description: TODO() * @Description: SmsServiceImpl
* @date 2025/6/5 16:57 * @date 2025/6/5 16:57
*/ */

@ -11,7 +11,7 @@ import java.util.Map;
/** /**
* @author heqijun * @author heqijun
* @ClassName: SendCheckContext * @ClassName: SendCheckContext
* @Description: TODO() * @Description:
* @date 2025/6/4 20:19 * @date 2025/6/4 20:19
*/ */

@ -12,7 +12,7 @@ import java.util.Set;
/** /**
* @author heqijun * @author heqijun
* @ClassName: CacheController * @ClassName: CacheController
* @Description: TODO() * @Description: CacheController
* @date 2025/6/5 13:46 * @date 2025/6/5 13:46
*/ */
@ -76,6 +76,21 @@ public class CacheController {
redisClient.sAdd(key, value); redisClient.sAdd(key, value);
} }
@PostMapping("/sinterstr/{key}/{sinterkey}")
public Set<Object> sinterStr(@PathVariable(value = "key") String key, @PathVariable String sinterkey, @RequestBody String... value) {
log.info("【缓存模块】sinterStr: key = {}sinterkey={}\nvalue = {}", key, sinterkey, value);
//1. 存入key和value
redisClient.sAdd(key, value);
//2. 取交集
Set<Object> result = redisClient.sIntersect(key, sinterkey);
if (result != null && !result.isEmpty()) {
log.info("【缓存模块】sinterStr: 交集={}", result);
}
//3. 删除key
redisClient.delete(key);
return result;
}
@PostMapping("/smember/{key}") @PostMapping("/smember/{key}")
public Set smember(@PathVariable(value = "key") String key) { public Set smember(@PathVariable(value = "key") String key) {
log.info("【缓存模块】smember: key = {}", key); log.info("【缓存模块】smember: key = {}", key);

@ -8,7 +8,7 @@ import java.lang.annotation.Target;
/** /**
* @author heqijun * @author heqijun
* @ClassName: Description * @ClassName: Description
* @Description: TODO() * @Description:
* @date 2025/6/4 20:42 * @date 2025/6/4 20:42
*/ */

@ -3,7 +3,7 @@ package com.mashibing.common.annotation.validParam;
/** /**
* @author heqijun * @author heqijun
* @ClassName: NotNull * @ClassName: NotNull
* @Description: TODO() * @Description: @NotNull
* @date 2025/6/5 11:46 * @date 2025/6/5 11:46
*/ */

@ -42,6 +42,9 @@ public interface BeaconCacheClient {
@PostMapping("cache/saddstr/{key}") @PostMapping("cache/saddstr/{key}")
void saddStr(@PathVariable(value = "key") String key, @RequestBody String... value); void saddStr(@PathVariable(value = "key") String key, @RequestBody String... value);
@PostMapping("cache/sinterstr/{key}/{sinterkey}")
Set<Object> sinterStr(@PathVariable(value = "key") String key, @PathVariable String sinterkey, @RequestBody String... value);
@PostMapping("cache/smember/{key}") @PostMapping("cache/smember/{key}")
Set smember(@PathVariable(value = "key") String key); Set smember(@PathVariable(value = "key") String key);

@ -5,7 +5,7 @@ import lombok.*;
/** /**
* @author heqijun * @author heqijun
* @ClassName: JsonResultCodeEnum * @ClassName: JsonResultCodeEnum
* @Description: TODO() * @Description: JsonResultCode
* @date 2025/6/5 11:57 * @date 2025/6/5 11:57
*/ */

@ -48,6 +48,13 @@
<groupId>org.projectlombok</groupId> <groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId> <artifactId>lombok</artifactId>
</dependency> </dependency>
<!-- ik分词器 -->
<dependency>
<groupId>com.janeluo</groupId>
<artifactId>ikanalyzer</artifactId>
<version>2012_u6</version>
</dependency>
<!-- common公共组件 --> <!-- common公共组件 -->
<dependency> <dependency>
<groupId>com.mashibing</groupId> <groupId>com.mashibing</groupId>

@ -7,16 +7,16 @@ import org.springframework.cloud.openfeign.EnableFeignClients;
/** /**
* @author heqijun * @author heqijun
* @ClassName: StragyApplication * @ClassName: StrategyApplication
* @Description: TODO() * @Description: StrategyApplication
* @date 2025/6/7 19:03 * @date 2025/6/7 19:03
*/ */
@SpringBootApplication @SpringBootApplication
@EnableFeignClients @EnableFeignClients
@EnableDiscoveryClient @EnableDiscoveryClient
public class StragyApplication { public class StrategyApplication {
public static void main(String[] args) { public static void main(String[] args) {
SpringApplication.run(StragyApplication.class, args); SpringApplication.run(StrategyApplication.class, args);
} }
} }

@ -7,7 +7,7 @@ import org.springframework.web.client.RestTemplate;
/** /**
* @author heqijun * @author heqijun
* @ClassName: RestTemplateConfig * @ClassName: RestTemplateConfig
* @Description: TODO() * @Description: RestTemplateConfig
* @date 2025/6/8 16:33 * @date 2025/6/8 16:33
*/ */

@ -15,7 +15,7 @@ import java.io.IOException;
/** /**
* @author heqijun * @author heqijun
* @ClassName: PreSendListener * @ClassName: PreSendListener
* @Description: TODO() * @Description:
* @date 2025/6/7 19:36 * @date 2025/6/7 19:36
*/ */

@ -6,7 +6,7 @@ import lombok.Data;
/** /**
* @author heqijun * @author heqijun
* @ClassName: PhasePOJO * @ClassName: PhasePOJO
* @Description: TODO() * @Description: pojo
* @date 2025/6/8 16:39 * @date 2025/6/8 16:39
*/ */

@ -0,0 +1,51 @@
package com.mashibing.strategy.service.strategyfilter.impl;
import com.mashibing.common.constant.CacheConstant;
import com.mashibing.common.pojo.StandardSubmit;
import com.mashibing.strategy.feignclient.CacheClient;
import com.mashibing.strategy.service.strategyfilter.StrategyFilter;
import com.mashibing.strategy.utils.DirtyWordTree;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.wltea.analyzer.core.IKSegmenter;
import org.wltea.analyzer.core.Lexeme;
import java.io.IOException;
import java.io.StringReader;
import java.util.HashSet;
import java.util.Set;
/**
* @author heqijun
* @ClassName: DirtyWordStrategyFilter
* @Description:
* @date 2025/6/7 20:26
*/
@Slf4j
@Service(value = "dfaDirtyword")
public class DFADirtyWordStrategyFilter implements StrategyFilter {
@Autowired
CacheClient cacheClient;
@Override
public void strategy(StandardSubmit submit) {
log.info("【策略模块-敏感词校验】开始====================================");
String text = submit.getText();
Set<String> set = new HashSet<>();
long start = System.currentTimeMillis();
long end = System.currentTimeMillis();
log.info("【策略模块-敏感词校验】通过敏感词树校验敏感词");
Set<String> result = DirtyWordTree.getDirtyWord(text);
if (!result.isEmpty()) {
log.error("【策略模块-敏感词校验】短信内容包含敏感词:{}", result);
return;
// throw new RuntimeException("短信内容包含敏感词");
}
log.info("【策略模块-敏感词校验】敏感词校验通过");
}
}

@ -1,9 +1,19 @@
package com.mashibing.strategy.service.strategyfilter.impl; package com.mashibing.strategy.service.strategyfilter.impl;
import com.mashibing.common.constant.CacheConstant;
import com.mashibing.common.pojo.StandardSubmit; import com.mashibing.common.pojo.StandardSubmit;
import com.mashibing.strategy.feignclient.CacheClient;
import com.mashibing.strategy.service.strategyfilter.StrategyFilter; import com.mashibing.strategy.service.strategyfilter.StrategyFilter;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.wltea.analyzer.core.IKSegmenter;
import org.wltea.analyzer.core.Lexeme;
import java.io.IOException;
import java.io.StringReader;
import java.util.HashSet;
import java.util.Set;
/** /**
* @author heqijun * @author heqijun
@ -16,8 +26,41 @@ import org.springframework.stereotype.Service;
@Service(value = "dirtyword") @Service(value = "dirtyword")
public class DirtyWordStrategyFilter implements StrategyFilter { public class DirtyWordStrategyFilter implements StrategyFilter {
@Autowired
CacheClient cacheClient;
@Override @Override
public void strategy(StandardSubmit standardSubmit) { public void strategy(StandardSubmit submit) {
log.info("【策略模块-敏感词校验】。。。"); log.info("【策略模块-敏感词校验】开始====================================");
Set<String> set = new HashSet<>();
long start = System.currentTimeMillis();
StringReader reader = new StringReader(submit.getText());
IKSegmenter ik = new IKSegmenter(reader, false);
long end = System.currentTimeMillis();
log.info("【策略模块-敏感词校验】分词器读取短信耗时:{}ms", end - start);
Lexeme lexeme = null;
start = System.currentTimeMillis();
while (true) {
try {
lexeme = ik.next();
} catch (IOException e) {
log.error("【策略模块-敏感词校验】IK分词器处理短信内容异常" + "\n e={}", e.getMessage());
e.printStackTrace();
}
if (lexeme == null) {
break;
}
set.add(lexeme.getLexemeText());
}
end = System.currentTimeMillis();
log.info("【策略模块-敏感词校验】分词耗时:{}ms", end - start);
//交集
Set<Object> result = cacheClient.sinterStr(submit.getSequenceId().toString(), CacheConstant.DIRTY_WORD, set.toArray(new String[0]));
if (result != null && !result.isEmpty()) {
log.error("【策略模块-敏感词校验】短信内容包含敏感词:{}", result);
throw new RuntimeException("短信内容包含敏感词");
}
log.info("【策略模块-敏感词校验】敏感词校验通过");
} }
} }

@ -0,0 +1,116 @@
package com.mashibing.strategy.utils;
import com.mashibing.common.constant.CacheConstant;
import com.mashibing.strategy.feignclient.CacheClient;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
/**
* @author heqijun
* @ClassName: DirtyWordTree
* @Description:
* @date 2025/6/8 21:23
*/
public class DirtyWordTree {
private static final Map DIRTY_WORD_TREE = new HashMap<>();
static {
//通过SpringUtil获取Spring中的CacheClient对象
CacheClient cacheClient = (CacheClient) StringUtil.getBeanByClass(CacheClient.class);
//调用缓存模块接口获取全部敏感词
Set<String> dirtyWords = cacheClient.smember(CacheConstant.DIRTY_WORD);
//构建敏感词树
buildTree(dirtyWords);
}
/**
*
* dfa
* mapkeykeyvaluemap
* mapkeyvaluemap
*
* @param dirtyWordsSet
*/
private static void buildTree(Set<String> dirtyWordsSet) {
Map<String, Map> currentMap;
//遍历每个词
for (String dirtyWord : dirtyWordsSet) {
//外层循环中每次都要指定当前map为最外层map
currentMap = DIRTY_WORD_TREE;
for (int i = 0; i < dirtyWord.length(); i++) {
//获取词中的每个字
String singleWord = String.valueOf(dirtyWord.charAt(i));
//如果当前字不在当前层的map中则添加进去
if (!currentMap.containsKey(singleWord)) {
currentMap.put(singleWord, new HashMap());
}
//当前字对应的map
Map currentWordMap = currentMap.get(singleWord);
//如果当前字的map中妹有isEnd说明这是刚添进去的字要指定isEnd
if (!currentWordMap.containsKey("isEnd") && i < dirtyWord.length() - 1) {
//如果没到当前词末尾说明不是敏感词指定为false
currentWordMap.put("isEnd", false);
} else if (i == dirtyWord.length() - 1) {
//如果到了当前词末尾说明是敏感词指定为true
currentWordMap.put("isEnd", true);
}
//每个词的循环中下一个字要进到下一层map中
currentMap = currentWordMap;
}
}
}
/**
*
*
* @param text
* @return
*/
public static Set<String> getDirtyWord(String text) {
//拿到敏感词树
Map currentMap;
Set<String> result = new HashSet<>();
//遍历文本
for (int i = 0; i < text.length(); i++) {
currentMap = DIRTY_WORD_TREE;
//记录匹配上的敏感字的长度
int dirtyLength = 0;
boolean isDirty = false;
for (int j = i; j < text.length(); j++) {
//当前字
String currentWord = String.valueOf(text.charAt(j));
currentMap = (Map) currentMap.get(currentWord);
if (currentMap == null) {
//没匹配上直接break
break;
}
//匹配上了
dirtyLength++;
//判断是否是敏感词,不是的话,继续下一个字
if ((Boolean) currentMap.get("isEnd")) {
//是敏感词,退出循环,记录匹配到的敏感词
isDirty = true;
break;
}
}
if (isDirty) {
//记录匹配到的敏感词
result.add(text.substring(i, i + dirtyLength));
}
}
return result;
}
private DirtyWordTree() {
}
}

@ -0,0 +1,32 @@
package com.mashibing.strategy.utils;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
/**
* @author heqijun
* @ClassName: StringUtil
* @Description: ioc使springbean
* @date 2025/6/8 23:09
*/
@Component
public class StringUtil implements ApplicationContextAware {
private static ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
StringUtil.applicationContext = applicationContext;
}
public static Object getBeanByName(String beanName) {
return applicationContext.getBean(beanName);
}
public static Object getBeanByClass(Class<?> clazz) {
return applicationContext.getBean(clazz);
}
}

@ -27,6 +27,7 @@ class ClientBusinessMapperTest {
ClientBusiness cb = mapper.findById(1L); ClientBusiness cb = mapper.findById(1L);
cb.setIpAddress("192.168.1.5"); cb.setIpAddress("192.168.1.5");
cb.setClientFilters("phase," + cb.getClientFilters()); cb.setClientFilters("phase," + cb.getClientFilters());
cb.setClientFilters( cb.getClientFilters().replace("dirtyword","dfaDirtyword"));
System.out.println(cb); System.out.println(cb);
ObjectMapper mapper = new ObjectMapper(); ObjectMapper mapper = new ObjectMapper();
cacheClient.hset("client_business:" + cb.getApikey(), mapper.convertValue(cb, Map.class)); cacheClient.hset("client_business:" + cb.getApikey(), mapper.convertValue(cb, Map.class));

Loading…
Cancel
Save