8

I have the following code and I would to achieve functionality that /getJson will return user object as json and /getJson2 will return user2 as Json object.

@ParentPackage("json-default")
public class JsonAction extends ActionSupport{
private User user = new User("John","Smith"); 
private User user2 = new User("Smith","John"); 
public String populate(){

    return "populate";
}

@Action(value="/getJson", results = {
        @Result(name="success", type="json")})
public String test(){
    return "success";
}

@Action(value="/getJson2", results = {
        @Result(name="success", type="json")})
public String test2(){
    return "success";
}

@JSON(name="user")
public User getUser() {
    return user;
}

public void setUser(User user) {
    this.user = user;
}

@JSON(name="user2")
public User getUser2() {
    return user2;
}

public void setUser2(User user2) {
    this.user2 = user2;
}
}

Currently no matter which method I'm calling I'm still getting the following result:

{"user":{"firstName":"John","lastName":"Smith"},"user2":{"firstName":"Smith","lastName":"John"}}

Is it possible?

Update:

I modified the code:

public class JsonAction extends ActionSupport{
private User user = new User("John","Smith"); 
private User user2 = new User("Smith","John"); 
public String populate(){

    return "populate";
}

@Action(value="/getJson", results = {
        @Result(name="success", type="json",params = {
                "includeProperties",
                "user"})})
public String test(){
    return "success";
}

@Action(value="/getJson2", results = {
        @Result(name="success", type="json",params = {
                "includeProperties",
                "user2"})})
public String test2(){
    return "success";
}

@JSON(name="user")
public User getUser() {
    return user;
}

public void setUser(User user) {
    this.user = user;
}

@JSON(name="user2")
public User getUser2() {
    return user2;
}

public void setUser2(User user2) {
    this.user2 = user2;
}
}

Now I'm getting

{"user":{}}

and

{"user2":{}}
danny.lesnik
  • 18,479
  • 29
  • 135
  • 200
  • I can't see the issue. I would at this time remove the setters (I don't know if you have any spring magic that could cause weirdness), move the User creation into a prepare method and verify that the users are not null (see http://struts.apache.org/2.0.14/docs/prepare-interceptor.html) and this is just personal preference but @JSON(name="user") when applied to getUser is redundant so I would get rid of the @JSON annotations on the getters. – Quaternion Jan 11 '11 at 00:20

3 Answers3

8

Yes it is possible, the solution requires the use of include/exclude parameters.

Following is an example.

Methods getJson1 and getJson2 show includeParameters while getJson3 shows excludeParameters.

Note: Although the example uses strings as the arguments for include/exclude parameters the string is interpreted as a regular expression. So I could replace "string1, string2" on action3 with "string*".

For more information see: https://cwiki.apache.org/confluence/display/WW/JSON%20Plugin

package struts2;

import com.opensymphony.xwork2.ActionSupport;
import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.ParentPackage;
import org.apache.struts2.convention.annotation.Result;

@ParentPackage("json-default")
public class Test2 extends ActionSupport {

    private String string1 = "One";
    private String string2 = "Two";
    private String other = "Other";

    public String getString1() {
        return this.string1;
    }

    public String getString2() {
        return this.string2;
    }

    public String getOther() {
        return this.other;
    }

    @Action(value="/getJson1", results = {
        @Result(type = "json", params = {
            "includeProperties",
            "string1"
        })})
    public String action1() {
        return ActionSupport.SUCCESS;
    }

    @Action(value="/getJson2", results = {
        @Result(type = "json", params = {
            "includeProperties",
            "string2"
        })})
    public String action2() {
        return ActionSupport.SUCCESS;
    }

    @Action(value="/getJson3", results = {
        @Result(type = "json", params = {
            "excludeProperties",
            "string1, string2"
        })})
    public String action3() {
        return ActionSupport.SUCCESS;
    }
}

.../getJson1 returns {"string1":"One"}

.../getJson2 returns {"string2":"Two"}

.../getJson3 returns {"other":"Other"}

Quaternion
  • 10,380
  • 6
  • 51
  • 102
  • Hi, I modified code according to your example but, now I'm getting empty JSON string, please see update. Thank you in advance. – danny.lesnik Jan 10 '11 at 23:37
4

You must include all properties that you want to serialize. This includes the properties of the User class like this, for example:

@Action(value="/getJson", results = {
        @Result(name="success", type="json",params = {
                "includeProperties",
                "user\.firstName, user\.lastName"})})

But, another form to get this work could be using regular expressions:

@Action(value="/getJson", results = {
        @Result(name="success", type="json",params = {
                "includeProperties",
                "user\..*"})})

Regards.

CHiRo79
  • 700
  • 1
  • 5
  • 17
2

This action provides two properties: user and user2.

If both /getJson and /getJson2 map to this action class, then they will both respond with the available properties: user and user2.

James Young
  • 1,372
  • 13
  • 16