Struts2在web.xml中配置为“/*”和“*.action,*.jsp”的差别
来源:互联网 发布:淘宝商城防晒手套 编辑:程序博客网 时间:2024/05/23 16:54
Struts2在web.xml中配置为“/*”和“*.action,*.jsp”的差别1、Struts2在web.xml中配置为“/*”和“*.action,*.jsp”的差别。
2、There is no Action mapped for namespace / and action name ...的问题。
分析(环境是Struts2.1.8.1):
Struts2过滤器的配置有2种方式:
< filter-mapping> < filter-name>struts2</filter-name> < url-pattern>/*</url-pattern> < /filter-mapping> < filter-mapping> < filter-name>struts2</filter-name> < url-pattern>*.action</url-pattern> < /filter-mapping> < filter-mapping> < filter-name>struts2</filter-name> < url-pattern>*.jsp</url-pattern> < /filter-mapping>
那么这两种方式的配置,究竟有什么差别呢?
首先,假如配置方式是*.action的话,一般应当同时配置*.jsp,因为如果不通过action而直接访问jsp页面的话,Struts2标签在解析的时候会获取当前线程ThreadLocal中的Dispatcher。而Dispatcher是在Struts过滤器中预设的。代码如下:
public static ValueStack getStack(PageContext pageContext) { HttpServletRequest req = (HttpServletRequest) pageContext.getRequest(); ValueStack stack = (ValueStack) req.getAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY); if (stack == null) { HttpServletResponse res = (HttpServletResponse) pageContext.getResponse(); Dispatcher du = Dispatcher.getInstance(); if (du == null) { throw new ConfigurationException("The Struts dispatcher cannot be found. This is usually caused by "+ "using Struts tags without the associated filter. Struts tags are only usable when the request "+ "has passed through its servlet filter, which initializes the Struts dispatcher needed for this tag."); }
除了为当前线程预设Dispatcher以外,Struts2对“/*”的请求,在完成普通的“*.action”过滤的基础上,另外提供2点功能:
第1点用于访问classpath中特定的静态资源;
第2点支持无后缀名的Action请求;
Struts2的标签有时候需要某些CSS、JS文件的支持,比如<s:head/>标签,可能就转换成:
< link rel="stylesheet" href="/demo/struts/xhtml/styles.css" type="text/css"/> < script src="/demo/struts/utils.js" type="text/javascript"></script>
第1点功能带来的好处是可以把这些Struts2框架用到的CSS、JS文件打包在Struts2-core-***.jar文件中分发,使得Struts2的发布包对开发人员而言更加简洁。
下面看一下StrutsPrepareAndExecuteFilter是怎样实现的:
①将Dispatcher预设到线程的ThreadLocal变量上;
②对于Action请求,直接execute.executeAction(request,response,mapping);
③如果是/struts、或者/static开始的资源,则在classpath下查找特定的包下面的匹配资源;
④其他的所有资源(包括直接访问的JSP、以及其他静态资源)转交过滤器链的下一个环节处理:chain.doFilter(request, response);
上面所说的特定包,是指在
< filter> < filter-name>struts2</filter-name> < filter-class> org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter < /filter-class> < init-param> < param-name>packages</param-name> < param-value>eee</param-value> < /init-param> < /filter>
中通过packages参数指定的包、以及 "org.apache.struts2.static template org.apache.struts2.interceptor.debugging static"这4个包。
由于packages可配置,从而,如果有自己的classpath上的资源需要访问,或者需要更改Struts本身的静态资源时,只要把Classpath下相应的package设置在过滤器的初始参数中即可(这一条看上去好像没什么用处)。
上面是使用/*时对静态资源的访问,那么使用*.action时如果需要的话,如何访问静态资源呢?
很简单,只要把需要用到的静态资源解压缩到WebContent/struts目录下即可。
第2点“支持无后缀名的Action请求”经常带来一些混乱,最典型的就是“/*”错误地拦截了其他的映射为无后缀名的Servlet请求。比如DWR、FCKEditor等都存在这种问题。
比如,当访问“/demo/dwr”时,正常情况应该显示当前系统中对外暴露的JS方法的列表,但在Struts2的默认配置下,却得到“There is no Action mapped for namespace / and action name dwr.”
又比如在默认配置下,访问http://localhost:8080/demo/hello.action
和访问http://localhost:8080/demo/hello这两者是等同的。
当然,也只有无后缀名的URL请求才会被Struts2当做是Action,这也是为什么/dwr无法访问,然而/dwr/interface.js可以访问的原因。
具体的,看一下下面的代码就明白了:
//Struts2默认将“*.action”或者无后缀的URL当做Action protected List<String> extensions = new ArrayList<String>() {{ add("action"); add("");}}; protected String dropExtension(String name, ActionMapping mapping) { if (extensions == null) { return name; } for (String ext : extensions) { if ("".equals(ext)) { // This should also handle cases such as /foo/bar-1.0/description. It is tricky to distinquish /foo/bar-1.0 but perhaps adding a numeric check in the future could work // request uri如果不包含扩展名的话,则匹配此情况 int index = name.lastIndexOf('.'); if (index == -1 || name.indexOf('/', index) >= 0) { return name; } } else { String extension = "." + ext; if (name.endsWith(extension)) { name = name.substring(0, name.length() - extension.length()); mapping.setExtension(ext); return name; } } } return null; }
那么,怎么解决此问题呢?
有2种办法。
第1种很简单,在Struts.properties中定义:
struts.action.extension = action即可解决此问题。
Struts2缺省配置对应于:
struts.action.extension = action,(注意后面有个逗号)
第2种是在Struts.properties中设置:
struts.action.excludePattern = /dwr.*,/webEditor.*(注意,这儿是正则表达式,不是URL匹配模式,所以要写/dwr.*而不是/dwr/*)
这种写法应配置StrutsPrepareAndExecuteFilter,配置FilterDispatcher是无效的。
在微博管家项目中,采用的是struts2.1.8,出现了jsp、js、css等文件加载失败等问题。通过以下配置解决:
struts.xml:
< constant name="struts.action.extension" value="" /> struts.properties: struts.locale=zh_CN struts.i18n.encoding=utf-8 struts.action.extension=, struts.action.excludePattern = /js.*,/static.*(js和static文件夹是项目中js和css所在的目录)
0 0
- Struts2在web.xml中配置为“/*”和“*.action,*.jsp”的差别
- Struts2在web.xml中配置为“/*”和“*.action,*.jsp”的差别
- Struts2在web.xml中配置为“/*”和“*.action,*.jsp”的差别
- Struts2在web.xml中配置为“/*”和“*.action,*.jsp”的差别
- 在web.xml中为Struts2配置拦截器
- 在Struts2 中 struts.xml的Action配置详解
- 在web.xml中配置了struts2的filter后访问jsp出现404
- Struts2-Action概述和在Action中访问WEB资源
- AjaxAnywhere在struts2中Web.xml的配置
- 关于Struts2 在web.xml中配置改变的问题
- struts2在web.xml中配置详情
- struts2在web.xml中配置详解
- struts1和struts2在web.xml配置的区别
- 如何在web.xml中配置jsp的访问路径
- struts2的xml配置action
- Struts2 在Struts.xml配置Action的result
- 02-解决不能在web.xml中配置action问题
- struts2中web.xml的配置
- SD卡中FAT32文件格式快速入门(图文详细介绍)
- 遇到的问题---eclipse提示:Syntax error on tokens, delete these tokens
- 互联网和信息技术对汽车行业的影响越来越大
- 【Linux编程】进程终止和exit函数
- 继承类
- Struts2在web.xml中配置为“/*”和“*.action,*.jsp”的差别
- 多线程下的下载原理
- 完胜文件处理,so easy
- u-boot-2009.08在飞凌OK2440/FL2440上的移植(一)——让u-boot在内存中运行进来
- SendMessage、PostMessage原理
- Linux apache 默认目录结构
- vc加载PNG以及JPG等图片资源并绘制图片
- 遇到的问题-----No JREs in workspace compatible with specified execution environment: JavaSE-1.7,java
- crm2011 使用SOAP 查询单个记录 Retrieve