How to call a method in Struts2 Action Class metho

2019-01-29 08:56发布

问题:

We currently use the following javascript to submit the form when one of the field values change.

var url = "project/location/myAction.action?name="+ lname ; 
document.forms[0].action = url;
document.forms[0].submit();

which calls the following Struts2 action

<action name="myAction" class="project.location.NameAction">
    <result name="success" type="tiles">myAction</result>   
</action>

which then goes to the execute() method of the Action class NameAction where I have to check to see if the form was submitted from the javascript.

I would prefer to call the findName() method in NameAction directly from the javascript. In other words I want the javascript to act like the following jsp code.

<s:submit method="findName" key="button.clear" cssClass="submit" >

Any help would be appreciated!

回答1:

There are different ways to achieve what you want, but probably the simpler is to map different actions to different methods of the same action class file, eg. with annotations:

public class NameAction {

    @Action("myAction")
    public String execute(){ ... }

    @Action("myActionFindName")
    public String findName(){ ... }

}

or with XML:

<action name="myAction" class="project.location.NameAction">
    <result name="success" type="tiles">myAction</result>   
</action>

<action name="myActionFindName" class="project.location.NameAction" method="findName">
    <result name="success" type="tiles">myAction</result>   
</action>

Then in javascript:

var url = "project/location/myActionFindName.action?name="+ lname ;


回答2:

You can use the same action class to map different methods using method attribute

<action name="myAction" class="project.location.NameAction" method="findName">

By default the method attribute if omitted uses execute method.

This approach requires changing the action name and hence URL to map the action. If you want to keep the same URL for different actions, then you should pass a method name as parameter to the action. Then in execute method parse this parameter for the method name and call the corresponding method.

When DMI was enabled in the previous versions to call the method you could use a method attribute of the s:submit tag. Currently the method: parameter name is blocked by the params interceptor, even if it gets to the action mapper.

You also read other possibilities from the How to exclude the submit action from a list of parameters in struts2.



回答3:

For completeness here is how I implemented the advice from Andrea and Roman.

When the user enters data in both the firstName and lastName fields we show them a list of names to choose from to fill in the rest of the form. The jsp is

                <div class="row">
                <div class=" col-sm-2 col-xs-12 no-padding-right text-right"><span class="required">*</span><label class="pull-right" for="lastNameId"><s:text name="lastName"></s:text>:</label></div>             
                <div class=" col-sm-2 col-xs-12 no-padding-right ">
                    <s:textfield name="lastName"  id="lastNameId" maxlength="50" onchange ="dirtyFlag();" onblur="selectNameInfo(\'newRequest\');" class="form-control"/>
                </div>
                <div class=" col-sm-2 col-xs-12 no-padding-right text-right " ><span class="required">*</span><label class="pull-right" for="firstNameId"><s:text name="firstName"></s:text>:</label></div>             
                <div class=" col-sm-2 col-xs-12 no-padding-right ">
                    <s:textfield name="firstName" id="firstNameId" maxlength="50" onchange ="dirtyFlag();" onblur="selectNameInfo(\'newRequest\');" class="form-control"/>
                </div>   
            </div>      

The javascript is

        function selectNameInfo(formId) {
        var lastName = document.forms[0].elements["lastNameId"].value;
        var firstName = document.forms[0].elements["firstNameId"].value;

        if(lastName != "" && firstName != ""){
        clearDirtyFlag(); 
        var oldAction = document.getElementById(formId).action;
        var actionName = document.getElementById(formId).name;
        var url = oldAction.replace(actionName,actionName+"_NameSearch");
            document.forms[0].action = url;
            document.forms[0].submit();
        };
    }

The javascript forms a url by adding "_NameSearch" to the action of the form calling the selectNameInfo() function. In this case the new action is newRequest_NameSearch which goes to the following xml which calls the generateNameList() method of the action class without using DMI which was my original question.

    <action name="newRequest_NameSearch" class="gov.mo.dnr.egims.controller.evaluation.NewRequestAction" method = "generateNameList">           
        <result name="success" type="tiles">newRequest</result>
        <result name="nameSearch" type="tiles">selectNameInfo</result>
        <result name="error" type="tiles">error</result>            
    </action>