Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to bind JSON to Java object in Struts2 using struts2-json-plugin

I want to deserialize (bind) JSON to java object. How to do it in Struts2?

I am trying to do it with struts2-json-plugin as you can see in code below, but sent JSON from frontend is not binding to my java object. Could you help me, please how to make this code to work correctly?

Please take a look at my Action class, I am not sure if I'm handling JSON correctly in this Action, or maybe I missed something?

JSON which I am trying to bind:

{"data":[
    {"active":true,"color":"orange","date":"2008-01-01","id":1,"name":"Chris"},
    {"active":false,"color":"blue","date":"2013-03-03","id":2,"name":"Kate"},
    {"active":true,"color":"black","date":"2013-05-03","id":3,"name":"Blade"},
    {"active":false,"color":"yellow","date":"2013-01-01","id":4,"name":"Zack"}]
}

Sending JSON by Ajax:

$.ajax({
  url: "../json/saveJSONDataAction.action",
  data: {"data": handsontable.getData()}, //returns all cells' data
  dataType: 'json',
  type: 'POST',
  success: function (res) {
    if (res.result === 'ok') {
      $console.text('Data saved');
    }
  }
});

Receiving JSON in Struts2:

I can reach execute() method in debug, but unfortunately, the data field is always null. What should I do to make this field filled with data from JSON? Is the JSON in correct format to bind to List<Report> data?

@ParentPackage("json-default")
@Action(value="saveJSONDataAction")
@Result(type="json")
public class JSONSaveAction extends ActionSupport {
    private static final long serialVersionUID = 1L;

    private List<Report> data;

    public JSONSaveAction(){
    }

    public String execute() {
        try {
            System.out.println(data);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return NONE;
    }

    public List<Report> getData() {
        return data;
    }

    public void setData(List<Report> data) {
        this.data = data;
    }
}

Report class:

public class Report {
    private int id;
    private String name;
    private boolean active;
    private String date;
    private String color;

    //getters and setters
}

struts.xml:

As you can see here I've added <interceptor-ref name="json"> with <param name="enableSMD">true</param>. Whole config below:

<struts>
<constant name="struts.action.extension" value="action,pdf" />
<constant name="struts.i18n.reload" value="true" />
<constant name="struts.configuration.xml.reload" value="true" />
<constant name="struts.custom.i18n.resources" value="i18n/ap,application" />
<constant name="struts.date.format" value="yyyy-MM-dd" />
<constant name="struts.serve.static" value="true" />
<constant name="struts.serve.static.browserCache" value="false" />

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

    <result-types>
       <result-type name="rethrowException" class="com.myhome.commons.util.ExceptionRethrowResult" />
       <result-type name="poi-excel" class="com.myhome.commons.util.PoiExcelResult"/>
    </result-types>

    <interceptors>
        <interceptor name="businessException" class="com.myhome.commons.exception.BusinessExceptionInterceptor"></interceptor>
        <interceptor-stack name="defaultStack">
            <interceptor-ref name="exception" />
            <interceptor-ref name="alias" />
            <interceptor-ref name="servletConfig" />
            <interceptor-ref name="i18n" />
            <interceptor-ref name="chain" />

            <interceptor-ref name="scopedModelDriven" />
            <interceptor-ref name="modelDriven" />
            <interceptor-ref name="fileUpload">
                <param name="maximumSize">10485760</param>
            </interceptor-ref>
            <interceptor-ref name="checkbox" />
            <interceptor-ref name="staticParams" />
            <interceptor-ref name="params">
                <param name="excludeParams">dojo\..*</param>
            </interceptor-ref>
            <interceptor-ref name="json">
                <param name="enableSMD">true</param>
            </interceptor-ref>
            <interceptor-ref name="prepare" />
            <interceptor-ref name="conversionError" />
            <interceptor-ref name="businessException" />
            <interceptor-ref name="validation">
                <param name="includeMethods">save,search</param>
            </interceptor-ref>
            <interceptor-ref name="workflow">
                <param name="includeMethods">save,search</param>
            </interceptor-ref>
            <interceptor-ref name="tokenSession">
                <param name="includeMethods">save</param>
            </interceptor-ref>
        </interceptor-stack>

    </interceptors>
    <default-interceptor-ref name="defaultStack"/>

    <global-results>
        <result name="exception" type="chain">
            <param name="actionName">exception</param>
            <param name="namespace">/</param>
        </result>
        <result name="rethrowException">/applicationAccessDeniedPage.jsp</result>       
        <result name="applicationAccessDenied">/applicationAccessDeniedPage.jsp</result>
        <result name="unavailableResource">/unavailableResource.jsp</result>        
        <result name="pessimisticLock">/pessimisticLock.jsp</result>        
        <result name="goto-crud" type="redirect">/crud/index.action</result>
        <result name="goto-dict" type="redirect">/dictionaries/index.action</result>
        <result name="reportXls" type="poi-excel">
            <param name="contentDisposition">attachment; filename="${resultFileName}"</param>
            <param name="excelWorkbook">workbook</param>
        </result>

    </global-results>
    <global-exception-mappings>
        <exception-mapping exception="com.myhome.ap.service.exception.AuthorizationFailedException" result="rethrowException"/>
        <exception-mapping exception="com.myhome.ap.service.exception.ApplicationAccessDeniedException" result="applicationAccessDenied"/>
        <exception-mapping exception="org.hibernate.ObjectNotFoundException" result="unavailableResource" />
        <exception-mapping exception="com.myhome.ap.service.exception.model.EntityHasBeenDeletedException" result="unavailableResource" />
        <exception-mapping exception="com.myhome.ap.service.exception.PessimisticLockingException" result="pessimisticLock" />
        <exception-mapping exception="java.lang.Exception" result="exception"/>
     </global-exception-mappings>

    <action name="version" class="com.myhome.ap.web.action.VersionAction" />

</package>
</struts>

What am I doing wrong? Can you suggest me some good examples/tutorial how to do deserialization from JSON to Java in Struts2, because I cannot find even one correct full example with JSON deserialization in Struts2, specially example of Action code which will receive the JSON and bind it to Java.

I am new in Struts at all, so that's why I have problems to understand some issues and flow, for example how to receive and handle JSON in Action. There are examples for serialization with struts2-json-plugin, but with this subject I had no trouble. Please help me...

like image 257
Roman Avatar asked May 22 '13 17:05

Roman


1 Answers

I figured it out. There was missing:

contentType: 'application/json',

in my Ajax request.

like image 153
Roman Avatar answered Oct 12 '22 18:10

Roman