政府项目,BT要求必须用GBK编码,于是 全部JS CSS FTL改成GBK编码格式,问题出现了
改以后的页面,浏览器加载时间特别长,不管是IE还是火狐,明明内容都出来完老,但是浏览器迟迟还是显示加载中,倒是页面的document onload事件需要10秒甚至15秒左右时间才能触发
项目采用了sitemesh,主要用的是meta.decorator,并没有定义excludes的页面,再仔细分析问题,发现声明了meta decorator的页面加载是正常的,恰恰是没有声明meta deracotor的页面加载很慢
分析代码,从struts2的FreemarkerPageFilter一直跟踪到sitemesh的PageFilter,发现sitemesh对于没有装饰器声明的页面是调用的
writeOriginal(request, response, page);
方法来输出原始页面内容,再看 writeOriginal(request, response, page);方法本身
private void writeOriginal(HttpServletRequest request, HttpServletResponse response, Page page) throws IOException {
response.setContentLength(page.getContentLength());
if (request.getAttribute(USING_STREAM).equals(Boolean.TRUE))
{
PrintWriter writer = new PrintWriter(response.getOutputStream());
page.writePage(writer);
//flush writer to underlying outputStream
writer.flush();
response.getOutputStream().flush();
}
else
{
page.writePage(response.getWriter());
response.getWriter().flush();
}
}
很正常的代码,一点问题也没,怎么会出现浏览器加载时间超长的,其实,问题恰恰是第一句话
response.setContentLength(page.getContentLength());
在看sitemesh2.3是如何生成这个conentLength的吧,
public int getContentLength() {
try
{
//todo - this needs to be fixed properly (SIM-196)
return new String(pageData).getBytes("UTF-8").length; // we cannot just measure pageData.length, due to i18n issues (SIM-157)
}
catch (UnsupportedEncodingException e)
{
return new String(pageData).getBytes().length;
}
}
问题的原因已经很明白了,sitemesh是UTF-8编码格式计算响应内容长度,如果页面编码格式非utf-8,就会出现实际输出内容与contentLength不一样的情况,导致浏览器一直处于加载状态。
修改 sitemesh代码,重新打包,问题果然解决