职业IT人-IT人生活圈

 找回密码
 成为会员
搜索
查看: 627|回复: 5

struts2应用中URL的相对路径以“static”开头时无法访问

[复制链接]
jinchang 发表于 2011-8-13 10:35 | 显示全部楼层 |阅读模式
     今天在同事的应用出了一个小错误,与struts2有关,这里记录一下。

    描述:web应用下有一个目录“static”,现在要访问其中的“top.html”文件,即访问“localhost:8080/static/top.html”,服务器总是抱404错误。

    原因:在struts2的doFilter中,如果请求的是静态资源,struts2会判断该请求是否可以处理,这里的代码如下:
    Java代码  
String resourcePath = RequestUtils.getServletPath(request);   
if ("".equals(resourcePath) && null != request.getPathInfo()) {   
    resourcePath = request.getPathInfo();   
}   
if (staticResourceLoader.canHandle(resourcePath)) {   
    staticResourceLoader.findStaticResource(resourcePath, request, response);   
} else {   
     // this is a normal request, let it pass through   
     chain.doFilter(request, response);   
}   
// The framework did its job here   
return;   


        String resourcePath = RequestUtils.getServletPath(request);
        if ("".equals(resourcePath) && null != request.getPathInfo()) {
            resourcePath = request.getPathInfo();
        }
        if (staticResourceLoader.canHandle(resourcePath)) {
            staticResourceLoader.findStaticResource(resourcePath, request, response);
        } else {
             // this is a normal request, let it pass through
             chain.doFilter(request, response);
        }
        // The framework did its job here
        return;
   

    其中,在DefaultStaticContentLoader类的canHandle方法中会对请求路径进行判断:
    Java代码  
public boolean canHandle(String resourcePath) {   
    return serveStatic &&   
      (resourcePath.startsWith("/struts") || resourcePath.startsWith("/static"));   
}   

    public boolean canHandle(String resourcePath) {
        return serveStatic &&
          (resourcePath.startsWith("/struts") || resourcePath.startsWith("/static"));
    }
   

    这里,serveStatic的值为true,再加上要访问的资源以“/static”开头,所以这里返回true。

    然后,会进入DefaultStaticContentLoader类的findStaticResource方法,该方法的第一行语句是:
    Java代码  
String name = cleanupPath(path);   

    String name = cleanupPath(path);
   

    这里,cleanupPath方法的定义如下:
    Java代码  
/**  
* @param path requested path  
* @return path without leading "/struts" or "/static"  
*/  
protected String cleanupPath(String path) {   
    //path will start with "/struts" or "/static", remove them   
    return path.substring(7);   
}   

     /**
     * @param path requested path
     * @return path without leading "/struts" or "/static"
     */
    protected String cleanupPath(String path) {
        //path will start with "/struts" or "/static", remove them
        return path.substring(7);
    }
   

    struts2把“/static”截掉了,这样,后面再进行解析的时候,就变成了解析对“/top.html”的请求,所以会报404错误。

    总结:悲剧的错误,还以为是自己程序的bug,改了半天。需要加强对开源程序中具体实现的了解。

木已 发表于 2011-8-13 10:36 | 显示全部楼层
这个发现很久了,好像是可以配置的。。配置一下就行了。

月上萧萧 发表于 2011-8-13 10:36 | 显示全部楼层
zhxing 写道
这个发现很久了,好像是可以配置的。。配置一下就行了。



受教了。以前还真没注意过。回头找找怎么配置。

走就走吧 发表于 2011-8-13 10:36 | 显示全部楼层
static是java的关键字,你这里虽然是当做字符串来使用的,但是对于java的关键字,还是不推荐用作程序中读取的目录名;

我在review我们项目组的代码的时候,经常看见类似:type、sort这类的变量命名,虽然在java语法上他们并没有错误,但是这样的命名,如果不结合代码的上下文,你很难知道它到底代表着什么,很容易引起二义性;

而且type、sort这类的常用计算机词汇,是SQL的关键字,我在NetBeans中review我们项目组员使用eclipse写得代码,凡是用到sql关键字的变量,NetBeans都会提示,建议改名。

话题回到你的这个问题上来,建议你把static目录改名为“resources”

钰云 发表于 2011-8-13 10:36 | 显示全部楼层
george_space 写道
static是java的关键字,你这里虽然是当做字符串来使用的,但是对于java的关键字,还是不推荐用作程序中读取的目录名;

我在review我们项目组的代码的时候,经常看见类似:type、sort这类的变量命名,虽然在java语法上他们并没有错误,但是这样的命名,如果不结合代码的上下文,你很难知道它到底代表着什么,很容易引起二义性;

而且type、sort这类的常用计算机词汇,是SQL的关键字,我在NetBeans中review我们项目组员使用eclipse写得代码,凡是用到sql关键字的变量,NetBeans都会提示,建议改名。

话题回到你的这个问题上来,建议你把static目录改名为“resources”



谢谢指点。

这此出现的问题貌似并不是因为static是java关键字的原因,而是因为struts的过滤器把以“/struts”和“/static”开头的url请求截断了。
fossil 发表于 2011-8-16 10:30 | 显示全部楼层
呵呵 我可不敢~~~~
您需要登录后才可以回帖 登录 | 成为会员

本版积分规则

QQ|手机版|小黑屋|网站帮助|职业IT人-IT人生活圈 ( 粤ICP备12053935号-1 )|网站地图
本站文章版权归原发布者及原出处所有。内容为作者个人观点,并不代表本站赞同其观点和对其真实性负责,本站只提供参考并不构成任何投资及应用建议。本站是信息平台,网站上部分文章为转载,并不用于任何商业目的,我们已经尽可能的对作者和来源进行了通告,但是能力有限或疏忽造成漏登,请及时联系我们,我们将根据著作权人的要求立即更正或者删除有关内容。

GMT+8, 2024-5-17 13:48 , Processed in 0.119066 second(s), 24 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表