2

Here is my form

  <s:form action="changeStatus">
    <s:div class="table">
        <s:textfield name="custId" label="CUSTOMER ID" />
        <s:textfield name="lifewardsCard" label="LIFE WARDS CARD NUMBER"
            size="20" />
        <s:textfield name="clientNo" label="CLIENT NUMBER" />
        <s:textfield name="custName" label="CUSTOMER NAME" />
        <s:textfield name="cardExpiryDate" label="CARD EXPIRY DATE(MMYYYY)" />
        <s:select name="status" label="CARD STATUS"
            list="#{'1':'Active', '2':'Inactive'}" />
        <tr>
            <td><s:submit value="search" theme="simple" /></td>
            <td><s:submit value="save" theme="simple" /></td>
            <td><s:submit type="button" theme="simple"
                    onclick="clear();return false;" value="clear" /></td>
        </tr>
    </s:div>
</s:form>

user will input the field custID and clicks search button I am able to get the values from database and show them on the page but what I wanted to do is after displaying the data he can edit the data and should be able to save the data by clicking save button. here's my xml configuration

<action name="changeStatus" class="com.struts.lifewardscard.ChangeAction">
    <result name="input">ChangeCardStatus.jsp</result>  
    <result name="success">ChangeCardStatus.jsp</result>
</action>       

and here is my action class

public class ChangeAction extends ActionSupport implements ModelDriven {
    CardStatusForm cardSform=new CardStatusForm();
    public String execute() throws Exception{
        String clientId=null;
        HttpServletRequest request = ServletActionContext.getRequest();
        getCardHolderDetails();     
        return "success";

    }

    private void getCardHolderDetails() {
        Connection c = null;
        Boolean empty = true;
        DateFormat inputFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss.S");

        // Format date into output format
        DateFormat outputFormat = new SimpleDateFormat("dd-MMM-yyyy");
        try {
            c = Conexion.getConnection();
            CallableStatement cst = c
                    .prepareCall("{call P_GET_CARD_DETAIILS(?,?)}");
            cst.setString(1, cardSform.getCustId());
            cst.registerOutParameter(2, OracleTypes.CURSOR);
            cst.executeUpdate();
            ResultSet rs = (ResultSet) cst.getObject(2);
            while (rs.next()) {
                cardSform.setLifewardsCard(rs.getString(1));
                cardSform.setClientNo(rs.getString(2));
                if(rs.getString(3).equalsIgnoreCase("active"))
                {
                    cardSform.setStatus(1);
                }else
                {
                    cardSform.setStatus(2);
                }

                cardSform.setCustName(rs.getString(4));
                cardSform.setCardExpiryDate(rs.getString(5));
                System.out.println(inputFormat.parse(rs.getString(6)));
                empty = false;
            }

        } catch (Exception e) {
            e.printStackTrace();
        }


    }


    @Override
    public Object getModel() {
        // TODO Auto-generated method stub
        return cardSform;
    }
}

even though I can write a method that can save the data in action class I dont find a way to call that method with out calling the other method getCardHolderDetails().

Roman C
  • 49,761
  • 33
  • 66
  • 176
Ashok Ogirala
  • 121
  • 2
  • 15
  • @AleksandrM Can you elaborate how to use `method:` prefix and why OP didn't use it in his/her question? I *really* love to use this prefix instead of ugly `action:` or better without any prefixes. – Roman C Oct 05 '15 at 10:45
  • @RomanC: Where did you find method prefix in those questions? ;) Anyway from the docs: *To use method attribute (to use multiple submit buttons which direct to different action methods) you must set struts.enable.DynamicMethodInvocation to true but this can lead to security vulnerability - use with care!*. – Aleksandr M Oct 05 '15 at 10:56
  • @AleksandrM The linked one by you, and yes that docs is correct... – Roman C Oct 05 '15 at 10:58
  • @RomanC: Nope. There isn't any reference to method prefix. – Aleksandr M Oct 05 '15 at 11:00
  • @RomanC: method="add" is form struts.xml which has nothing to do with method prefix. There were no setting for action prefix prior to `2.3.15.3` and my answer dates way back that time. :) – Aleksandr M Oct 05 '15 at 11:11
  • @AleksandrM Oops, my bad reading, sorry :|. – Roman C Oct 05 '15 at 11:19
  • @RomanC: It happens. Don't worry. ;) – Aleksandr M Oct 05 '15 at 11:20

2 Answers2

2

You should define an action for each logical action you need to perform.

Multiple actions can reside

  • in different Java classes (eg ReadCardAction.java, UpdateCardAction.java, etc.) or
  • in a single Java class with multiple methods (eg. CardAction.java with read() and update()).

Using a single Java class can be handy if you need to share common logic and helper methods, otherwise you can exploit the inheritance to achieve the same with single files, as described here.

To call two different actions from within a single form, there are three ways:

  1. Using the action attribute:

    <s:submit value="search"                     />
    <s:submit value="save"   action="saveStatus" />
    

    This way, search will call form's action method (changeStatus), that will default to execute(), while save will call saveStatus action, that you will map to an update() method:

    <action name="changeStatus" class="com.struts.lifewardscard.ChangeAction">        
        <result name="success">ChangeCardStatus.jsp</result>
        <result name="input">ChangeCardStatus.jsp</result>  
    </action>
    
    <action name="saveStatus" class="com.struts.lifewardscard.ChangeAction" method="update">
        <result name="success">ChangeCardStatus.jsp</result>
        <result name="input">ChangeCardStatus.jsp</result>  
    </action>
    

    To do this on Struts2 > 2.3.15.2 you need to activate the action prefix in struts.xml as described here.

  2. Changing the target of the form with Javascript on button click;

    • when clicking search, point to changeStatus,

    • when clicking save, point to saveStatus.

    You will find thousands of examples of how to do this.

  3. Dynamic Method Invocation (DMI). Discouraged, deprecated, do not try this at home. I'm just including it for completeness, because you could get into it in the future while reading someone else's legacy code, and saying "whut ?".

Community
  • 1
  • 1
Andrea Ligios
  • 49,480
  • 26
  • 114
  • 243
  • But basically 1. it is DMI :) And we are working hard to bring DMI back :) – Lukasz Lenart Oct 06 '15 at 14:16
  • Well, sort of @LukaszLenart, DMI lets you call an action's method, the action prefix is much less powerful, allowing you just to call a mapped action. I'd rather call it half-DMI... it still sounds weird to manually changing the target with javascript *every* time, sounds too hackishly un-automatic, but I guess that a vanilla javascript changing the target could be generated directly by the theme(s) for `` in a transparent way... that would be interesting. My 2 cents obviously – Andrea Ligios Oct 06 '15 at 14:39
2

Another way

Use the name attribute and the pressed button will be included in the request

<td><s:submit name="search" value="search" theme="simple" /></td>
<td><s:submit name="save"   value="save"   theme="simple" /></td>

Execute method

 public String execute() throws Exception{
        String clientId=null;
        HttpServletRequest request = ServletActionContext.getRequest();
        if (request.getParameter("search") != null) {
          // search button pressed   
           ....
        } else if (request.getParameter("save") != null) {
          // save button pressed
           ....
        }
        return "success";
 }
Andrea Ligios
  • 49,480
  • 26
  • 114
  • 243
tib
  • 195
  • 1
  • 7