4

I search for this case but couldn't find a solution.

I would like to return List or JSON Object (for this List) from the same action class based on user request. I am trying to configure based on my return name but not able to do it.

Eg; if isJSON value is set to 1 by user, I convert the List to JSON object.

I can reach my List on JSP but not JSON Object.

I tried to set my result type to 'json' for related result name and implemented necessary interceptor. In this case, I couldn't get any data from user.

I don't want to add code because I tried so many different ways and it will be mass to show all. I can show upon request. I am looking forward to your advise.

Thanks

likeachamp
  • 765
  • 4
  • 11
  • 21

1 Answers1

4

Two actions, one result each one

You can simply use two actions, mapped to the same action class, pointing to different methods, returning different results (one JSP, one JSON, in this case):

<package name="foobar" namespace="/" extends="json-default">    

    <action name="jspList" class="foo.bar.MyAction">
        <result>myList.jsp</result>
    </action>

    <action name="jsonList" class="foo.bar.MyAction" method="jsonExecute">
        <result type="json">
            <param name="root">myList</param>
        </result>
    </action>

</package>

Note: method="execute" in actions and name="success" in results are omitted due to Intelligent Default.

In myList.jsp read with Struts tags the myList action attribute and use it for what you want (populate a Select tag, a table, or whatever...). Or use a Stream result instead of a standard Dispatcher.

In the Action class:

public class MyAction extends ActionSupport {

    private List<Object> myList;          // Getter 

    public String execute(){
        doBusiness();
        return SUCCESS;
    }
    
    public String jsonExecute(){
        doBusiness();
        return SUCCESS;
    }
    
    private void doBusiness(){
        myList = // load the list here
    }    

}

One action, two results

Of course, instead of two actions each one with one result, you can use a single action with two results, picking up the right one to return basing on a parameter (like you was trying to do, appearently)...:

<package name="foobar" namespace="/" extends="json-default">
    <action name="list" class="foo.bar.MyAction">
        <!-- success -->
        <result>myList.jsp</result> 
        <!-- json -->
        <result name="json" type="json">
            <param name="root">myList</param>
        </result>
    </action>
</package>

In the action, perform the check on the parameter:

public class MyAction extends ActionSupport {

    private int isJSON;                  // Setter
    private List<Object> myList;         // Getter

    public String execute(){
        myList = // load the list here

        if (isJSON==1) {
            return "json"; // mapped to a JSON result
        }
        return SUCCESS; // mapped to a dispatcher result
    }
            
}

Content-Negotiation

Another way is to do a real Content-Negotiation based on HTTP headers, returning a result in the format the browser is claiming to accept:

public class MyAction extends ActionSupport implements ServletRequestAware {

    private HttpServletRequest request;  // Setter
    private List<Object> myList;         // Getter

    public String execute(){
        myList = // load the list here

        String acceptHeader = request.getHeader("Accept");
        if (acceptHeader != null && acceptHeader.equals("application/json"){
            return "json"; // mapped to a JSON result
        } 
        return SUCCESS; // mapped to a dispatcher result
    }
            
}

Also read how the JSON plugin works with the root object.

Community
  • 1
  • 1
Andrea Ligios
  • 49,480
  • 26
  • 114
  • 243
  • Actually, I am looking for the second solution. (Starting with 'Of course' :) But I couldn't make it. Can you give an example for that case please ? – likeachamp Mar 10 '15 at 15:58
  • I've added it, even though it seemed naive after the answer. Two actions way is cleaner IMHO, but is opinion based... – Andrea Ligios Mar 10 '15 at 16:10
  • 1
    Thank you Andrea! It works like a champ! Your help is greatly appreciated. My problem was; I was trying to configure my action inside "struts-default" and try to define result-type, interceptor etc to identify json. – likeachamp Mar 10 '15 at 17:18