Struts2 JSON Plugin with Hibernate - json

So I'm trying to create a JSON object from a List of AcaClasses.
Action Class:
public class StudentJSONAction extends ActionSupport{
//Your result List
private List<AcaClass> gridModel;
public String getJSON() {
return execute();
}
public String execute() {
//Get the first student from the Factory and get their AcaClasses
gridModel = StudentFactory.getAll().get(0).getAcaClasses();
return SUCCESS;
}
//Getters and Setters
The StudentFactory is my interface to the hibernate database.
Struts.xml
<action name="getJSON" class="StudentJSONAction">
<result type="json">
<param name="enableSMD">true</param>
<param name="ignoreInterfaces">false</param>
</result>
</action>
When I call the getJSON action, all I get is:
{"methods":[],"objectName":null,"serviceType":"JSON-RPC","serviceUrl":"\/FlowridersSP\/getJSON","version":".1"}
This problem is very similar to mine but I would like to see if there is a solution using the Struts2 JSON Plugin
Question: Why am I not getting back a list of AcaClasses in JSON form?
My end goal is to plug in this JSON in the JQuery Grid Plugin

I am not familiar with JSON plugin, but are you correctly configuring the plugin to serialize the gridModel? A quick look at the plugin documentation suggests that you might want to set the root parameter also:
<action name="getJSON" class="StudentJSONAction">
<result type="json">
<param name="enableSMD">true</param>
<param name="ignoreInterfaces">false</param>
<param name="root">gridModel</param>
</result>
</action>
Also, try to identify if the problem is with StudentFactory or with the JSON serialization. You can set up gridModel with a list of dummy AcaClass objects and see if the serialization works correctly. Also, as suggested by #Quaternion, you can log the list of AcaClass objects loaded by StudentFactory and verify that it is loading the expected instances.

Related

Struts2 Only Use Specific Variable Object for JSON Result (not all Action variables)

Suppose my Struts mapping returns a JSON string,
<action name="retrieveJson" method="retrieveJson" class="myapp.WebServiceAction">
<result type="json">
<param name="contentType">text/plain</param>
</result>
</action>
My Action class has multiple variables that could be "construed" as the potential result.
public class WebServiceAction {
private List<PublicationRecord> publicationRecords; // getters+setters
private List<ReviewRecord> reviewRecords; // getters+setters
private List<CustomRecord> customRecords; // getters+setters
}
When I do the following, I set the particular variable that I want, but Struts2 seems to return all variables under the Action that are suitable:
public String retrieveJson() {
publicationRecords = service.getPublicationRecords();
return SUCCESS;
}
Is it wrong to return SUCCESS? I only want the JSON-ified variable that I set in this method. Right now, it's returning all 3 vars,
{
"publicationRecords" : ..,
"reviewRecords" : null,
"customRecords" : null
}
Expected:
{"publicationRecords" : .. }
For this you could use 2 properties.
excludeNullProperties or includeProperties for serializing only the desired fields. Also includeProperties allow the use of regular expressions in case you do not want to serialize the full object content.
<result type="json">
<param name="includeProperties">
^entries\[\d+\].clientNumber,
^entries\[\d+\].scheduleNumber,
^entries\[\d+\].createUserId
</param>
</result>
Here is the official documentation.

Getting json return type and html return in the same action

I'll try be as specific as possible.
I have an Action with two methods, one is called via ajax and other one via regular submit.
The point is that can't get the request from the regular submit, I'm getting only the action properties.
public class ClientAction{
#SMDMethod
public Map<String, Object> findClient(String myParam){
...
}
public String saveClient(){
Map<String, String[]> parameterMap = this.getRequest().getParameterMap();
}
}
getRequest from saveClient method returns null!!! But, why??? I didn't declare it with #SMDMethod
and here is the struts.xml
<action name="client" class="myCompany.ClientAction">
<interceptor-ref name="customJSON"><param name="enableSMD">true</param></interceptor-ref>
<result type="json"><param name="enableSMD">true</param></result>
</action>
I did all the others declarations. I used to have two separete classes, one for each method, but maintainability wasn't easy with ClientAction and ClientActionJSON.
Any thoughts on how to have both methods, one ajax and the other not, in the same class.
I'll straight away consider to write a sample :
<action name="xclient" class="myCompany.ClientAction" method="jsonMethod">
<result type="json"></result>
</action>
<action name="yclient" class="myCompany.ClientAction" method="htmlMethod">
<result type="dispatcher">/pages/y.jsp</result>
</action>
now simply create both methods jsonMethod() & htmlMethod() in your ClientAction, one handling json and another html response.
[EDIT]
I read it again and seems like you require only one-action, well then simply consider using a field (request parameter) to decide the return type.
public String execute(){
//..Other code
if(returntype.equals("json")){
return "jsonresult";
}
else{
return "htmlresult";
}
}
<action name="client" class="myCompany.ClientAction" method="jsonMethod">
<result name="jsonresult" type="json"></result>
<result name="htmlresult" type="dispatcher">/pages/y.jsp</result>
</action>
Above I assumed, returntype is a String variable which you sent along with each request specifying what return is expected. You can simply send it hidden in the form-submit and set it in the ajax-request.

struts 2 mapping return List/collection as json

I have simplfied my code to make it easiear to understand:
I have an action class
public class MyAction extends ActionSupport {
private BigClass item;
public String myMethod(){
//call some services
this.item = processedStuff;
return SUCCESS;
}
}
and BigClass has an Array in it:
public class BigClass{
private String data1;
private String data2;
private List<MyBean> dataArray=new ArrayList()<MyBean>;
//setters and getters ...
}
and the strut.xml mapping
<result name="success" type="json">
<param name="includeProperties">
item\.data1,
item\.data2,
item\.dataArray\[\d+\]\.id,
item\.dataArray\[\d+\]\.name
</param>
</result>
as json result, I'm only getting information data1, and data2, the array is not returning..
however if I change
item\.dataArray\[\d+\]\.id,
item\.dataArray\[\d+\]\.name
to
item\.dataArray.*,
I get all the information I need.
is it the expression item\.dataArray\[\d+\]\.id incorrect?
In the struts.xml adding the extra two lines item\.dataArray,
item\.dataArray\[\d+\], fixes the problem. I have also shown it below.
<result name="success" type="json">
<param name="includeProperties">
item\.data1,
item\.data2,
item\.dataArray,
item\.dataArray\[\d+\],
item\.dataArray\[\d+\]\.id,
item\.dataArray\[\d+\]\.name
</param>
</result>
Please see this answer, and this rejected Suggestion :(
And make sure your OGNL expression is correct, both grammatically and logically.
"item\.dataArray\[\d+\]\.id" is grammatically correct, which will get values such as item.dataArray[0].id, item.dataArray[1].id, item.dataArray[2].id and so on.

Transfer only a part of properties in a class in struts' json

Sorry, I really don't know how to summarize the title of this question. So, the title may not be clear.
I have an action class which performs some business logic.
in the Action Class:
class ActionClass extends ActionSupport{
private Merchandise merchandise;// I want to transfer it to the client
//setter and getter
}
in the Merchandise class:
class Merchandise{
private String name; // I want to transfer it
private String price; //I don't want to transfer it
private String description;//I don't want to transfer it
//setter and getter
}
Now, I need to transfer the merchandise property in ActionClass to the client.
However, in the merchandise property, I want to transfer only the name property while inhibiting the other two properties.
Then how to inhibit the transfer of the other two properties(price and description) in class Merchandise?
Try something like:
<!-- Result fragment -->
<result type="json">
<param name="root">merchandise</param>
<param name="excludeProperties">price,description</param>
</result>
See full documentation, other options and examples at http://struts.apache.org/2.2.3/docs/json-plugin.html
The easiest way is to create a Data Transfer Object in your action class that contains only the fields you want to send to the client and make that your root object
#nmc answer is correct another way you can try like:
<result type="json">
<param name="root">merchandise</param>
<param name="includeProperties">name</param>
</result>
Or
<result type="json">
<param name="includeProperties">
merchandise.name
</param>
<param name="root">
#action
</param>
</result>

JSON serialization (using Jquery plugin) w/ Struts2 interceptors -

I'm trying to implement http://code.google.com/p/struts2-jquery/wiki/SelectTag#A_simple_Doubleselect_with_Topics but I can't seem to combine the json interceptor with other interceptors successfully.
In my struts.xml:
<package name="admin" namespace="/admin" extends="struts-default,json-default">
<action name="LoadLists" method="loadLists" class="test.JSONAction">
<interceptor-ref name="json">
<param name="contentType">application/json</param>
<!--interceptor added to override this property below-->
<param name="excludeNullProperties">true</param>
</interceptor-ref>
<result name="success" type="json"/>
<interceptor-ref name="servletConfig"/>
</action>
</package>
Here's some of the action class code.
Note that I need the session variable and therefore have added the <interceptor-ref name="servletConfig"/> line above to set the session variable so that it can be used in the following Java code:
public String loadLists() {
items = (List<String>) session.get("itemsList");
if (itemSelected.equals...
// Do stuff to process the list and generate the second list...
}
public void setItemSelected(String itemSelected) {
this.itemSelected = itemSelected;
}
BUT when I have <interceptor-ref name="servletConfig"/>, error logs show:
org.apache.struts2.json.JSONInterceptor.debug:68 - Content type must be 'application/json' or 'application/json-rpc'. Ignoring request with content type application/x-www-form-urlencoded
and the variable itemSelected never gets set because the json serialization is ignored!
If I remove <interceptor-ref name="servletConfig"/> then I can't access the session!
What am I missing?
The problem here appears to be that you are not making an AJAX/JSON request to your action, you are posting to it using a standard form approach.
The message that you have provided is saying that the Content-Type request header was expected to be JSON-related, but instead was x-www-form-urlencoded. In other words, the request was not an AJAX/JSON request, but was just a normal form submit.
Double check how you are making the request to your JSONAction and make sure that you are actually sending the request properly.