Hi,
Check the instruction given below.
Our web application has one limitation , and this limitation is growing day by day. This limitation is because of stateless nature of http protocol. Struts framework has managed this problem specified below.
So please read this article and make required changes into your code. We will make some schedule so that our web application will be bug free in future.
Not Checking for Duplicate Form Submissions
Aside effect of the stateless nature of the HTTP protocol is that the interface
presented in the browser can easily get out of sync with the state of the
model on the server. There is a common pitfall involving this lack of synchronization
that must be dealt with in nearly every application. This occurs
when a user submits values using a form on a given page and then, at some
later point, backtracks to the cached page, edits the now stale values, and
resubmits the form. This has the potential to corrupt the underlying data
store by creating duplicate records, overwriting current data with stale values,
and so on. In the best case, it creates a bad transaction that is rejected by
the data store.
This pitfall potentially affects nearly every
JSP containing a form tag. In
most projects, the problems show up during system
test. Fortunately for
developers, system testers are generally wise enough to include scenarios
in their test scripts that expose this type of bug. Developers, on the other
hand, rarely test for these conditions.
Example
The code that follows represents a typical naive form implementation that
is trapped in this pitfall. If we don�t do anything special to prevent it, the
user can use the HTML generated by this JSP to submit the same form multiple
times.
<html:form action=�/saveInvoice� method=�post�>
<table>
<tr>
<td><bean:message
key=�<%=Constants.INVOICE_NUMBER_LABEL_KEY%>�/><td>
<td><html:text property=�invoiceNumber�/></td>
</tr>
<tr>
<td><bean:message
key=�<%=Constants.BILLING_DATE_LABEL_KEY%>�/><td>
<td><html:text property=�billingDate�/></td>
</tr>
<tr>
<td><bean:message
key=�<%=Constants.AMOUNT_KEY%>�/><td>
<td><html:text property=�amount�/></td>
</tr>
<td colspan=3 align=�right�><html:submit/></td>
</tr>
</table>
</html:form>
One of the common mechanisms to control this pitfall, and the one that
will be explored in the accompanying solution, is to have forms submit
tokens that the application can check to ensure that the forms are not
submitted more than once.
Solving Pitfall 4.7: Add Tokens to Generated JSP
To solve this pitfall, we will make use of one of the more obscure features
of Struts. The token management facility is provided by the Action and
FormTag classes, comprising a small group of Action methods that provide
for token generation and checking, and largely undocumented code in the
FormTag to render the generated tokens automatically. Taken together,
these two features make it quite easy to check for duplicate submissions.
Our goal here is to ensure that forms are submitted only when they contain
fresh data. In essence, we�re trying to exert some control over the flow
of the application. To do that, we can call on Struts to place tokens in our
forms as necessary, so that we can check the submitted token against a
copy cached on the server.
Step-by-Step
1. Choose a form.
2. Identify the Action that navigates to the form.
a. Add code to generate a token.
3. Identify the Action that handles submission of the form.
a. Add code to check the generated token and to generate a new
one if the Action is successful.
4. Test the implementation.
5. Continue with other Actions until all form-submission scenarios
have been covered.
Example
The first step in the solution is to choose a form. We will begin this example
by choosing the FindInvoice form. The next step is to identify the
Action that navigates to the form and add code to generate the token. The
Action that navigates to the form is the FindInvoiceAction. This is the code
for that action with the token generation added.
public class FindInvoiceAction extends BaseAction
{
public ActionForward execute(ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException
{
...
saveToken(request); // This is all we need to add
return mapping.findForward(�saveInvoicePage�);
}
}
The FormTag class takes care of inserting the token for you if a value for
it has been set, as we did above with saveToken in the FindInvoiceAction.
The next step is to identify the action that handles submission of the
form and add code to that form that will make sure that the tokens match
and then generate a new token if the form submission was successful. Listing
4.5 is the code for the SaveInvoiceAction that has been modified to
check the token.
public class SaveInvoiceAction extends BaseAction
{
public ActionForward execute(ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response)
throws Exception {
// Check the token. If it doesn�t match the token currently in
// the session, it�s stale.
if (!isTokenValid(request)) {
postGlobalError(Constants.DUPLICATE_FORM_ERROR, request);
return mapping.findForward(�saveInvoicePage�);
}
...
// if we got this far, everything worked okay, so generate
Listing 4.5 Checking the token in SaveInvoiceAction. (continues)
// a new token.
saveToken(request);
return mapping.findForward(�confirmInvoicePage�);
}
}
Listing 4.5 (continued)
The final step is to deploy and test the code to make sure it functions
properly. Once you have a working implementation, you can add token
generation and checking wherever else it is needed. Extra care should be
taken in testing the solution to ensure that forms cannot be resubmitted
under any odd combinations of circumstances.