Struts源码研究 - Action-Input属性篇
n (this.inputForward);
}
public void setInputForward(boolean inputForward) {
this.inputForward = inputForward;
}
====================================================
开始有点明白了,原来inputForward这个属性默认值是false,那么由于没有配置这个属性,那么上述的那个方法
moduleConfig.getControllerConfig().getInputForward()自然就返回false了,Bingo!
那么重点就转移到了internalModuleRelativeForward这个方法了,看这个方法的源代码,如下:
====================================================
protected void internalModuleRelativeForward(
String uri,
HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException {
// Construct a request dispatcher for the specified path
uri = moduleConfig.getPrefix() + uri;
// Delegate the processing of this request
// FIXME - exception handling?
if (log.isDebugEnabled()) {
log.debug(" Delegating via forward to '" + uri + "'");
}
doForward(uri, request, response);
}
protected void doForward(
String uri,
HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException {
// Unwrap the multipart request, if there is one.
if (request instanceof MultipartRequestWrapper) {
request = ((MultipartRequestWrapper) request).getRequest();
}
RequestDispatcher rd = getServletContext().getRequestDispatcher(uri);
if (rd == null) {
response.sendError(
HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
getInternal().getMessage("requestDispatcher", uri));
return;
}
rd.forward(request, response);
}
====================================================
从上可以看到,这个方法是将uri = moduleConfig.getPrefix() + uri;这个东东传给了doForward方法
而doForward这个方法又调用了javax.servlet.ServletContext的方法getRequestDispatcher这个方法
既然出错信息中是路径出了问题,那么看来这个参数uri非常的重要,极有可能就是这个uri发生了错误导致了出错
OK,开始剖析这个uri,从头开始看,这个uri是这样被赋值的:
uri = moduleConfig.getPrefix() + uri
1、moduleConfig.getPrefix()这个方法返回的应该是""
(这个请看ActionServlet的Init方法,如果在web.xml文件中定义ActionServlet的时候,给定了一些init-params,那么这个prefix就有可能
不为空,这里不再列举了)
2、代码右边的这个uri是从processValidate这个方法中定义的input,如下:
String input = mapping.getInput();
这个input应该是struts-config.xml文件中定义的那个action的input,也就是“createuser”,如果Struts将其做了进一步的解析,那么这个
input应该进一步被转化成为“/jsp/createuser.jsp”
好,到此为止,可以看到,这个uri不是“createuser”,那就是“/jsp/createuser.jsp”,再来看getRequestDispatcher这个方法的定义,
翻开Servlet的API文档,可以看到如下一段话:
====================================================
public RequestDispatcher
getRequestDispatcher(java.lang.String path)Returns a RequestDispatcher object that acts as a wrapper
for the resource located at the given path. A RequestDispatcher object can be used to forward a request
to the resource or to include the resource in a response. The resource can be dynamic or static.
The pathname must begin with a "/" and is interpreted as relative to the current context root.
Use getContext to obtain a RequestDispatcher for resources in foreign contexts. This method returns null
if the ServletContext cannot return a RequestDispatcher.
====================================================
终于有拨云见日的感觉了,因为这段话和出错信息实在是太一致了!由上面这段话,我们可以断定,uri这个变量的值
肯定是“createuser”,而不是我们所希望的“/jsp/createuser.jsp”。为什么会这样呢?显然是struts-config.xml中配置
有些还是不对,或是缺了点什么。想到这里,很自然的就联想到上面所提到的InputForward这个配置项了,因为从字面意思上
看来,这个配置项的用处就应该是将input的值解析成forward中对应的值,而且在ControllerConfig中,这个变量默认值是
false,所以猜测将其改成true是不是就可以了呢?
为了寻找答案,再次翻开struts-example(因为这个例子中的action也定义了input),终于找到了答案,和之前猜测的果然
十分吻合,如下:
====================================================
<controller>
<set-property property="inputForward" value="true"/>
</controller>
====================================================
至此,问题解决,正确的action配置可以是如下两种:
====================================================
1、不使用inputForward
<action
path="/docreateuser"
type="com.zchome.CreateUserAction"
name="CreateUserForm"
scope="request"
input="/jsp/createuser.jsp">
<forward name="createusersuccess" path="/jsp/Welcome.jsp"/>
</action>
2、使用InputForward
<action
path="/docreateuser"
type="com.zchome.CreateUserAction"
name="CreateUserForm"
scope="request"
input="createuser">
<forward name="createusersuccess" path="/jsp/Welcome.jsp"/>
<forward name="createuser" path="/jsp/createuser.jsp"/>
</action>
<controller>
<set-property property="inputForward" value="true"/>
<se
}
public void setInputForward(boolean inputForward) {
this.inputForward = inputForward;
}
====================================================
开始有点明白了,原来inputForward这个属性默认值是false,那么由于没有配置这个属性,那么上述的那个方法
moduleConfig.getControllerConfig().getInputForward()自然就返回false了,Bingo!
那么重点就转移到了internalModuleRelativeForward这个方法了,看这个方法的源代码,如下:
====================================================
protected void internalModuleRelativeForward(
String uri,
HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException {
// Construct a request dispatcher for the specified path
uri = moduleConfig.getPrefix() + uri;
// Delegate the processing of this request
// FIXME - exception handling?
if (log.isDebugEnabled()) {
log.debug(" Delegating via forward to '" + uri + "'");
}
doForward(uri, request, response);
}
protected void doForward(
String uri,
HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException {
// Unwrap the multipart request, if there is one.
if (request instanceof MultipartRequestWrapper) {
request = ((MultipartRequestWrapper) request).getRequest();
}
RequestDispatcher rd = getServletContext().getRequestDispatcher(uri);
if (rd == null) {
response.sendError(
HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
getInternal().getMessage("requestDispatcher", uri));
return;
}
rd.forward(request, response);
}
====================================================
从上可以看到,这个方法是将uri = moduleConfig.getPrefix() + uri;这个东东传给了doForward方法
而doForward这个方法又调用了javax.servlet.ServletContext的方法getRequestDispatcher这个方法
既然出错信息中是路径出了问题,那么看来这个参数uri非常的重要,极有可能就是这个uri发生了错误导致了出错
OK,开始剖析这个uri,从头开始看,这个uri是这样被赋值的:
uri = moduleConfig.getPrefix() + uri
1、moduleConfig.getPrefix()这个方法返回的应该是""
(这个请看ActionServlet的Init方法,如果在web.xml文件中定义ActionServlet的时候,给定了一些init-params,那么这个prefix就有可能
不为空,这里不再列举了)
2、代码右边的这个uri是从processValidate这个方法中定义的input,如下:
String input = mapping.getInput();
这个input应该是struts-config.xml文件中定义的那个action的input,也就是“createuser”,如果Struts将其做了进一步的解析,那么这个
input应该进一步被转化成为“/jsp/createuser.jsp”
好,到此为止,可以看到,这个uri不是“createuser”,那就是“/jsp/createuser.jsp”,再来看getRequestDispatcher这个方法的定义,
翻开Servlet的API文档,可以看到如下一段话:
====================================================
public RequestDispatcher
getRequestDispatcher(java.lang.String path)Returns a RequestDispatcher object that acts as a wrapper
for the resource located at the given path. A RequestDispatcher object can be used to forward a request
to the resource or to include the resource in a response. The resource can be dynamic or static.
The pathname must begin with a "/" and is interpreted as relative to the current context root.
Use getContext to obtain a RequestDispatcher for resources in foreign contexts. This method returns null
if the ServletContext cannot return a RequestDispatcher.
====================================================
终于有拨云见日的感觉了,因为这段话和出错信息实在是太一致了!由上面这段话,我们可以断定,uri这个变量的值
肯定是“createuser”,而不是我们所希望的“/jsp/createuser.jsp”。为什么会这样呢?显然是struts-config.xml中配置
有些还是不对,或是缺了点什么。想到这里,很自然的就联想到上面所提到的InputForward这个配置项了,因为从字面意思上
看来,这个配置项的用处就应该是将input的值解析成forward中对应的值,而且在ControllerConfig中,这个变量默认值是
false,所以猜测将其改成true是不是就可以了呢?
为了寻找答案,再次翻开struts-example(因为这个例子中的action也定义了input),终于找到了答案,和之前猜测的果然
十分吻合,如下:
====================================================
<controller>
<set-property property="inputForward" value="true"/>
</controller>
====================================================
至此,问题解决,正确的action配置可以是如下两种:
====================================================
1、不使用inputForward
<action
path="/docreateuser"
type="com.zchome.CreateUserAction"
name="CreateUserForm"
scope="request"
input="/jsp/createuser.jsp">
<forward name="createusersuccess" path="/jsp/Welcome.jsp"/>
</action>
2、使用InputForward
<action
path="/docreateuser"
type="com.zchome.CreateUserAction"
name="CreateUserForm"
scope="request"
input="createuser">
<forward name="createusersuccess" path="/jsp/Welcome.jsp"/>
<forward name="createuser" path="/jsp/createuser.jsp"/>
</action>
<controller>
<set-property property="inputForward" value="true"/>
<se

