您的位置:首页 > 编程语言 > Java开发

深入浅出学习Struts1框架(九):截取URL

2015-01-22 17:14 393 查看
前两篇博客介绍了ActionServlet的初始化,讲述了它在初始化的时候做的事情。有了ActionServlet初始化,才能说当我们访问页面如何利用digester读取struts-config.xml配置文件信息,如何讲这些信息存到ActionMapping中,如何完成相应的业务处理和页面跳转。

那么今天就开始进入这一环节的分析。分析之前,希望大家还是好好看看原先的系列文章,那些文章都是引子,能够很清晰的认识struts框架大概的运行流程,所以不至于出现分析到底层源码的时候不好理解的现象。废话也不多说,现在开始分析。

这节课我们开始从截取路径开始,在《struts1框架一》博客中的mvc小实例中就已经写到了截取路径了,主要代码就是:

[java] view
plaincopyprint?

String requestURI=request.getRequestURI();

System.out.println("request="+requestURI);

String path=requestURI.substring(requestURI.indexOf("/",1),requestURI.indexOf("."));

System.out.println("path="+path);

这样我们就能从一个url中获得最后的名称和前面的“/”,也就是/login之类的字符串,之后用if-else判断就初始化相应的Action,虽然说这仅仅是一个mvc的小实例,但是就是这一简单的过程其实就是Struts框架截取字符串实现的原理所在(我个人观点,如果有不同见解,希望沟通交流)。

记得前几篇博客的朋友都知道,我对mvc小实例进行了几次重构,我把那些if-else中的字符串放到了配置文件中,最终变成了dom4j读取配置文件,之后动态相匹配通过多肽形式实例化Action,完成相应的业务逻辑和页面跳转。有了这个基础我们来看看struts框架是如何进行截取字符串的,相信大家会有所共鸣。

下面我们来对ActionServlet深层次进行分析。我们用断点的调试的方式来看底层源码。因为这个实例是post方式提交,所以将断点设置到doPost方法上。



我们debug运行程序,进入doPost里面的方法:



这个方法非常重要是ActionServlet运行的核心方法,这个Process处理了非常多的事情,后面的博客会一一介绍。

我们进入这个方法:



再继续进入:



我们赫然发现了这样一个方法就是processPath方法,这个方法就是截取字符串的方法。这个方法的源代码如下:

[java] view
plaincopyprint?

/**

* <p>Identify and return the path component(from the request URI) that

* we will use to select an <code>ActionMapping</code> with which todispatch.

* If no such path can be identified,create an error response and return

* <code>null</code>.</p>

*

* @param request The servlet request weare processing

* @param response The servlet response weare creating

*

* @exception IOException if an input/outputerror occurs

*/

protectedString processPath(HttpServletRequest request,

HttpServletResponse response)

throws IOException {

String path = null;

// For prefix matching, match on the path info (if any)

path = (String) request.getAttribute(INCLUDE_PATH_INFO);

if (path == null) {

path = request.getPathInfo();

}

if ((path != null) && (path.length() > 0)) {

return (path);

}

// For extension matching, strip the module prefix and extension

path = (String) request.getAttribute(INCLUDE_SERVLET_PATH);

if (path == null) {

path = request.getServletPath();

}

String prefix = moduleConfig.getPrefix();

if (!path.startsWith(prefix)) {

String msg =getInternal().getMessage("processPath");

log.error(msg + " " + request.getRequestURI());

response.sendError(HttpServletResponse.SC_BAD_REQUEST, msg);

return null;

}

path = path.substring(prefix.length());

int slash = path.lastIndexOf("/");

int period = path.lastIndexOf(".");

if ((period >= 0) && (period >slash)) {

path = path.substring(0, period);

}

return (path);

}

分析一下这段代码:

[java] view
plaincopyprint?

path = (String)request.getAttribute(INCLUDE_PATH_INFO);

if (path == null) {

path = request.getPathInfo();

}

if ((path != null) && (path.length() > 0)) {

return (path);

}

这段代码首先判断一下javax.servlet.include.path_info是否存在路径信息,这里要知道当当一个页面是以RequestDispatcher.include方式显示的话,这个属性值才存在。所以这里没有值,就会进入path =request.getPathInfo()程序中,这里的getPathInfo获取的值是相对servlet的路径信息。具体见博客(request.getPathInfo()方法的作用),通过那篇博客的分析,所以这里getPathInfo是获取不到值的。所以会进入下面的代码:

[java] view
plaincopyprint?

// For extension matching, stripthe module prefix and extension

path = (String) request.getAttribute(INCLUDE_SERVLET_PATH);

if (path == null) {

path = request.getServletPath();

}

String prefix = moduleConfig.getPrefix();

if (!path.startsWith(prefix)) {

String msg =getInternal().getMessage("processPath");

log.error(msg + " " + request.getRequestURI());

response.sendError(HttpServletResponse.SC_BAD_REQUEST, msg);

return null;

}

这一段代码是判断javax.servlet.include.servlet_path是否存在值,这个也是当一个页面是以equestDispatcher.include方式显示的话,这个属性值才存在,所以这里的值没有。之后进入path = request.getServletPath();这个方法是获得返回请求URI上下文后的子串,所以这里的返回值就是“/”和访问页面名称和后缀(这里和我的mvc实例截取的是不是一样的道理)。随后进入下面代码:

[java] view
plaincopyprint?

path = path.substring(prefix.length());

intslash = path.lastIndexOf("/");

intperiod = path.lastIndexOf(".");

if((period >= 0) && (period > slash)) {

path = path.substring(0, period);

}

return (path);

这里的方法主要和我的上面的那里是一样的,主要就是去掉后缀。

到此为止,截取字符串的工作就算完成了。接下来就是要和action标签匹配,把相应信息放到ActionMapping中。

随着分析的深入,这专栏的连载会越来越精彩。敬请关注!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐