Struts框架的namespace
1. Struts设计namespace用来做什么的
Struts官网上有一段话描述了namespace的含义:
The namespace attribute subdivides action configurations into logical modules, each with its own identifying prefix. Namespaces avoid conflicts between action names. Each namespace can have its own “menu” or “help” action, each with its own implementation. While the prefix appears in the browser URI, the tags are “namespace aware”, so the namespace prefix does not need to be embedded in forms and links.
命名空间将action划分到不同的逻辑模块中,每个action都有它自己的独立前缀,这样就避免了不同逻辑模块下的action命名冲突问题。就比如项目中两个模块中都有日志功能,我们可以使用相同的菜单名称(action的name),但要保证模块名称不一样(namespace)。
所以我们在写配置文件时需要注意命名空间的名称最好是跟功能模块相关,不要乱写或者不写。

  1. 使用过程中存在的问题
    贴出struts.xml配置文件:

    /user_add.jsp

    我们知道正常请求路径应写为:http://localhost:8081/项目名/user/user_XXX.action
    这样请求当然没有问题。
    因为默认Struts会根据namespace去寻找对应的配置的action,如果找不到会到默认的命名空间去寻找。
    后来发现如果用这样的url:http://localhost:8081/项目名/user/aa/bb /user_XXX.action
    居然也可以访问成功,这样很显然就导致了访问路径的混乱。我们来分析一下。
    经过一系列测试发现根据url查找action符合以下规则:

1.假设请求路径的URI,例如url是:http://localhost:8081/项目名/path1/path2 /addUser.action
2.首先寻找namespace为/path1/path2的package,如果存在这个package,则在这个package中寻找名字为addUser的action,若找到则执行,否则转步骤5;如果不存在这个package则转步骤3。
3.寻找namespace为/path1的package,如果存在这个package,则在这个package中寻找名字为addUser的action,若找到则执行,否则转步骤5;如果不存在这个package则转步骤4。
4. 寻找namespace为/的package,如果存在这个package,则在这个package中寻找名字为addUser的action,若找到则执行,转步骤5;如果不存在转步骤5。
5. 如果存在缺省的命名空间,就在该package下查找名字为addUser的action,若找到则执行,否则页面提示找不到action;否则提示面提示找不到action。
上述一个很重要的地方就是一旦找到对应的namespace的package就停止向上级路径查找了,另外缺省命名空间(package中没有指明namespace属性或namespace属性值为空)的package的可以不存在。
以上出现的问题是在Struts-2.3.16版本测试的,在Struts2.2.X或者早期版本中没有该问题。

  1. 原因分析
    这里跟踪源码发现Struts控制器用org.apache.struts2.dispatcher.mapper.DefaultActionMapper类来寻找url对应的action。其中的getMapping方法是获取对应action的:

    上述方法的parseNameAndNamespace就是为了得到符合uri请求的name和namespace的。
    接下来我们看这个方法里面做了怎样的处理?
    protected void parseNameAndNamespace(String uri, ActionMapping mapping, ConfigurationManager configManager)
    {
    int lastSlash = uri.lastIndexOf(“/”);//获取uri路径的最后一个斜杠位置
    String name;
    String namespace;
    String name;
    //如果写的路径直接就是action的名称,没有命名空间,则将namespace定为缺省的也就是””
    if (lastSlash == -1) {
    String namespace = “”;
    name = uri;
    }

    else
    {String name;//最后一个斜杠位置是0表示命名空间就是"/"if (lastSlash == 0){String namespace = "/";name = uri.substring(lastSlash + 1);}//namespace不是空或者"/",可以是多路径else{String name;//下面这句就是导致该问题的原因了,如果总是用全路径寻找action则得到的namespace就是"path1/path2/"if (this.alwaysSelectFullNamespace){String namespace = uri.substring(0, lastSlash);name = uri.substring(lastSlash + 1);}else {/** 如果该属性alwaysSelectFullNamespace设置为false,则会递归路径去查找package,遍历所有配置文件的package,* 直到找到跟uri匹配的namespace。*/Configuration config = configManager.getConfiguration();String prefix = uri.substring(0, lastSlash);namespace = "";boolean rootAvailable = false;for (PackageConfig cfg : config.getPackageConfigs().values()) {String ns = cfg.getNamespace();if ((ns != null) && (prefix.startsWith(ns)) && (((prefix.length() == ns.length()) || (prefix.charAt(ns.length()) == '/'))) && (ns.length() > namespace.length())) {namespace = ns;}if ("/".equals(ns)) {rootAvailable = true;}}name = uri.substring(namespace.length() + 1);if ((rootAvailable) && ("".equals(namespace)))namespace = "/";}}
    }
    if (!(this.allowSlashesInActionNames)) {int pos = name.lastIndexOf(47);if ((pos > -1) && (pos < name.length() - 1)) {name = name.substring(pos + 1);}
    }mapping.setNamespace(namespace);
    mapping.setName(cleanupActionName(name));
    

    }
    上面重要的地方做了注释,可以发现这个问题是由于Struts中的alwaysSelectFullNamespace属性导致的,如果为false,则会遍历所有配置文件中的package,直到找到合理的action,寻找原则如上文所总结的那样。如果设置为true,则会严格按照uri提供的namespace寻找action,找不到就报404错误。

  2. 解决问题
    Struts的配置文件default.properties文件中有关于该属性的配置,

    在我们struts.xml重写该属性即可。

  3. 总结
    Struts框架的namespace的确有很多的问题会出现,通过设置这个属性可以做到准备匹配对应的action,但是当form表单或者超链接写的是相对路径时,点击之后新的uri又会拼接上当前浏览器地址栏现有的路径,导致action找不到的错误。要求我们注意以下几点:
    1).页面最好写绝对路径来请求action,这样在页面跳转就不会带上namespace。
    2).配置
    防止没有严格按照namespace+action的方式搜索action处理方法。
    3).可以使用Struts注解的方式来定义Action对应的匹配url,只要将url写成以斜杠开头的绝对路径形式,就可以做到跟namespace无关,形如:

    还要注意Action类必须定义在名字为action的包下面,不然即使打了@Action注解也不会被Struts框架扫描到。

Struts框架命名空间问题答疑相关推荐

  1. Struts框架的入门使用

    1.struts框架的使用 导入jar包 1.commons-fileupload-1.2.jar 2. freemarker-2.3.15.jar 3.ognl-2.7.3.jar 4.struts ...

  2. struts(三)——struts框架实现登录示例

    前两篇讲解了struts框架的基本实现,自己感觉讲的也有些枯燥,今天拿登录的例子来做一个实现. 1.新建一个javaweb项目,并将struts的jar包拷贝到WebRoot/WEB-INF/lib下 ...

  3. java 详解 搭建 框架_在Eclipse中搭建Struts框架过程详解

    虽然用MyEclipse搭建Struts框架是更为便捷的方式,但是用Eclipse可以增强自己对Struts的理解.本文演示了使用Eclipse搭建Struts 1.2框架的过程.此项目实现了简单的功 ...

  4. c#Struts框架理念和自制Struts框架下 复杂版

    在上文中,我提到了一个"简单的zjy框架"的数据流程,但是那只是很少的一部分,用法和功能也比较简单,他能够完成的只是把一个数据库显示到页面(或者窗体)上.在这个第四章节中,我想将这 ...

  5. mysql国际化_Java的Struts框架中的主题模板和国际化设置

    主题模板 如果不指定一个主题,然后Struts2中会使用默认的XHTML主题.例如Struts 2中选择标签: 生成HTML标记: Name: 这里empinfo struts.xml文件中定义动作名 ...

  6. 深入浅出学习Struts框架(九):分析Struts框架实例4

    前两篇博客介绍了ActionServlet的初始化,讲述了它在初始化的时候做的事情.有了ActionServlet初始化,才能说当我们访问页面如何利用digester读取struts-config.x ...

  7. 【SSH进阶之路】一步步重构MVC实现Struts框架——封装业务逻辑和跳转路径(四)...

    目录: [SSH进阶之路]Struts基本原理 + 实现简单登录(二) [SSH进阶之路]一步步重构MVC实现Struts框架--从一个简单MVC开始(三) [SSH进阶之路]一步步重构MVC实现St ...

  8. Spring与Struts框架整合

    Spring,负责对象对象创建 Struts,用Action处理请求 Spring与Struts框架整合,关键点:让struts框架action对象的创建,交给spring完成! 1.步骤: 引入ja ...

  9. struts框架学习过程中的问题。

    1,错误: java.lang.NullPointerException: Module 'null' not found. 错误原因,struts运行需要的.jar文件拷贝不足,应该把它们加入到cl ...

  10. 基于Tiles框架Struts框架的UI 设计—几种组织HTML和JSP视图组件

    摘要每个web应用开发者一定组织视图组件,例如  页首,正文体和页尾. 有许多技术可以组织这些组件, 但每个都有优缺点.这篇文章包括了7个可用的解决方案并让你了解 Tiles框架和Struts框架的灵 ...

最新文章

  1. linux下模拟CPU占用100%小程序
  2. POJ 3356 水LCS
  3. jupyter中python3如何导入文件_Python·Jupyter Notebook各种使用方法
  4. 【时间序列】最完整的时间序列分析和预测(含实例及代码)
  5. Java黑皮书课后题第5章:**5.37(十进制转二进制)编写程序,提示用户输入一个十进制整数,然后显示对应的二进制值(不要使用Integer.toBinaryString(int)方法)
  6. HttpClient中的各种请求
  7. 冲突域、广播域的通俗讲解
  8. 一秒创建高级查询服务
  9. 2019.01.28【NOIP普及组】模拟赛C组总结
  10. 反向输出dna序列_蛋白质序列反向(逆向)翻译成DNA序列-在线工具
  11. 广义表的基本概念【数据结构】
  12. 麦肯锡70页特辑报告论述《人工智能的未来之路》(完整版PPT)
  13. C++菱形继承逆向分析
  14. Deep learning 学习开篇
  15. vnr懒人版教程_凉皮懒人做法,不揉面不洗面,配方配料无保留,简单快速又好吃...
  16. 基于Android的图书管理系统
  17. 详解YUV420数据格式
  18. OpenCVSharp Mat.Set<T>修改像素颜色
  19. MacOS破解WiFi(WPA、WPA2)
  20. CEO年薪过亿,谁说了算?

热门文章

  1. 历届二级c语言pdf,历年全国计算机二级C语言题库.pdf
  2. c语言函数调用及应用举例
  3. python输入一个自然数字符串、然后输出各位数字之和_Python练习题
  4. java软件工程师自我评价_java开发简历自我评价【java简历自我评价模板】
  5. 计算机专业计算机二级java有用吗_计算机二级java含金量如何 对就业有帮助吗
  6. 读书笔记:《浪潮之巅》
  7. Fortan中读取数据到text文件
  8. matlab视频教程矩阵,《机器学习》之矩阵和Matlab教程(适合初学)
  9. PHP仿网易云原创音乐分享平台网站源码
  10. perl语言语法基础