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
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 泰迪在床上睡觉怎么办 泰迪睡觉换地方怎么办 猫一定要和人睡怎么办 狗喜欢跳到床上怎么办 幼猫晚上不睡觉怎么办 宝宝不在床上睡觉怎么办呢 瑜伽球表面粘了怎么办 鞋子洗了很臭怎么办 在社区开瑜伽馆怎么办 腿被开水烫伤了怎么办 狗狗的腿脱臼了怎么办 手火辣辣的烧疼怎么办 网贷收到告知函怎么办 收到捷信催收律师函怎么办 快钱贷款不还怎么办 快易花逾期3个月怎么办 欠微粒贷一万多没还找上门了怎么办 装修公司骚扰电话太多了怎么办 总有大便的感觉怎么办 黎明杀机无网络连接怎么办 监控视频电脑播放不了怎么办 绝地手游击倒了怎么办? 绝地求生全军出击倒地后怎么办 黑魂3杀了npc怎么办 菜刀背容易割手怎么办 商铺厨房太热怎么办 农村自建房厨房卫生间怎么办 宾利车门不会开怎么办 两岁的宝宝好动怎么办 被别人坏了名声怎么办 在单位混臭了怎么办 在公司名声臭了怎么办 怀孕三个月吐的厉害怎么办 孕38周轻微贫血怎么办 孕38周中度贫血怎么办 孕38周贫血严重怎么办 孕38周有点贫血怎么办 脚被热水烫红了怎么办 学员练车撞死人怎么办 三胎意外来了该怎么办 因为飞机延误耽误行程怎么办