Steve Lu
Steve Lu

Reputation: 111

How to use jQuery to post JSON data to a Struts2 Action class

I've a problem sending data from jQuery to struts2 action class. I have seen the question: JSON Jquery to Struts2 action but I don't understand the solution quite well.

Here is my problem:

The json array is like this:

[{"id":"1","code":"111","name":"ddd"},
 {"id":"2","code":"222","name":"sss"},
 {"id":"3","code":"333","name":"eee"}]

I want to send the json data to the struts2 action class. The jQuery code is like this:

var data = JSON.stringify(dataObj);
$.ajax({
  url: "Update",
  type: "post",
  data:  data,
  dataType: 'json',
  contentType:"application/json;charset=utf-8",
  success : function(){
    alert("You made it!");
  }
});

However, in Chrome's Development Tool, I have seen the data submitted to the server side. But on the server side, I don't know how receive the json data.

Action:

public class Update extends ActionSupport{
    private String data;

    public String getData(){
        return data;
    }

    public void setData(String data){
        this.data= data;
    }

    public String execute(){
        System.out.println(data);
        return SUCCESS;
    }
}

In this way, data is null.

I've also tried to use a List to receive JSON data. Changing "data" type from String to List<Node>, it failed again. Probably because I don't quite understand the OGNL model which Struts2 is using.

Please Help Me. Thank you very much!

Upvotes: 7

Views: 17389

Answers (3)

user23335865
user23335865

Reputation: 1

To whom are struggling to this question, I just did several steps:

Step 1. add dependency(maven)

  • make sure the version of this dependency matches the struts version
<dependency>
    <groupId>org.apache.struts</groupId>
    <artifactId>struts2-json-plugin</artifactId>
    <version>2.5.22</version>
</dependency>

Step 2. modify struts.xml

  • add json-default in your <package> label
  • add <interceptor-ref name="json" /> to my custom <interceptor-stack>, then it shoud be like the following:
<struts>
    <package name="your-custom-package-name" extends="struts-default json-default">
        <interceptors>
            <interceptor-stack name="your-custom-interceptor-stack">
                ...
                <interceptor-ref name="json" />
            </interceptor-stack>
        </interceptors>

        <default-interceptor-ref name="your-custom-interceptor-stack"/>
    </package>

Step 3. Modify Action class

  • add @ParentPackage("your-custom-package-name") to your Action class
  • create a javaBean to match the format of the transferring data
  • remember the getter/setter of your javaBean
  • Make sure that your javaBean should implement Serializable
@ParentPackage("your-custom-package-name")
public class XXXAction extends ActionSupport implements SessionAware 
{
    CustomJavaBean po;
    ...
    
    @Action(value="test")
    public void test()
    {
        System.out.println(po != null);
    }

    public void setPo(CustomJavaBean po){
        this.po = po;
    }
    public CustomJavaBean getPo(){
        return this.po;
    }
}

Step 4. follow the jQuery/ajax rule

  • Be sure to add extra layer on your raw data like {"your-javaBean-name": data} and transform it to the string by JSON.stringify()
  • Here is my template if you need it:
let obj = {
    'addr': 'AAA',
    'postcode': 'AAA',
    'mail': 'AAA',
};
let data = {'po': obj};
data = JSON.stringify(data);
    
$.ajax({
    type: "post",
    url: "test.action",
    data: data,
    contentType:"application/json",
    success: function() {
        console.log("success");
    },
    error: function() {
        console.log("error");
    }
});

Still, if you meet the exception like it's not well formed JSON (invalid char d) then try to rename the javaBean in your Action class. For example, I encounter this problem that I put CustomJavaBean data in my Action class. It's solved after I changed to CustomJavaBean po.

By the way, who else uses struts these days, it sucks :P

Upvotes: 0

Rajeshkumar
Rajeshkumar

Reputation: 895

Hey The problem is you are directly posting array of objects. So Struts2 don't know whicch method to call. Change your json data like below. Then it will work.

{"data":[{"id":"1","code":"111","name":"ddd"},
"id":"2","code":"222","name":"sss"},
{"id":"3","code":"333","name":"eee"}]}

Then inside the setter read with object

public void setData(List < Report > data) {
    System.out.println("Setter Call Flow");
    this.data = data;
}

Where Report is a java class contains id,code,name as it's members with setters and getters.

Upvotes: 1

coding_idiot
coding_idiot

Reputation: 13734

{"id":"1","code":"111","name":"ddd"}

Step 1 : Create a bean/pojo to accumulate/encapsulate the above fields

class MyBean{
    String id,code,name;
    //getters & setters
}

Step 2 : Change your action code to receive a List of MyBeans

public class Update extends ActionSupport{
    private List<MyBean> data;

   //other code, getters & setters
}

Step 3: Configure your action to de-serialize JSON data and fill the action fields (using json-plugin)

    <action name="Update" class="Update">
        <interceptor-ref name="defaultStack"/>
         <interceptor-ref name="json">
            <param name="enableSMD">true</param>
        </interceptor-ref>
</action>

Step 4 : Make necessary changes in the ajax request body being sent to match the action-params/fields

var data = JSON.stringify(dataObj);
$.ajax({
  url: "Update",
  type: "post",
  data:  "data:"+data,
  dataType: 'json',
  contentType:"application/json;charset=utf-8",
  success : function(){
    alert("You made it!");
  }
});

The above code is untested.

Upvotes: 9

Related Questions