文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Spring Boot如何实现敏感词及特殊字符过滤处理

2023-06-20 11:57

关注

这篇文章主要介绍“Spring Boot如何实现敏感词及特殊字符过滤处理”,在日常操作中,相信很多人在Spring Boot如何实现敏感词及特殊字符过滤处理问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Spring Boot如何实现敏感词及特殊字符过滤处理”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

背景:

技术采用的是 Spring Boot ,请求方法主要为 POST, 请求使用较多的注解为 @RequestBody

交付测试人员进行测试,测试人员在对模糊搜索模块进行了各种特殊字符的搜索,以至于敏感词和特殊字符均会入库。

对于我这样有情怀的开发者而言,是不能容忍的。

上来就是干!主要采用

@ControllerAdvice(basePackages = "com.my")

的方式,对用户提交的数据做处理。

以下是示例代码,不影响笔者要言表的功能实现:

@ControllerAdvice(basePackages = "com.ytkj")public class EscapeSensitiveWordFilter implements RequestBodyAdvice {    @Override    public boolean supports(MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) {        return true;    }    @Override    public HttpInputMessage beforeBodyRead(HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) throws IOException {        return inputMessage;    }    @Override    public Object afterBodyRead(Object o, HttpInputMessage httpInputMessage, MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) {        if(o != null){            SensitiveWordUtils.apply(o);        }        return o;    }    @Override    public Object handleEmptyBody(Object o, HttpInputMessage httpInputMessage, MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) {        return o;    }}

由于我们主要针对提交的数据做处理,主要入口在 SensitiveWordUtils.apply(o); 这里的 “Object ” 参数,其实也就是我们 Controller 方法参数中,打了 @RequestBody 的实体。我们可以直接在这里,使用一些手段做处理即可。

这里的手段,也只能使用反射了(如果读者有什么好的方案可以告诉我)。

字符串替换;

自定义抛出运行时异常;

这样做的另外一个好处就是,可以在这里统一管理敏感词。

如果你使用 replaceAll 的话,统一管理上就比较费劲了。

最后,笔者把自己写的反射放在下面,仅供参考,敏感词替换部分写了一个“测试“ 作为要替换入口的标记。

欢迎各界大佬来扶正!

import java.lang.reflect.Field;import java.util.ArrayList;import java.util.Arrays;import java.util.List;import java.util.Map;public class SensitiveWordUtils {        public static Object apply(Object result) {        if (result == null) {            return null;        }        objectParse(result);        return result;    }        public static void objectParse(Object obj) {        List<Field> allField = findAllField(obj);        for (Field field : allField) {            field.setAccessible(true);            Class<?> typeClazz = field.getType();            matchFieldType(obj, field, typeClazz);        }    }    public static List<Field> findAllField(Object object){        List<Field> result = new ArrayList<>();        Class<?> clazz = object.getClass();        while (true) {            clazz = clazz.getSuperclass();            if (clazz == Object.class) {                break;            }            Field[] declaredFields = clazz.getDeclaredFields();            result.addAll(Arrays.asList(declaredFields));        }        return result;    }        public static <T> void matchFieldType(Object obj, Field field, T clazz) {        try {            T param = (T) field.get(obj);            if(param == null){                return;            }            if (clazz == List.class) {                List p = (List)param;                for (Object o : p) {                    objectParse(o);                }            } else if (clazz == String.class) {                setValue(obj, field, "测试");            } else if (clazz == Map.class) {                Map map = (Map)param;                for (Object o : map.keySet()) {                    objectParse(o);                }            }        } catch (IllegalAccessException e) {            e.printStackTrace();        }    }        public static void setValue(Object object, Field field, Object param) throws IllegalAccessException {        if(!field.isAccessible()){            throw new IllegalAccessException("modify the field fail.");        }        field.set(object, param);    }}

这里的 SensitiveWordUtils 还有很大的优化点,我在这里没有目前只是看看效果,写的很粗糙,望大神不要喷。

读者自行实现一下,我说一下优化点:

缓存 object 的 String.class 类型的 Field 或者 methodName; 在第一次加载的时候,缓存进去;放到 ConcurrentHashMap<ObjectType, List<StringField>> , 是不是感觉清爽了好多;

过滤出来 String 类型的 Field ,其他的类型酌情考虑;

等臣妾的再想想;

Spring Boot 统一敏感词过滤 demo

对象序列化前的处理

例如springframework框架(responseBody)json 格式:

org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyAdviceChain#beforeBodyWrite

中进行对象数据的转换。

@ControllerAdvice@Slf4jpublic class ShanDongShengYuHandler implements ResponseBodyAdvice {     @Autowired    private ObjectMapper objectMapper;     @Override    public boolean supports(MethodParameter returnType, Class converterType) {        return true;    }     @Override    public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {        ResponseData d = new ResponseData();        sensitiveHidden(body);        d.setData(body);        return d;    }          private void sensitiveHidden(Object body) {        if(body==null || StringUtils.isBlank(body.getClass().getName()) || !body.getClass().getName().contains("山东")){            return;        }        Field[] declaredFields = body.getClass().getDeclaredFields();        for (Field declaredField : declaredFields) {            SensitiveWorldHidden annotation = declaredField.getAnnotation(SensitiveWorldHidden.class);            log.warn("【注解类型】{}",annotation);            try {                declaredField.setAccessible(true);                Object o = declaredField.get(body);                if(annotation != null) {                    String content = objectMapper.writeValueAsString(o);                    content = content.replace("垃圾", "**");                    Object replaced = objectMapper.readValue(content, o.getClass());                    declaredField.set(body, replaced);                }else {                    sensitiveHidden(o);                }            } catch (IllegalAccessException e) {                e.printStackTrace();            } catch (JsonProcessingException e) {                e.printStackTrace();            } catch (IOException e) {                e.printStackTrace();            }        }    }}

到此,关于“Spring Boot如何实现敏感词及特殊字符过滤处理”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注编程网网站,小编会继续努力为大家带来更多实用的文章!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯