Spring Boot 下,敏感词及特殊字符过滤处理方式

时间:2025-03-18 20:27:22

背景:

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

 

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

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

上来就是干!

 

主要采用  @ControllerAdvice(basePackages = "") 的方式,对用户提交的数据做处理。

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

/**
 * @author Ryan
 * @date 2019/4/25 18:41
 */
@ControllerAdvice(basePackages = "")
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){
            (o);
        }
        return o;
    }

    @Override
    public Object handleEmptyBody(Object o, HttpInputMessage httpInputMessage, MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) {

        return o;
    }
}

 

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

 

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

1. 字符串替换;

2. 自定义抛出运行时异常;

 

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

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

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

欢迎各界大佬来扶正!

 

import ;
import ;
import ;
import ;
import ;

/**
 * @author Ryan
 * @date 2019/4/26 12:40
 */
public class SensitiveWordUtils {


    /**
     * @param result
     * @return
     */
    public static Object apply(Object result) {
        if (result == null) {
            return null;
        }

        objectParse(result);

        return result;
    }



    /**
     * @param obj
     */
    public static void objectParse(Object obj) {
        List<Field> allField = findAllField(obj);
        for (Field field : allField) {
            (true);
            Class<?> typeClazz = ();
            matchFieldType(obj, field, typeClazz);
        }
    }

    public static List<Field> findAllField(Object object){
        List<Field> result = new ArrayList<>();

        Class<?> clazz = ();
        while (true) {
            clazz = ();
            if (clazz == ) {
                break;
            }

            Field[] declaredFields = ();
            ((declaredFields));
        }
        return result;
    }


    /**
     * @param obj
     * @param field
     * @param clazz
     */
    public static <T> void matchFieldType(Object obj, Field field, T clazz) {
        try {
            T param = (T) (obj);
            if(param == null){
                return;
            }

            if (clazz == ) {
                List p = (List)param;
                for (Object o : p) {
                    objectParse(o);
                }
            } else if (clazz == ) {
                setValue(obj, field, "测试");
            } else if (clazz == ) {
                Map map = (Map)param;
                for (Object o : ()) {
                    objectParse(o);
                }
            }
        } catch (IllegalAccessException e) {
            ();
        }
    }

    /**
     *
     * @param object
     * @param field
     * @param param
     * @throws IllegalAccessException
     */
    public static void setValue(Object object, Field field, Object param) throws IllegalAccessException {
        if(!()){
            throw new IllegalAccessException("modify the field fail.");
        }

        (object, param);
    }
}

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

 

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

  1. 缓存 object 的 类型的 Field 或者 methodName; 在第一次加载的时候,缓存进去;放到 ConcurrentHashMap<ObjectType,  List<StringField>>  , 是不是感觉清爽了好多;
  2. 过滤出来 String 类型的 Field ,其他的类型酌情考虑;
  3. 等臣妾的再想想;