为了那所谓的效率,试用了一下undertow容器,之前在tomcat容器下可以正常拦截的广告代码,在undertow下居然无效了...
费话不多说,直接上代码
错误提示:
ERROR io.undertow.request - [handleThrowable,80] - UT005023: Exception handling request to /druid/js/common.js
java.lang.IllegalStateException: UT010019: Response already commited
at io.undertow.servlet.spec.ServletOutputStreamImpl.resetBuffer(ServletOutputStreamImpl.java:748)
at io.undertow.servlet.spec.HttpServletResponseImpl.resetBuffer(HttpServletResponseImpl.java:514)
at javax.servlet.ServletResponseWrapper.resetBuffer(ServletResponseWrapper.java:190)
at javax.servlet.ServletResponseWrapper.resetBuffer(ServletResponseWrapper.java:190)
at com.dhecp.framework.config.DruidConfig$1.doFilter(DruidConfig.java:109)
at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
tomcat下有效的代码
/**
* 去除监控页面底部的广告
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
@Bean
@ConditionalOnProperty(name = "spring.datasource.druid.statViewServlet.enabled", havingValue = "true")
public FilterRegistrationBean removeDruidFilterRegistrationBean(DruidStatProperties properties)
{
// 获取web监控页面的参数
DruidStatProperties.StatViewServlet config = properties.getStatViewServlet();
// 提取common.js的配置路径
String pattern = config.getUrlPattern() != null ? config.getUrlPattern() : "/druid/*";
String commonJsPattern = pattern.replaceAll("\\*", "js/common.js");
final String filePath = "support/http/resources/js/common.js";
// 创建filter进行过滤
Filter filter = new Filter()
{
@Override
public void init(javax.servlet.FilterConfig filterConfig) throws ServletException
{
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException
{
chain.doFilter(request, response);
// 重置缓冲区,响应头不会被重置
response.resetBuffer();
// 获取common.js
String text = Utils.readFromResource(filePath);
// 正则替换banner, 除去底部的广告信息
text = text.replaceAll("<a.*?banner\"></a><br/>", "");
text = text.replaceAll("powered.*?shrek.wang</a>", "");
response.getWriter().write(text);
}
@Override
public void destroy()
{
}
};
FilterRegistrationBean registrationBean = new FilterRegistrationBean();
registrationBean.setFilter(filter);
registrationBean.addUrlPatterns(commonJsPattern);
return registrationBean;
}
Undertow下有效的方法
@Bean
@ConditionalOnProperty(name = "spring.datasource.druid.statViewServlet.enabled", havingValue = "true")
public FilterRegistrationBean<DruidAdFilter> druidAdFilterRegistration() {
FilterRegistrationBean<DruidAdFilter> registration = new FilterRegistrationBean<>();
registration.setFilter(new DruidAdFilter());
// 设置过滤器匹配的URL模式
registration.addUrlPatterns("/druid/js/common.js");
// 设置过滤器的顺序
registration.setOrder(Integer.MIN_VALUE);
return registration;
}
@WebFilter(filterName = "druidWebStatFilter", urlPatterns = "/druid/*")
public static class DruidAdFilter implements Filter {
private String processedJs;
@Override
public void init(javax.servlet.FilterConfig filterConfig) throws ServletException {
try {
// 在初始化时加载和处理JS文件,避免每次请求都进行读取和处理
ClassPathResource resource = new ClassPathResource("support/http/resources/js/common.js");
byte[] bytes = FileCopyUtils.copyToByteArray(resource.getInputStream());
String originalJs = new String(bytes);
//processedJs = originalJs.replaceAll("<a.*?banner\"></a><br/>", "").replaceAll("powered.*?shrek.wang</a>", "");
// 定义要匹配的正则表达式
String pattern = "<footer class=\"footer\">([\\s\\S]*?)</footer>";
// 编译正则表达式
processedJs = Pattern.compile(pattern).matcher(originalJs).replaceAll("");;
} catch (IOException e) {
throw new ServletException("Failed to load js/common.js", e);
}
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
// 使用自定义响应包装器捕获响应输出
chain.doFilter(request, response);
// 确保仅在需要替换JS内容时才重写响应
if (response.getContentType() != null && response.getContentType().contains("javascript")) {
response.getWriter().write(processedJs);
}
}
@Override
public void destroy() {
// 销毁时清理资源,如果有必要
}
}