精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2013-04-17
2 这个请求经过一系列的过滤器(Filter)(这些过滤器中有一个叫做ActionContextCleanUp的可选过滤器,这个过滤器对于Struts2和其他框架的集成很有帮助,例如:SiteMesh Plugin) 3 接着FilterDispatcher被调用,FilterDispatcher询问ActionMapper来决定这个请求是否需要调用某个Action 4 如果ActionMapper决定需要调用某个Action,FilterDispatcher把请求的处理交给ActionProxy 5 ActionProxy通过Configuration Manager询问框架的配置文件,找到需要调用的Action类 6 ActionProxy创建一个ActionInvocation的实例。 7 ActionInvocation实例使用命名模式来调用,在调用Action的过程前后,涉及到相关拦截器(Intercepter)的调用。 8 一旦Action执行完毕,ActionInvocation负责根据struts.xml中的配置找到对应的返回结果。返回结果通常是(但不总是,也可 能是另外的一个Action链)一个需要被表示的JSP或者FreeMarker的模版。在表示的过程中可以使用Struts2 框架中继承的标签。在这个过程中需要涉及到ActionMapper 上述是大家熟知的struts2原理 在下有几点疑问: 疑问1:第三步中,ActionMapper如何判断请求是action请求 疑问2:第七步中,ActionInvocation实例使用命名模式来调用,何谓命名模式? 疑问3:第七步中,调用action的前后要调用一系列的拦截器,请问拦截器的作用是什么? 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2013-04-17
1、来自客户端的都是httprequest,ActionMapper只是负责将请求映射到具体的Action上处理
2、ActionInvocation使用的是命令模式 3、拦截器Intercepter可以完成额外的工作,比如TokenInterceptor可以在执行具体的业务前后增加对token的检验,又比如RolesInterceptor可以检验权限等,将这些功能与核心代码分离,AOP思想 |
|
返回顶楼 | |
发表时间:2013-04-17
cectsky 写道 1、来自客户端的都是httprequest,ActionMapper只是负责将请求映射到具体的Action上处理 2、ActionInvocation使用的是命令模式 3、拦截器Intercepter可以完成额外的工作,比如TokenInterceptor可以在执行具体的业务前后增加对token的检验,又比如RolesInterceptor可以检验权限等,将这些功能与核心代码分离,AOP思想 第三点解答的不错,1,2您等于木有说啊,我想知道的,1是如何判断一个请求是action,2是命名模式是什么意思,您如果只说了第三点我会觉得你是个高手,明明不知道还凑了1,2点,我就觉得画蛇添足了,不过还是谢谢您 |
|
返回顶楼 | |
发表时间:2013-04-17
mumuaimao2009 写道 cectsky 写道 1、来自客户端的都是httprequest,ActionMapper只是负责将请求映射到具体的Action上处理
2、ActionInvocation使用的是命令模式 3、拦截器Intercepter可以完成额外的工作,比如TokenInterceptor可以在执行具体的业务前后增加对token的检验,又比如RolesInterceptor可以检验权限等,将这些功能与核心代码分离,AOP思想 第三点解答的不错,1,2您等于木有说啊,我想知道的,1是如何判断一个请求是action,2是命名模式是什么意思,您如果只说了第三点我会觉得你是个高手,明明不知道还凑了1,2点,我就觉得画蛇添足了,不过还是谢谢您 1、如何判断一个请求是action??请求和action根本就不是一个概念,action是负责accept和redirect请求的,根本没有判断,只有映射。 2、都说了是命令模式,你还在那说命名模式,命毛的名 |
|
返回顶楼 | |
发表时间:2013-04-17
cectsky 写道 mumuaimao2009 写道 cectsky 写道 1、来自客户端的都是httprequest,ActionMapper只是负责将请求映射到具体的Action上处理
2、ActionInvocation使用的是命令模式 3、拦截器Intercepter可以完成额外的工作,比如TokenInterceptor可以在执行具体的业务前后增加对token的检验,又比如RolesInterceptor可以检验权限等,将这些功能与核心代码分离,AOP思想 第三点解答的不错,1,2您等于木有说啊,我想知道的,1是如何判断一个请求是action,2是命名模式是什么意思,您如果只说了第三点我会觉得你是个高手,明明不知道还凑了1,2点,我就觉得画蛇添足了,不过还是谢谢您 1、如何判断一个请求是action??请求和action根本就不是一个概念,action是负责accept和redirect请求的,根本没有判断,只有映射。 2、都说了是命令模式,你还在那说命名模式,命毛的名 您还是不知道我问的是什么,我问的是actionMapper如何判断是否要调用一个action 您说是命令模式?什么叫命令模式呢?就这样给我们小白解释啊?我倒 |
|
返回顶楼 | |
发表时间:2013-04-17
mumuaimao2009 写道 cectsky 写道 mumuaimao2009 写道 cectsky 写道 1、来自客户端的都是httprequest,ActionMapper只是负责将请求映射到具体的Action上处理
2、ActionInvocation使用的是命令模式 3、拦截器Intercepter可以完成额外的工作,比如TokenInterceptor可以在执行具体的业务前后增加对token的检验,又比如RolesInterceptor可以检验权限等,将这些功能与核心代码分离,AOP思想 第三点解答的不错,1,2您等于木有说啊,我想知道的,1是如何判断一个请求是action,2是命名模式是什么意思,您如果只说了第三点我会觉得你是个高手,明明不知道还凑了1,2点,我就觉得画蛇添足了,不过还是谢谢您 1、如何判断一个请求是action??请求和action根本就不是一个概念,action是负责accept和redirect请求的,根本没有判断,只有映射。 2、都说了是命令模式,你还在那说命名模式,命毛的名 您还是不知道我问的是什么,我问的是actionMapper如何判断是否要调用一个action 您说是命令模式?什么叫命令模式呢?就这样给我们小白解释啊?我倒 1、ActionMapper获取xml中action的配置信息,装配成ActionMapping对象,当dispatchAction收到request后,寻找是否有对于的ActionMapping对象,有就调用反射调用action的方法,没有就exception 2、命令模式,google之,设计模式不是简单能说明白的,看看例子 |
|
返回顶楼 | |
发表时间:2013-04-17
最后修改:2013-04-17
关于第三步的疑问:
1. 查看 org.apache.struts2.dispatcher.mapper.DefaultActionMapper.getMapping 这个方法, 逻辑是会先把你的 requestURI取到, 然后去掉后缀 (你如果没有配置, 默认是.action, 由struts.action.extension 配置项指定, 多个可以用逗号隔开) 看 org.apache.struts2.dispatcher.mapper.DefaultActionMapper.dropExtension 2. 去掉后缀后 解析这个路径, 得到 该路径对应的 namespance, action name 看 org.apache.struts2.dispatcher.mapper.DefaultActionMapper.parseNameAndNamespace 3. 如果解析得到null, 那么就不会进入到对应的action里面 如果解析得到action存在的话, 就看是不是需要用!method表达式指定的方法 if (allowDynamicMethodCalls) { // handle "name!method" convention. String name = mapping.getName(); int exclamation = name.lastIndexOf("!"); if (exclamation != -1) { mapping.setName(name.substring(0, exclamation)); mapping.setMethod(name.substring(exclamation + 1)); } } 通过以上3步, 就得到一个完整的actionMapping了. 4. 得到actionMapping后, 就交给Dispacher 去处理执行了 看 org.apache.struts2.dispatcher.Dispatcher.serviceAction, 通过actionMapping等信息可以得到一个ActionProxy, 接下来就是执行了(先执行iterceptor, 再action, 具体看:com.opensymphony.xwork2.DefaultActionInvocation.invoke() 可以得到答案) |
|
返回顶楼 | |
发表时间:2013-04-17
关于第三步的疑问:
|
|
返回顶楼 | |
发表时间:2013-04-18
wujiazhao88 写道 关于第三步的疑问:
1. 查看 org.apache.struts2.dispatcher.mapper.DefaultActionMapper.getMapping 这个方法, 逻辑是会先把你的 requestURI取到, 然后去掉后缀 (你如果没有配置, 默认是.action, 由struts.action.extension 配置项指定, 多个可以用逗号隔开) 看 org.apache.struts2.dispatcher.mapper.DefaultActionMapper.dropExtension 2. 去掉后缀后 解析这个路径, 得到 该路径对应的 namespance, action name 看 org.apache.struts2.dispatcher.mapper.DefaultActionMapper.parseNameAndNamespace 3. 如果解析得到null, 那么就不会进入到对应的action里面 如果解析得到action存在的话, 就看是不是需要用!method表达式指定的方法 if (allowDynamicMethodCalls) { // handle "name!method" convention. String name = mapping.getName(); int exclamation = name.lastIndexOf("!"); if (exclamation != -1) { mapping.setName(name.substring(0, exclamation)); mapping.setMethod(name.substring(exclamation + 1)); } } 通过以上3步, 就得到一个完整的actionMapping了. 4. 得到actionMapping后, 就交给Dispacher 去处理执行了 看 org.apache.struts2.dispatcher.Dispatcher.serviceAction, 通过actionMapping等信息可以得到一个ActionProxy, 接下来就是执行了(先执行iterceptor, 再action, 具体看:com.opensymphony.xwork2.DefaultActionInvocation.invoke() 可以得到答案) 不错 |
|
返回顶楼 | |
发表时间:2013-04-22
在web.xml中配置的Struts2的Filter相应的doFilter中会执行如下代码:
ActionMapping mapping = prepare.findActionMapping(request, response, true); if (mapping == null) { boolean handled = execute.executeStaticResourceRequest(request, response); if (!handled) { chain.doFilter(request, response); } } else { execute.executeAction(request, response, mapping); } 而findActionMapping会根据request的uri来获取,如果请求没有和配置的extension匹配,会返回null,代码: public ActionMapping getMapping(HttpServletRequest request, ConfigurationManager configManager) { ActionMapping mapping = new ActionMapping(); String uri = getUri(request); int indexOfSemicolon = uri.indexOf(";"); uri = (indexOfSemicolon > -1) ? uri.substring(0, indexOfSemicolon) : uri; uri = dropExtension(uri, mapping); if (uri == null) { return null; } parseNameAndNamespace(uri, mapping, configManager); handleSpecialParameters(request, mapping); return parseActionName(mapping); } 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 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; } 见第一段代码,如果没有相应匹配的请求,则会执行后续的filter,都不存在,会返回404 |
|
返回顶楼 | |