用戶提交留言/評論時,自動將敏感詞替換為 ***,不修改業務 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() {}
}
@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 讀多寫少場景無鎖讀取