1

我已经完成了同样问题的答案,但是 Struts 中没有任何默认方法可以防止重新提交吗?另外,就我而言,如果我确实重置了表单字段,它仍然会保存旧值(但它如何获取这些值)?

我有一个调度动作类:

public class QrcAction extends DispatchAction
{
    public ActionForward waiverPage( final ActionMapping inMapping,
                                     final ActionForm inForm,
                                     final HttpServletRequest inRequest,
                                     final HttpServletResponse inResponse )
    {
        QrcForm qrcForm = (QrcForm) inForm;
        if ( StringUtils.isEmpty( qrcForm.getCustomerId() ) )
        {
            ActionMessages errors = getErrors( inRequest );
            errors.add( IAppConstants.APP_ERROR, new ActionMessage( IPropertiesConstant.ERROR_INVALID_CUSTOMER_ID ) );
            saveErrors( inRequest, errors );
            return inMapping.findForward( IActionForwardConstant.QRC_SEARCH_CUSTOMER_PAGE );
        }
        qrcForm.setCustWaiverPojo( new CrmCustWaiverPojo() );
        qrcForm.setRemarksPojo( new RemarksPojo() );
        return inMapping.findForward( IActionForwardConstant.WAIVER_PAGE );
    }

    public ActionForward applyWaiver( final ActionMapping inMapping,
                                      final ActionForm inForm,
                                      final HttpServletRequest inRequest,
                                      final HttpServletResponse inResponse )
    {
        String forward = IActionForwardConstant.WAIVER_PAGE;
        QrcForm qrcForm = (QrcForm) inForm;
        ActionMessages messages = getMessages( inRequest );
        ActionMessages errors = getErrors( inRequest );
        CrmuserDetailsDto userDto = (CrmuserDetailsDto) inRequest.getSession( false )
                .getAttribute( IAppConstants.CRM_USER_OBJECT );
        
        double waiverLimit = 0;
        if ( StringUtils.isNotEmpty( userDto.getWaiverLimitAmmount() ) )
            waiverLimit = Double.parseDouble( userDto.getWaiverLimitAmmount() );
        if ( waiverLimit < qrcForm.getCustWaiverPojo().getWaiverAmount().doubleValue() )
        {
            errors.add( IAppConstants.APP_ERROR, new ActionMessage( IPropertiesConstant.ERROR_INVALID_WAIVER_LIMIT,
                                                                    waiverLimit ) );
        }
        QrcFormHelper.validateWaiver( errors, qrcForm );  // validates pojo fields

        if ( errors.isEmpty() )
        {
            // saving data to database
            if ( success )
            {
                messages.add( IAppConstants.APP_MESSAGE, new ActionMessage( "success.msg.key" ) );
                // resetting the form fields
                qrcForm.setCustWaiverPojo( new CrmCustWaiverPojo() );
                qrcForm.setRemarksPojo( new RemarksPojo() );
                qrcForm.setSrTicketNo( null );
            }
            else
                errors.add( IAppConstants.APP_ERROR, new ActionMessage( "error.msg.key" ) );
        }
        saveErrors( inRequest, errors );
        saveMessages( inRequest, messages );
        return inMapping.findForward( forward );
    }
}

waiverPage()调用以显示表单并提交给applyWaiver(). 在applyWaiver()成功保存值时,我正在重置表单字段并将其转发到同一页面。提交并成功后,将显示一条消息并清除表单,然后如果我再次刷新它,请使用相同的先前值在 db 中输入。
这个问题有什么解决办法吗?

更新
waiver.jsp

<html:form action="manageQrc.do?method=applyWaiver">
    <html:hidden property="custWaiverPojo.customerId" name="qrcForm" value="${ qrcForm.customerId }"/>
    <label class="label_radio"> 
        <html:radio property="custWaiverPojo.waiverType" value="Goodwill Wavier" name="qrcForm" styleClass="waiverType">Goodwill</html:radio>
    </label> 
    <label class="label_radio"> 
        <html:radio property="custWaiverPojo.waiverType" value="Process Wavier" name="qrcForm" styleClass="waiverType">Process</html:radio>
    </label>
    <strong> Select Category </strong> 
    <span class="LmsdropdownWithoutJs"> 
        <html:select property="custWaiverPojo.waiverHead" name="qrcForm" styleId="waiverHead">
            <html:option value="">Please Select</html:option> <!-- options are filled after radio button selection -->
      </html:select>
    </span>
    <strong>Amount</strong>
    <html:text property="custWaiverPojo.waiverAmount" name="qrcForm" styleClass="textbox" styleId="waiverAmount" maxlength="10"></html:text>
    <strong>Bill No. </strong> 
    <span class="LmsdropdownWithoutJs"> 
        <html:select property="custWaiverPojo.billNo" name="qrcForm" styleId="waiverBill">
            <html:option value="0">Please Select</html:option>
            <html:option value="20140101">20140101</html:option>
            <html:option value="20140201">20140201</html:option>
            <html:option value="20140301">20140301</html:option>
            <html:option value="20140401">20140401</html:option>
        </html:select>
    </span>
    <strong>Ticket ID</strong>
    <html:text property="srTicketNo" name="qrcForm" maxlength="20" styleClass="textbox" styleId="waiverSRT"></html:text>
    <strong> Remarks</strong>
    <html:textarea property="remarksPojo.remarks" name="qrcForm" styleClass="LmsRemarkstextarea" styleId="waiverRemarks"></html:textarea>
    <html:submit />
</html:form>
4

2 回答 2

1

在成功保存值的 applyWaiver() 中,我正在重置表单字段并将其转发到同一页面。

这是一个问题,因为在提交后您应该重定向到会显示页面的操作。如果它不是会话范围,您还可以在操作中填充表单 bean。因此,在代码中使用重定向到动作的转发

public ActionForward applyWaiver( final ActionMapping inMapping,
                                  final ActionForm inForm,
                                  final HttpServletRequest inRequest,
                                  final HttpServletResponse inResponse )
{
    ...

    if (! errors.isEmpty() )
    {
        errors.add( IAppConstants.APP_ERROR, new ActionMessage( "error.msg.key" ) ;

        // resetting the form fields
        qrcForm.setCustWaiverPojo( new CrmCustWaiverPojo() );
        qrcForm.setRemarksPojo( new RemarksPojo() );
        qrcForm.setSrTicketNo( null );

        saveErrors( inRequest, errors );
        saveMessages( inRequest, messages );
        return inMapping.findForward( forward );
    }

    MessageResources mr = (MessageResources) inRequest.getAttribute(Globals.MESSAGES_KEY);
    // saving data to database
    if ( success )
        inRequest.setAttribute( IAppConstants.APP_MESSAGE, mr.getMessage( "success.msg.key" ) );
    else
        inRequest.setAttribute( IAppConstants.APP_MESSAGE, mr.getMessage( "error.msg.key" ) );

    return new ActionForward(inMapping.findForward( forward ).getPath(), true ); //true is for redirect 
}
于 2014-10-31T11:50:41.550 回答
1

博客中的解决方案使用令牌将请求标识为:

第 1 步:使用实现的方法
将令牌保存在会话中。saveToken()Action class

public class EmployeeLoadAction extends Action{
    private final static String SUCCESS = "success";
    @Override
    public ActionForward execute(ActionMapping mapping, ActionForm form,
    HttpServletRequest request, HttpServletResponse response)
    throws Exception {
        ActionForward forward;
        forward = mapping.findForward(SUCCESS);
        saveToken(request);
        return forward;
    }
}

第 2 步:
在 JSP 文件中。在此示例employee.jsp
中,使用隐藏变量将令牌存储在 JSP 文件中,如下所示。不要忘记在 JSP 文件中导入GlobalsConstants分类以避免Jasper Exception

TRANSACTION_TOKEN_KEY不推荐使用内部变量Action class,因此请改用它Globlas class

<%@ page import="org.apache.struts.Globals" %>
<%@ page import="org.apache.struts.taglib.html.Constants" %>
<html>
    <head>
      <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
      <title>Insert title here</title>
    </head>
    <body>
      <form name="employee" action="EmployeeSubmit.do" method="POST">
        <input type="hidden" name="<%= Constants.TOKEN_KEY %>" value="<%= session.getAttribute(Globals.TRANSACTION_TOKEN_KEY) %>">
        <TABLE>
          <TR>
            <TD>Name</TD>
            <TD>
              <input type="text" name="empName">
            </TD>
          </TR>
          <TR>
            <TD>ID</TD>
            <TD>
              <input type="text" name="empId">
            </TD>
          </TR>
          <TR>
            <TD colspan="2">
              <input type="submit" value="Submit">
            </TD>
          </TR>
        </TABLE>
      </form>
    </body>
</html>

第 3 步:现在在动作类
中重复提交的实际逻辑。EmployeeSubmit方法isTokenValid()将验证令牌并返回boolean. 基于此,我们可以决定是否重新提交了表单。

public class EmployeeSubmitAction extends Action{
    private final static String SUCCESS = "success";
    @Override
    public ActionForward execute(ActionMapping mapping, ActionForm form,
    HttpServletRequest request, HttpServletResponse response)
    throws Exception {
        ActionForward forward;
        forward = mapping.findForward(SUCCESS);
        EmployeeSubmitForm frm = (EmployeeSubmitForm) form;
        if (isTokenValid(request)) {
            System.out.println("frm.getName() : " + frm.getEmpName());
            resetToken(request);
        } else {
            System.out.println("frm.getName() : " + frm.getEmpName());
            System.out.println("Duplicate Submission of the form");
        }
        return forward;
    }
}
于 2014-11-03T06:30:10.260 回答