This might be a minor thing but significantly improves the user experience. The problem usually happens when the update action forwards to the view action. Instead of doing a redirect. This means the user sees /editPerson.action in the address field of the browser. But he is really looking at /viewPerson.action. This means that if he presses reload he will resubmit the data. It also means the user can navigate back to the /editPerson.action by using the back and forward buttons or the browser history.
To avoid this you can use the
PRG (Post, Redirect and Get) Pattern. It can be summarized as follows:
Never show pages in response to POST
Always load pages using GET
Navigate from POST to GET using REDIRECT
Using the PRG approach removes this possibility by never showing the /editPerson.action to the user. This means he cannot navigate back to the page in any way. In this case it means a redirect between the editPerson action (update action) and the viewPerson action (view action).
It is easily implemented in Webwork by using the redirect result type. The final mapping of editPerson and viewPerson looks like this.
<action name="editPerson" class="example.EditPersonAction">
<result name="success" type="redirect">
<param name="location">/viewPerson.action?id=${userId}</param>
<param name="parse">true</param>
</result>
<result name="invalid.token">/duplicate_post.vm</result>
<interceptor-ref name="defaultStack"/>
<interceptor-ref name="token"/>
</action>
<action name="viewPerson" class="example.ViewPersonAction">
<result name="success">/view_person.vm</result>
<interceptor-ref name="defaultStack"/>
</action> One thing to notice is the OGNL expression in the location (/viewPerson.action?id=${userId}) This means Webwork will evaluate the expression at runtime and replace ${userId}. In this case it is taken directly from a request parameter.
In Struts you would have to manually code the redirect as far as I know.
方向:分布式系统设计