最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Spring Boot 實(shí)現(xiàn)敏感詞及特殊字符過濾處理

 更新時間:2021年06月29日 10:53:26   作者:Ryan-瑞恩  
這篇文章主要介紹了SpringBoot實(shí)現(xiàn)敏感詞及特殊字符過濾處理方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

背景:

技術(shù)采用的是 Spring Boot ,請求方法主要為 POST, 請求使用較多的注解為 @RequestBody

交付測試人員進(jìn)行測試,測試人員在對模糊搜索模塊進(jìn)行了各種特殊字符的搜索,以至于敏感詞和特殊字符均會入庫。

對于我這樣有情懷的開發(fā)者而言,是不能容忍的。

上來就是干!主要采用

@ControllerAdvice(basePackages = "com.my") 

的方式,對用戶提交的數(shù)據(jù)做處理。

以下是示例代碼,不影響筆者要言表的功能實(shí)現(xiàn):

/**
 * @author Ryan
 * @date 2019/4/25 18:41
 */
@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;
    }
}

由于我們主要針對提交的數(shù)據(jù)做處理,主要入口在 SensitiveWordUtils.apply(o); 這里的 “Object ” 參數(shù),其實(shí)也就是我們 Controller 方法參數(shù)中,打了 @RequestBody 的實(shí)體。我們可以直接在這里,使用一些手段做處理即可。

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

1. 字符串替換;

2. 自定義拋出運(yùn)行時異常;

這樣做的另外一個好處就是,可以在這里統(tǒng)一管理敏感詞。

如果你使用 replaceAll 的話,統(tǒng)一管理上就比較費(fèi)勁了。

最后,筆者把自己寫的反射放在下面,僅供參考,敏感詞替換部分寫了一個“測試“ 作為要替換入口的標(biāo)記。

歡迎各界大佬來扶正!

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
/**
 * @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) {
            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;
    }
    /**
     * @param obj
     * @param field
     * @param clazz
     */
    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();
        }
    }
    /**
     *
     * @param object
     * @param field
     * @param param
     * @throws IllegalAccessException
     */
    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 還有很大的優(yōu)化點(diǎn),我在這里沒有目前只是看看效果,寫的很粗糙,望大神不要噴。

讀者自行實(shí)現(xiàn)一下,我說一下優(yōu)化點(diǎn):

1. 緩存 object 的 String.class 類型的 Field 或者 methodName; 在第一次加載的時候,緩存進(jìn)去;放到 ConcurrentHashMap<ObjectType, List<StringField>> , 是不是感覺清爽了好多;

2. 過濾出來 String 類型的 Field ,其他的類型酌情考慮;

3. 等臣妾的再想想;

Spring Boot 統(tǒng)一敏感詞過濾 demo

對象序列化前的處理

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

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

中進(jìn)行對象數(shù)據(jù)的轉(zhuǎn)換。

@ControllerAdvice
@Slf4j
public 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;
    } 
 
    /**
     * 只支持自定義類型數(shù)據(jù)的敏感詞過濾,考慮遞歸性能
     */
    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();
            }
        }
    }
}

以上為個人經(jīng)驗(yàn),希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • 詳解如何用Java實(shí)現(xiàn)對m3u8直播流抽幀

    詳解如何用Java實(shí)現(xiàn)對m3u8直播流抽幀

    抽幀(frame extraction)是指從視頻流中提取一些特定的幀,通常是關(guān)鍵幀或者隨機(jī)幀,以供后續(xù)處理。這篇文章主要為大家介紹了如何用Java實(shí)現(xiàn)對m3u8直播流抽幀,需要的可以參考一下
    2023-03-03
  • 如何利用IDEA搭建SpringBoot項(xiàng)目整合mybatis實(shí)現(xiàn)簡單的登錄功能

    如何利用IDEA搭建SpringBoot項(xiàng)目整合mybatis實(shí)現(xiàn)簡單的登錄功能

    這篇文章主要介紹了如何利用IDEA搭建SpringBoot項(xiàng)目整合mybatis實(shí)現(xiàn)簡單的登錄功能,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-08-08
  • java刪除文件和文件夾具體實(shí)現(xiàn)

    java刪除文件和文件夾具體實(shí)現(xiàn)

    這篇文章介紹了java刪除文件和文件夾具體實(shí)現(xiàn),有需要的朋友可以參考一下
    2013-10-10
  • ElasticSearch不停機(jī)重建索引延伸思考及優(yōu)化詳解

    ElasticSearch不停機(jī)重建索引延伸思考及優(yōu)化詳解

    這篇文章主要為大家介紹了ElasticSearch不停機(jī)重建索引延伸思考及優(yōu)化詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-02-02
  • Netty中序列化的作用及自定義協(xié)議詳解

    Netty中序列化的作用及自定義協(xié)議詳解

    這篇文章主要介紹了Netty中序列化的作用及自定義協(xié)議詳解,Netty自身就支持很多種協(xié)議比如Http、Websocket等等,但如果用來作為自己的RPC框架通常會自定義協(xié)議,所以這也是本文的重點(diǎn),需要的朋友可以參考下
    2023-12-12
  • SpringSecurity概念及整合ssm框架的示例詳解

    SpringSecurity概念及整合ssm框架的示例詳解

    用戶登錄系統(tǒng)時我們協(xié)助?SpringSecurity?把用戶對應(yīng)的角色、權(quán)限組裝好,同時把各個資源所要求的權(quán)限信息設(shè)定好,剩下的“登錄驗(yàn)證”、“權(quán)限驗(yàn)證”等等工作都交給SpringSecurity,對SpringSecurity整合ssm框架相關(guān)知識感興趣的朋友跟隨小編一起看看吧
    2022-12-12
  • java虛擬機(jī)jvm方法區(qū)實(shí)例講解

    java虛擬機(jī)jvm方法區(qū)實(shí)例講解

    在本篇文章里小編給大家整理的是一篇關(guān)于java虛擬機(jī)jvm方法區(qū)實(shí)例講解內(nèi)容,有興趣的朋友們可以學(xué)習(xí)下。
    2021-02-02
  • Spring AOP中的JDK和CGLib動態(tài)代理哪個效率更高?

    Spring AOP中的JDK和CGLib動態(tài)代理哪個效率更高?

    今天小編就為大家分享一篇關(guān)于Spring AOP中的JDK和CGLib動態(tài)代理哪個效率更高?,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2019-03-03
  • Java線程之線程同步synchronized和volatile詳解

    Java線程之線程同步synchronized和volatile詳解

    這篇文章主要介紹了Java線程之線程同步synchronized和volatile詳解,具有一定參考價值,需要的朋友可以了解下。
    2017-11-11
  • Java棋類游戲?qū)嵺`之中國象棋

    Java棋類游戲?qū)嵺`之中國象棋

    這篇文章主要為大家詳細(xì)介紹了Java棋類游戲中的中國象棋實(shí)現(xiàn)方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-02-02

最新評論

崇仁县| 宿州市| 苍梧县| 揭阳市| 徐闻县| 泰顺县| 米泉市| 洛浦县| 桓台县| 南川市| 府谷县| 杭锦后旗| 万荣县| 巴青县| 九龙城区| 珠海市| 盐源县| 东兴市| 长沙县| 邵阳县| 思茅市| 称多县| 错那县| 乐昌市| 荥阳市| 农安县| 高陵县| 县级市| 龙海市| 卢龙县| 高要市| 肇东市| 黄大仙区| 涞源县| 博罗县| 建昌县| 丽江市| 瑞安市| 油尖旺区| 诸城市| 绥德县|