The modeldriven mechanism in STRUTS2 and its application (turn)

Source: Internet
Author: User

The so-called Modeldriven, meaning is directly the entity class as the collection object of the page data. For example, there is an entity class user as follows:

Package cn.com.leadfar.struts2.actions;

Public class User {

Private int ID;

Private String username;

Private String password;

Private int age;

Private String address;

Public String GetUserName () {

return username;

}

Public void setusername (String username) {

this. Username = Username;

}

Public String GetPassword () {

return password;

}

Public void SetPassword (String password) {

this. Password = password;

}

Public int getage () {

return age;

}

Public void setage (int age) {

this. Age = age;

}

Public String getaddress () {

return address;

}

Public void setaddress (String address) {

this. Address = address;

}

Public int getId () {

return ID;

}

Public void setId (int id) {

this. id = ID;

}

}

If you want to write an action, use it to add user.

The first approach is to define all the required properties directly in the action, and then submit the data directly in the JSP using the property name:

Useraction:

Public class useraction {

Private int ID;

Private String username;

Private String password;

Private int age;

Private String address;

Public String Add () {

User user = new user ();

User.setid (ID);

User.setusername (username);

User.setpassword (password);

User.setage (age);

User.setaddress (address);

New Usermanager (). AddUser (user);

return "Success";

}

Public int getId () {

return ID;

}

Public void setId (int id) {

this. id = ID;

}

Public String GetUserName () {

return username;

}

Public void setusername (String username) {

this. Username = Username;

}

Public String GetPassword () {

return password;

}

Public void SetPassword (String password) {

this. Password = password;

}

Public int getage () {

return age;

}

Public void setage (int age) {

this. Age = age;

}

Public String getaddress () {

return address;

}

Public void setaddress (String address) {

this. Address = address;

}

}

ADD_INPUT.JSP:

<form action= "Test/user.action" method= "POST" >

<input type= "hidden" name= "Method:add" >

Username:<input type= "text" name= "username" > <br/>

Password:<input type= "text" name= "password" > <br/>

Age:<input type= "text" name= "age" > <br/>

Address:<input type= "text" name= "Address" > <br/>

<input type= "Submit" name= "Submit" value= "Add User" >

</form> <br/>

The downside of this approach is that if the attributes of an entity class are very numerous, the same properties are defined in the action.

The second approach is to define the user object to Useraction and then assign a value to the user through the user property in the JSP:

Useraction:

public class useraction {

    

    private user user;

   

    Public String Add () {

 

        New Usermanager (). AddUser (user);

      

       return "success";

   }

 

    Public User GetUser () {

       return user;

   }

 

    public void setUser (user user) {

        this . user = user;

   }

   

   

}

ADD_INPUT.JSP:

<form action= "Test/user.action" method= "POST" >

<input type= "hidden" name= "Method:add" >

Username:<input type= "text" name= "User.username" > <br/>

Password:<input type= "text" name= "User.password" > <br/>

Age:<input type= "text" name= "User.age" > <br/>

Address:<input type= "text" name= "user.address" > <br/>

<input type= "Submit" name= "Submit" value= "Add User" >

</form> <br/>

The downside is that the name in the form field on the JSP page becomes too long

The third approach is to use the Modeldriven mechanism to allow useraction to implement a Modeldriven interface while implementing the method in the interface: Getmodel (). As shown below:

Public class Useraction implements modeldriven{

Private User user;

@Override

Public Object Getmodel () {

if (user = = null) {

user = new user ();

}

return user;

}

Public String Add () {

New Usermanager (). AddUser (user);

return "Success";

}

Public User GetUser () {

return user;

}

Public void setUser (user user) {

this. user = user;

}

}

The code for the JSP is as follows:

<form action= "Test/user.action" method= "POST" >

<input type= "hidden" name= "Method:add" >

Username:<input type= "text" name= "username" > <br/>

Password:<input type= "text" name= "password" > <br/>

Age:<input type= "text" name= "age" > <br/>

<input type= "Submit" name= "Submit" value= "Add User" >

</form> <br/>

As can be seen, the third approach is better, and the action and JSP are relatively simple to write.

The mechanism behind Modeldriven?

The mechanism behind Modeldriven is valuestack. Interface through: username/age/address such a name, it can be directly assigned to the user object, which proves that the user object is a root object in Valuestack!

So why is the user object in Valuestack? When did it get pressed into the valuestack? The answer is: modeldriveninterceptor (for the concept of interceptor, please refer to the following section for instructions). Modeldriveninterceptor is part of the default interceptor chain, and when a request is modeldriveninterceptor, in this interceptor, Determines whether the currently invoked action object implements the Modeldriven interface, and if this interface is implemented, calls the Getmodel () method and presses the return value (this example returns the user object) into the Valuestack.

Take a look at the Modeldriveninterceptor code:

Public class Modeldriveninterceptor extends abstractinterceptor {

protected boolean Refreshmodelbeforeresult = false;

Public void Setrefreshmodelbeforeresult (boolean val) {

this. Refreshmodelbeforeresult = val;

}

@Override

Public String Intercept (actioninvocation invocation) throws Exception {

Object action = Invocation.getaction ();

if (Action instanceof Modeldriven) {

Modeldriven Modeldriven = (modeldriven) action;

Valuestack stack = Invocation.getstack ();

Object model = Modeldriven.getmodel ();

if (model = null) {

Stack.push (model);

}

if (Refreshmodelbeforeresult) {

Invocation.addpreresultlistener (new Refreshmodelbeforeresult (Modeldriven, model));

}

}

return Invocation.invoke ();

}

From Modeldriveninterceptor, you can see that the model object is pressed into the valuestack!

The Refreshmodelbeforeresult is a solution to the problem described next.

understand common pitfalls and how to solve them

Suppose we want to update an entity object, the first step is to open the update interface, see the following simulation to open the update interface code:

Public class Useraction implements modeldriven{

Private User user;

@Override

Public Object Getmodel () {

if (user = = null) {

user = new user ();

User.setusername ("This is the original user object");

}

return user;

}

Public String Updateinput () {

Query the database based on the ID, get the User object

user = new Usermanager (). Finduserbyid (User.getid ());

return "Update_input";

}

In the code above, new Usermanager (). Finduserbyid (User.getid ()); This line will query the corresponding record from the database while converting it back to the user object. and return "Update_input"; will turn to update the display page.

The update page is as follows:

<form action= "Test/user.action" method= "POST" >

<input type= "hidden" name= "Method:update" >

Id:<input type= "text" name= "id" value= "<s:property value=" id "/>" > <br/>

Username:<input type= "text" name= "username" value= "<s:property value=" username "/>" > <br/>

Password:<input type= "text" name= "password" value= "<s:property value=" password "/>" > <br/>

Age:<input type= "text" name= "Age" value= "<s:property value=" age "/>" > <br/>

Address:<input type= "text" name= "Address" value= "<s:property value=" Address "/>" > <br/>

<input type= "Submit" name= "Submit" value= "Update User" >

</form> <br/>

After you run the code above, you will not see the data on the update interface (the ID attribute has values and other properties are not shown). The key reason is that before executing to Updateinput, the user object (the object created in the GetMode () method) is pressed into Valuestack, when both Useraction and Valuestack point to the same user object; The user in Useraction is overwritten by a new user object, when Useraction and Valuestack no longer point to the same user Object! Valuestack is the old user object, and Useraction is the new user Object! We have direct access to the JSP, directly through username/address, of course, to access the old user objects in Valuestack, so their properties are empty (except for the id attribute)!

Understanding the above questions is important, and when you understand the problem, there are many ways to solve the problem:

For example, you can copy the properties of the new object to the old object, for example, you can remove the old object from the Valuestack, then press the new object into the Valuestack, etc...

In the latest version of STRUTS2, Modeldriveninterceptor provides a configuration parameter: Refreshmodelbeforeresult, as long as it is defined as true, the above problem is resolved! The solution for STRUTS2 is to remove the old model object from the Valuestack before pressing the new model object into the valuestack!

The modeldriven mechanism in STRUTS2 and its application (turn)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.