Using ModelDriven in Struts 2

1.5k Views Asked by At

I am developing a project using Hibernate, Struts 2 and Spring, but my problems are with Struts.

I have created 3 classes extending ActionSupport and are implementing ModelDriven for the same class in all of them. I have implemented some methods to be executed when the actions are called.

The structure for the classes is like

Class1Action.java:

public class Class1Action extends ActionSupport implements ModelDriven<ModelDrivenClass> {

     private ModelDrivenClass modelDrivenClass;


     // getter and setter for modelDrivenClass

     public String methodName() {

     System.out.println("Entrou!");

        return SUCCESS;

    }

    @Override
    public Sensor getModel() {
        return getSensor();
    }

}

In struts.xml I have created 3 action using the next structure

struts.xml:

<action name="actionName1" method="methodName" class="Class1Action">
   <interceptor-ref name="validation">
      <param name="excludeMethods">methodName</param>
   </interceptor-ref>
   <result name="success" >success.jsp</result>
   <result name="input" >input.jsp</result>
</action>

Besides that I have a JSP with 3 buttons referring the different Struts actions, and several fields that represents fields from the model driven class used in the 3 action classes, and all of the fields inside a <s:push> tag.

The problem is when I am populating the fields and just after click on any of the buttons, data in the fields are missing.

I have tried to remove the 3 Struts lines that excludes the methods from validation, but instead of the fields are being empty, at the second time I have pressed the same button he returns an input and redirects to input.jsp.

The next code is from success.jsp, that is the starting page:

success.jsp:

<form method="post" >
    
    
    <s:push value="modelDrivenClass">

        <s:textfield label="FieldLabel1" name="modelDrivenClassAttribute1" />
        <s:textfield label="FieldLabel2" name="modelDrivenClassAttribute2" />
        <s:textfield label="FieldLabel3" name="modelDrivenClassAttribute3" />
        <s:textfield label="FieldLabel4" name="modelDrivenClassAttribute4" />
        <s:textfield label="FieldLabel5" name="modelDrivenClassAttribute5" />
            
    </s:push>
    
    
<s:submit action="actionName1" name="Submit1" value="Submit1" />
<s:submit action="actionName2" name="Submit2" value="Submit2" />
<s:submit action="actionName3" name="Submit3" value="Submit3" />
</form>

I don't know if is this the right way to do it, but I made it work when I used only one class implementing ModelDriven and this class has all the 3 methods.

I am just trying this way because I would like to let my code clear and don't have all methods in only one class.

1

There are 1 best solutions below

0
On

An approach with ModelDriven action class is very useful if you are migrating old Struts code to a new one, so it simplifies a concept of FormBean.

And in the newer Struts 2 isn't necessary to use ModelDriven if you can use the action bean from the top of the valueStack and model associated within just prefixed to its name.

Note: that when overriding interceptors configuration in the action config the defaultStack disappears. So, better to create your own stack or reference at least basicStack to make sure necessary interceptors are invoked. In your case a modelDriven interceptor.

If you use this interceptor on the stack it pushes the model in front of the action, so you don't need to s:push it in the result.

The model object should be initialized to the instance of he model class and returned by the getter of the model. Also consider using a visitor validator when validation fields of a model.

Having three actions that share a data between calls requires preparing a model using Preparable to populate fields from session or use a session object reference to provide default values for fields to keep them saved.

Note: using prepare requires changing the order of interceptors call to push the model before it's populated.