首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 其他教程 > 开源软件 >

Struts2 过滤器处置静态资源的若干bug

2012-06-29 
Struts2 过滤器处理静态资源的若干bug版权所有,转载请注明来源http://gogo1217.iteye.com,违者必究!?? ?St

Struts2 过滤器处理静态资源的若干bug

版权所有,转载请注明来源http://gogo1217.iteye.com,违者必究!??

?

Struts2是一个优秀的MVC框架,在使用中发现struts2的过滤器在处理静态资源的一些问题,现与大家分享解决办法。

?

问题1: struts2的过滤器转发静态资源等待时间超长

??? 最近在使用ext4.1,ext-all.js可不是一般的大,达到了1.2M,在使用struts2的过滤器转发静态资源的时候,发现巨慢无比,但是如果使用ext的Loader动态加载,减小单个文件的大小,则不会出现这样的情况,

??? 初步判断是struts2过滤器的在处理静态资源文件过大的时候出现了问题。

?

通过firebug查看网络请求,对比使用struts2过滤器和未使用struts2过滤器的情况。

1、通过struts2的过滤器的请求,响应头消息中没有设置Content-Length,文件大小为0,加载完成时间达到了1-2m。

?

Struts2 过滤器处置静态资源的若干bug

2、未通过struts2的过滤器转发,响应头消息中Content-Length设置为1264053,文件的大小为1.2M,加载时间在1-2s完成。

?

Struts2 过滤器处置静态资源的若干bug

?

通过分析struts2过滤器的源码,发现默认是使用org.apache.struts2.dispatcher.DefaultStaticContentLoader处理的静态资源。在整个DefaultStaticContentLoader类中,未发现设置Content-Length的代码。

修改思路:在往response中写入数据之前,预先读取文件的大小,写入response中。当然我们可以自己继承该类,对该方法进行覆写。然后将自定义的类配置在struts2的过滤器中,具体代码如下:

?

 public void findStaticResource(String path, HttpServletRequest request, HttpServletResponse response)            throws IOException {        String name = cleanupPath(path);        for (String pathPrefix : pathPrefixes) {            URL resourceUrl = findResource(buildPath(name, pathPrefix));            if (resourceUrl != null) {                InputStream is = null;                try {                    //check that the resource path is under the pathPrefix path                    String pathEnding = buildPath(name, pathPrefix);                    if (resourceUrl.getFile().endsWith(pathEnding)){                    is = resourceUrl.openStream();                    }                } catch (IOException ex) {                    continue;                }                //not inside the try block, as this could throw IOExceptions also                if (is != null) {                //此处为新增代码                String fileName=resourceUrl.getPath();                String realFileName=fileName.replaceAll("\\%20", " ");//由于路径是URL方式,需要对路径进行替换编码                if(fileName.indexOf("file:/")>-1){                realFileName=realFileName.substring(fileName.indexOf("file:/")+6);                }                if(realFileName.startsWith("/")){                realFileName=realFileName.substring(1);                }                if(fileName.indexOf(".jar!/")>0){//如果来源是jar包                String[] paths=realFileName.split("!/");                JarEntry file=new JarFile(paths[0]).getJarEntry(paths[1]);                response.setContentLength((int) file.getSize());                }else{//否则是classes目录下                File file=new File(realFileName);                response.setContentLength((int) file.length());                }                //新增代码结束                                    process(is, path, request, response);                    return;                }            }        }        response.sendError(HttpServletResponse.SC_NOT_FOUND);    }

?

?

问题2:某些静态资源文件经过struts2过滤器后不能正常加载,如ie特有的.htc文件经过过滤器后不能正常使用。

????? 我们知道通过csshover3.htc的加载,能解决ie低版本不能相应css :hover 等一些兼容性问题。但是经过struts2过滤器后,则不能正常加载,经过ie的开发者工具查看,发现contentType未正常设置,可通过修改 org.apache.struts2.dispatcher.DefaultStaticContentLoader的下面方法解决。

当然我们可以自己集成该类,对该方法进行覆写。然后将自定义的类配置在struts2的过滤器中,

    /**     * Determine the content type for the resource name.     *     * @param name The resource name     * @return The mime type     */    protected String getContentType(String name) {        // NOT using the code provided activation.jar to avoid adding yet another dependency        // this is generally OK, since these are the main files we server up        if (name.endsWith(".js")) {            return "text/javascript";        } else if (name.endsWith(".css")) {            return "text/css";        } else if (name.endsWith(".html")) {            return "text/html";        } else if (name.endsWith(".txt")) {            return "text/plain";        } else if (name.endsWith(".gif")) {            return "image/gif";        } else if (name.endsWith(".jpg") || name.endsWith(".jpeg")) {            return "image/jpeg";        } else if (name.endsWith(".png")) {            return "image/png";          //新增处理.htc文件        }else if(name.endsWith(".htc")){        return "text/x-component";        }else {            return null;        }    }

热点排行