AbstractWizardFormController中的command对象是如何进出session的
正常流程: Click "Next" all the way
1. 展现第一个表单时 -- 系统会创建一个空的command对象并把它放入session中
2. 提交第一个表单时 -- 系统会把command从session中取出,并立即把它从session中移除,然后再把request中的参数值塞到command中,在展现第二个表单之前,系统又会把这个对象塞回到session中
3. 提交第二个表单时 -- 系统会把command从session中取出,并立即把它从session中移除,然后再把request中的参数值塞到command中。当展现最终的结果页面时,session中已没有command对象
正常流程: Click "Back"
1. 展现第一个表单时 -- 系统会创建一个空的command对象并把它放入session中
2. 提交第一个表单时 -- 系统会把command从session中取出,并立即把它从session中移除,然后再把request中的参数值塞到command中,在展现第二个表单时,系统又把这个对象塞回到session中
3. 在第二个表单点“Back”时 -- 系统会把command从session中取出,并立即把它从session中移除,然后再把request中的参数值塞到command中。在展现第一个表单时,系统会把这个对象塞回到session中,并把对象丢到Model中,好让第一个表单展现它
异常流程:
1. 展现第一个表单时 -- 系统会创建一个空的command对象并把它放入session中
2. 错误地提交第一个表单后 -- 系统会把command从session中取出,并立即把它从session中移除,然后再把request中的参数值塞到command中;由于出错,所以会重现第一个表单,这时系统会把command塞回到session中
3. 这时如果按“F5” -- 系统就会重走第2步
4. 正确地提交第一个表单和第二个表单,直到看到结果页面 -- 到这里session中已无command
5. 如果这时用户按 "F5" 重复提交 -- 系统会试图从session中拿到command,这时已经拿不到了,那系统就会进入handleInvalidSubmit()流程,并最终回到第一个表单页面
归纳一下:
1. 每个HttpRequest结束后,如果整个Wizard未终结,就应把command存到session中,这样才能让下一个HttpRequest使用到这个command -- 所以系统每次处理完表单后,如果还有后续流程(包括Back、Next、校验出错),都要塞一下command; 如果没有后续流程(Submit),就不需要再塞了
2. 每个HttpRequest开始时,如果该Request不是Wizard的第一个Request,应先从session中把command取出来使用 -- 所以系统每次处理表单前,都会先把command从session中取出来并使用;而“第一次展现第一个表单”算是Wizard中的第一个HttpRequest,这时候不必从Session中拿command
3. 把command从session取来后,以后可能需要把它塞回去(Next, Back),也可能不需要(Submit),所以可以在取到command之后立即将它从session中移除,由后续的程序自已决定要不要重新塞回session
简化策略(待验证)
把command取出来后立即从session中移除,这是一种非常让人费解的行为。
可以简化为:仅在Submit后才删除command. 不过,这又需要在每页校验成功后设置一个标识位说“本页已校验通过”,否则下一页不知道上页的输入是否是对的。