首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java EE Filter 實戰:敏感詞過濾與請求包裝器模式完整代碼

     編輯:Java 相關知識

場景

用戶提交留言/評論時,自動將敏感詞替換為 ***,不修改業務 Servlet 代碼。

核心思路:請求包裝器

繼承 HttpServletRequestWrapper,重寫 getParameter(),在獲取參數時攔截並替換敏感詞,再將包裝後的 Request 傳遞給下游 Servlet。

敏感詞工具類(單例,支援動態擴展)

public class SensitiveWordUtil {
    private static final List<String> WORDS = new CopyOnWriteArrayList<>();
    static { WORDS.addAll(Arrays.asList("坑貨", "罵人", "傻逼")); } // 初始詞庫
    public static List<String> getWords() { return WORDS; }
    public static void addWord(String w) { if (w != null) WORDS.add(w); }
    public static String filter(String text) {
        if (text == null) return null;
        for (String w : WORDS) text = text.replace(w, "***");
        return text;
    }
}

過濾器實現

@WebFilter("/*")
public class SensitiveFilter implements Filter {
    @Override public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
            throws IOException, ServletException {
        HttpServletRequest httpReq = (HttpServletRequest) req;
        // 包裝請求,攔截 getParameter
        chain.doFilter(new HttpServletRequestWrapper(httpReq) {
            @Override public String getParameter(String name) {
                return SensitiveWordUtil.filter(super.getParameter(name));
            }
            @Override public String[] getParameterValues(String name) {
                String[] vals = super.getParameterValues(name);
                if (vals == null) return null;
                return Arrays.stream(vals).map(SensitiveWordUtil::filter).toArray(String[]::new);
            }
            @Override public Map<String, String[]> getParameterMap() {
                Map<String, String[]> map = super.getParameterMap();
                map.replaceAll((k, v) -> Arrays.stream(v).map(SensitiveWordUtil::filter).toArray(String[]::new));
                return map;
            }
        }, resp);
    }
    @Override public void init(FilterConfig cfg) {}
    @Override public void destroy() {}
}

測試 Servlet

@WebServlet("/submit")
public class SubmitServlet extends HttpServlet {
    @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        String msg = req.getParameter("msg");
        resp.setContentType("text/html;charset=UTF-8");
        resp.getWriter().write("收到內容:" + msg); // 已自動過濾
    }
}

前端表單

<form action="/submit" method="post">
  留言:<textarea name="msg"></textarea><br/>
  <input type="submit" value="提交">
</form>

優勢總結

  • 非侵入式:業務代碼零感知,符合開閉原則
  • 全覆蓋:攔截 getParameter/getParameterValues/getParameterMap 所有入口
  • 可擴展:詞庫支援熱更新,可對接資料庫/配置中心
  • 性能:CopyOnWriteArrayList 讀多寫少場景無鎖讀取
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved