Struts2中URL处理
来源:互联网 发布:流程梳理,优化建议书 编辑:程序博客网 时间:2024/06/13 07:40
在Struts中,碰到一个奇怪的现象对于一下两个URL可以访问到同一个Action,
- 链接:
- http://localhost:8081/operation/operator/quotetask/operator/quotetask/queryByTaskId.do?quoteTaskId=
- http://localhost:8081/operation/operator/quotetask/queryByTaskId.do?quoteTaskId=
在好奇心的驱使下,查看了Struts对于URL的处理源码,在Struts中,主要是需要通过URL找到对应的ActionMapping设置,也就是在Struts.xml中配置的action,其寻找过程如下:
1. 在web.xml中,配置了.do结尾的请求,都会被struts的org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
过滤器过滤。
2. 在StrutsPrepareAndExecuteFilter中的doFilter中,执行寻找ActionMapping,并执行对应的action方法逻辑
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) req; HttpServletResponse response = (HttpServletResponse) res; try { if (excludedPatterns != null && prepare.isUrlExcluded(request, excludedPatterns)) { chain.doFilter(request, response); } else { prepare.setEncodingAndLocale(request, response); // 创建Struts值栈ValueStack prepare.createActionContext(request, response); // 设置当前分发工具类Dispatcher到当前线程中 prepare.assignDispatcherToThread(); request = prepare.wrapRequest(request); // 寻找相应的ActionMapping 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); } } } finally { prepare.cleanupRequest(request); } }
- 在PrepareOperations.findActionMapping中的逻辑
public ActionMapping findActionMapping(HttpServletRequest request, HttpServletResponse response, boolean forceLookup) { ActionMapping mapping = (ActionMapping) request.getAttribute(STRUTS_ACTION_MAPPING_KEY); if (mapping == null || forceLookup) { try { mapping = dispatcher.getContainer().getInstance(ActionMapper.class).getMapping(request, dispatcher.getConfigurationManager()); if (mapping != null) { request.setAttribute(STRUTS_ACTION_MAPPING_KEY, mapping); } } catch (Exception ex) { dispatcher.sendError(request, response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, ex); } } return mapping; }
- 最后处理URL的地方在DefaultActionMapper.parseNameAndNamespace中
protected void parseNameAndNamespace(String uri, ActionMapping mapping, ConfigurationManager configManager) { String namespace, name; int lastSlash = uri.lastIndexOf("/"); if (lastSlash == -1) { namespace = ""; name = uri; } else if (lastSlash == 0) { // ww-1046, assume it is the root namespace, it will fallback to // default // namespace anyway if not found in root namespace. namespace = "/"; name = uri.substring(lastSlash + 1); } else if (alwaysSelectFullNamespace) { // Simply select the namespace as everything before the last slash namespace = uri.substring(0, lastSlash); name = uri.substring(lastSlash + 1); } else { // Try to find the namespace in those defined, defaulting to "" Configuration config = configManager.getConfiguration(); String prefix = uri.substring(0, lastSlash); namespace = ""; boolean rootAvailable = false; // Find the longest matching namespace, defaulting to the default //找到对应的namespace(operator/quotetask) for (PackageConfig cfg : config.getPackageConfigs().values()) { String ns = cfg.getNamespace(); if (ns != null && prefix.startsWith(ns) && (prefix.length() == ns.length() || prefix.charAt(ns.length()) == '/')) { if (ns.length() > namespace.length()) { namespace = ns; } } if ("/".equals(ns)) { rootAvailable = true; } } // 找到对应的namspace,并用uri中,去除namespace,用于获取对应的action名字 name = uri.substring(namespace.length() + 1); // Still none found, use root namespace if found if (rootAvailable && "".equals(namespace)) { namespace = "/"; } } // 以上两个URL之所以能访问到同一个action, 关键在此处, 通过前面去掉namespace后,最后获得两个actionName为: operator/quotetask/queryByTaskId 与 /queryByTaskId .在以下代码中,直接获取最后一个"/"后的串,则都获得queryByTaskId.并找到对应的ActionMapping if (!allowSlashesInActionNames) { int pos = name.lastIndexOf('/'); if (pos > -1 && pos < name.length() - 1) { name = name.substring(pos + 1); } } mapping.setNamespace(namespace); mapping.setName(cleanupActionName(name)); }
总结: 在struts中,对与URL的处理,是直接忽略了namespace 与 actionName之间的字符串的。无论是 operator/quotetask/queryByTaskId, operator/quotetask/operator/quotetask/queryByTaskId, 还是operator/quotetask/operator/quotetask/operator/quotetask/queryByTaskId最后获取到的actionMapping都是 namespace: operator/quotetask, actionName: queryByTaskId
0 0
- Struts2中URL处理
- struts2配置文件中url传递参数中文乱码处理
- struts2配置文件中url传递参数中文乱码处理
- java中Url处理
- Struts2中乱码处理
- struts2中处理placeholder
- struts2中异常处理
- jsp中URL中文处理
- jsp中URL中文处理
- url中特殊字符#处理
- url 中特殊字符处理
- java中url加密处理
- java 中URL的处理
- URL中特殊字符处理
- URL中特殊符号的处理
- struts2中<s:url>标签的用法
- struts2页面中获取url参数方法
- Struts2中处理文件上传
- java hashCode() equals()
- 相册获取图片报OOM异常解决办法
- Unity 对话系统插件学习笔记
- bfs入门——Catch That Cow
- 用sklearn和tensorflow做boston房价的回归计算的比较(3)--RNN之递归神经网路LSTM
- Struts2中URL处理
- JAVAMAIL实现发送邮件
- 形象的描述大数据的技术生态以及Hadoop、Hive、Spark 之间关系
- 坑:删除ViewGroup中的一个已经得到焦点的EditText时,同级的第一个EditView会得到焦点
- c++小程序媛常用网站
- Python的hasattr() getattr() setattr() 函数使用方法详解
- XPath总结
- Redis数据库的dump备份与aof备份
- 数据库入门之常用模板汇总