springboot項目敏感詞屏蔽html頁面modelAndView中值基于HandlerInterceptor實現(xiàn)已及外圍接口Response中值屏蔽基于Filter
1 需求背景:
網(wǎng)站內(nèi)容防止觸發(fā)廣告法,需要自動屏蔽些關鍵字;例如: "最", "第一" 等;可以通過后臺配置及時生效
2 html頁面屏蔽實現(xiàn):
中小型公司官網(wǎng)等項目,日訪問量不會很大,而且要考慮SEO問題,而且基本就1個程序員.項目選型大多數(shù)都不會使用前后端分離技術,而是選擇前后端一體單應用,
例如:上古時期的springMVC+JSP 及后來的 springboot + html + 模板引擎(freemark,velocity,thymeleaf).
對于上述需求,要求屏蔽詞語隨時可以更改, 那么就不能在編寫文章入庫時候處理,只能在頁面展示時候屏蔽,
在springboot返回頁面?zhèn)髦禃r使用modelAndView賦值,那么怎么進行敏感詞過濾呢?
其實很簡單,HandlerInterceptor的 postHandle中會直接獲取到modelAndView,對其ModelMap值遍歷過濾就可以;屏蔽的關鍵字需要從數(shù)據(jù)庫中讀取
@Component public class BlackWordsInterceptor implements HandlerInterceptor { @Autowired private BlackWordsUtil blackWordsUtil; @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) { if(modelAndView != null){ ModelMap modelMap = modelAndView.getModelMap(); modelMap.forEach((k,v) -> { try { //跳過敏感詞校驗的key if(!CST.BLACK_WORDS_SKIP_KEY.contains(k)){ String s = BeanUtil.beanToJson(v); s = blackWordsUtil.doFilter(s); //過濾后的值覆蓋舊值 modelMap.addAttribute(k, BeanUtil.jsonToBean(s,v.getClass())); } } catch (Exception e) { } }); } } }
@Component public class BlackWordsUtil { public final String REPLACE_WORDS = "*"; @Autowired private IBlackWordsService blackWordsService; public String doFilter(String str){ if(StringUtils.isBlank(str)){ return str; } List<BlackWords> blackWords = blackWordsService.findAll(); for (BlackWords blackWord : ListUtil.nvlList(blackWords)) { str = str.replaceAll(blackWord.getValue(),getStr(blackWord.getValue().length())); } return str; } private String getStr(int l){ String s = ""; for(int i=0 ; i < l;i++){ s += REPLACE_WORDS; } return s; } }
3 提供接口過濾
@WebFilter(urlPatterns = {"/pc/*","/app/*","/uni/*"}, filterName = "blackWordsFilter")
@Order(1)
// 需要在啟動類加@ServletComponentScan注解 urlPatterns 必須是 /* 結(jié)尾
public class BlackWordsFilter implements Filter {
@Autowired
private BlackWordsUtil blackWordsUtil;
@Override
public void init(FilterConfig filterConfig) throws ServletException {
Filter.super.init(filterConfig);
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
ResponseWrapper wrapperResponse = new ResponseWrapper((HttpServletResponse) response);//轉(zhuǎn)換成代理類
// 這里只攔截返回,直接讓請求過去,如果在請求前有處理,可以在這里處理
chain.doFilter(request, wrapperResponse);
byte[] content = wrapperResponse.getContent();//獲取返回值
//判斷是否有值
if (content != null && content.length > 0) {
String str = new String(content, "UTF-8");
String outStr = blackWordsUtil.doFilter(str);
//把返回值輸出到客戶端
byte[] outBytes = outStr.getBytes();
ServletOutputStream out = response.getOutputStream();
response.setContentLength(outBytes.length);//重新設置返回長度
out.write(outBytes);
out.flush();
}
}
@Override
public void destroy() {
Filter.super.destroy();
}
}
public class ResponseWrapper extends HttpServletResponseWrapper { private ByteArrayOutputStream buffer; private ServletOutputStream out; public ResponseWrapper(HttpServletResponse httpServletResponse) { super(httpServletResponse); buffer = new ByteArrayOutputStream(); out = new WrapperOutputStream(buffer); } @Override public ServletOutputStream getOutputStream() throws IOException { return out; } @Override public void flushBuffer() throws IOException { if (out != null) { out.flush(); } } public byte[] getContent() throws IOException { flushBuffer(); return buffer.toByteArray(); } class WrapperOutputStream extends ServletOutputStream { private ByteArrayOutputStream bos; public WrapperOutputStream(ByteArrayOutputStream bos) { this.bos = bos; } @Override public void write(int b) throws IOException { bos.write(b); } @Override public boolean isReady() { // TODO Auto-generated method stub return false; } @Override public void setWriteListener(WriteListener arg0) { // TODO Auto-generated method stub } } }
4 測試效果
1頁面屏蔽

2 接口屏蔽


浙公網(wǎng)安備 33010602011771號