先来看具体struts中processActionForm方法的具体实现:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- protectedActionForm processActionForm(HttpServletRequestrequest,
-
- HttpServletResponse response,
-
- ActionMapping mapping) {
-
-
-
-
-
- ActionForm instance = RequestUtils.createActionForm
-
- (request, mapping, moduleConfig, servlet);
-
- if (instance == null) {
-
- return (null);
-
- }
-
-
-
-
-
- if (log.isDebugEnabled()) {
-
- log.debug(" Storing ActionForm bean instance in scope '" +
-
- mapping.getScope() + "' under attribute key '" +
-
- mapping.getAttribute() + "'");
-
- }
-
- if ("request".equals(mapping.getScope())) {
-
- request.setAttribute(mapping.getAttribute(), instance);
-
- } else {
-
- HttpSession session =request.getSession();
-
- session.setAttribute(mapping.getAttribute(), instance);
-
- }
-
- return (instance);
-
-
-
- }
这个方法的大体流程是:根据ActionMapping中的name名称查找ActionForm,如果配置了ActionForm,那么就到request或session中查找,如果在request或session中存在已经创建的ActionForm,那么将返回。如果不存在那么会根据ActionForm的完成路径采用反射进行创建,再将创建好的ActionForm放到request或session中,之后返回ActionForm。
具体我们可以跟随断点调试来看看这个方法是如何运行的。
首先还是同上篇博客中的方法一样,先设置断点,之后进入processActionForm方法。
第一个步骤就是创建ActionForm:
-
-
- ActionForm instance = RequestUtils.createActionForm
-
- (request, mapping, moduleConfig, servlet);
-
- if (instance == null) {
-
- return (null);
-
- }
-
-
-
-
通过调用RequestUtils.createActionForm的方法把ActionMapping中的ActionForm字符串生成对象,并且返回。进入这段代码中:
- publicstaticActionForm createActionForm(
-
- HttpServletRequest request,
-
- ActionMapping mapping,
-
- ModuleConfig moduleConfig,
-
- ActionServlet servlet) {
-
-
-
-
-
- String attribute = mapping.getAttribute();
-
- if (attribute == null) {
-
- return (null);
-
- }
-
-
-
-
-
- String name = mapping.getName();
-
- FormBeanConfig config =moduleConfig.findFormBeanConfig(name);
-
- if (config == null) {
-
- log.warn("No FormBeanConfig found under '"+ name + "'");
-
- return (null);
-
- }
-
-
-
- ActionForm instance = lookupActionForm(request,attribute, mapping.getScope());
-
-
-
-
-
- try {
-
- if (instance != null && canReuseActionForm(instance,config)) {
-
- return (instance);
-
- }
-
- } catch(ClassNotFoundException e) {
-
- log.error(servlet.getInternal().getMessage("formBean",config.getType()), e);
-
- return (null);
-
- }
-
-
-
- return createActionForm(config,servlet);
-
- }
方法首先定义变量nama,并且从mapping中获取值,String name = mapping.getName();也就是我们实例中的LoginForm字符串。之后通过调用FormBeanConfig config =moduleConfig.findFormBeanConfig(name);这句话把相应的LoginForm字符串生成相应的对象。
这里要说明的是我们在struts-config配置文件中,配置过这样一个标签信息:
-
-
- <form-beans>
-
- <form-bean name="loginForm" type="com.bjpowernode.struts.LoginActionForm"/>
-
- </form-beans>
这个标签在服务器一启动的时候就会利用digester读取这里的配置信息,并且放在FormBeanConfig类中,这样我们可以通过上面那一句话就可以把LoginForm字符串生成相应的对象。
之后调用了ActionForm instance = lookupActionForm(request,attribute, mapping.getScope());这个方法,这个方法主要是查找scope属性中有没有存在ActionForm。具体实现:
- if ("request".equals(scope)){
-
- instance = (ActionForm)request.getAttribute(attribute);
-
- } else {
-
- session = request.getSession();
-
- instance = (ActionForm)session.getAttribute(attribute);
-
- }
这里判断scope属性值是否为request,如果是则从request中读出ActionForm,如果不是则从session中读出。程序如果是第一次执行,那么ActionForm会是为空的。因为这里的ActionForm为空,所以就进入了if判断语句中,最后通过调用return createActionForm(config, servlet);创建ActionForm并且返回。
之后processActionForm就会把返回来的ActionForm放入request或者session中。具体实现就是:
- if ("request".equals(mapping.getScope())){
-
- request.setAttribute(mapping.getAttribute(), instance);
-
- } else {
-
- HttpSession session =request.getSession();
-
- session.setAttribute(mapping.getAttribute(), instance);
-
- }
到此为止,ActionForm就创建完成