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。

 

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

 

 

通过分析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;
        }
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
边界值容易引发 bug 的原因主要有以下几点: 1. 边界条件容易被忽视:在编写代码或设计系统时,人们往往更关注常规情况而忽视了边界条件。这导致在处理边界值时可能存在逻辑错误或未考虑到的情况。 2. 边界条件可能引发特殊行为:边界值通常会导致系统或算法的特殊行为,这些行为可能与常规情况不同。如果在处理边界值时没有正确考虑这些特殊行为,就容易出现错误。 3. 边界条件测试不充分:测试用例通常会覆盖一般情况,但往往忽略了边界条件。如果没有充分测试边界值,就无法发现潜在的问题。 4. 数字处理精度问题:在涉及到浮点数或小数计算时,边界值可能导致精度问题。由于计算机表示数字的限制,处理边界值时可能出现舍入误差或精度丢失。 为了避免边界值引发的 bug,可以采取以下措施: 1. 明确定义边界条件:在设计和编写代码时,明确定义边界条件,并确保正确处理这些情况。 2. 进行全面的测试:在测试阶段,充分考虑边界值,并编写相应的测试用例来覆盖这些情况。 3. 注意特殊行为:了解边界值可能引发的特殊行为,并在代码中正确处理这些情况。 4. 考虑数值精度:对于涉及到浮点数或小数计算的情况,需要注意处理数值精度的问题,避免舍入误差或精度丢失。 通过以上措施,可以减少边界值引发 bug 的概率,并提高系统的稳定性和准确性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值