I'm facing an issue with CXF and JSON marshalling. My GET request for an
object returns the following JSON.

{
   "d.definition":{
      "@filename":"credit-line-increase-data",
      "@repeating":"false",
      "@index":"0",
      "@name":"Credit Line Increase Data",
      "d.structure":{
         "@repeating":"false",
         "@index":"0",
         "@name":"CreditLineIncConversation",
         "d.symbolic":[
            {
               "@index":"0",
               "@name":"ReasonForIncrease"
            },
            {
               "@index":"4",
               "@name":"TermsConds"
            }
         ],
         "d.numeric":[
            {
               "@index":"1",
               "@name":"AmountAppliedFor"
            },
            {
               "@index":"2",
               "@name":"AmountOffered"
            }
         ],
         "d.boolean":[
            {
               "@index":"3",
               "@name":"CustApprovesCreditCheck"
            },
            {
               "@index":"5",
               "@name":"CustAgreesToTermsConds"
            }
         ],
         "d.structure":{
            "@repeating":"false",
            "@index":"6",
            "@name":"CreditCheck",
            "d.symbolic":{
               "@index":"0",
               "@name":"DateOfCreditCheck"
            },
            "d.structure":{
               "@repeating":"true",
               "@index":"1",
               "@name":"CreditLines",
               "d.symbolic":{
                  "@index":"0",
                  "@name":"LineType"
               },
               "d.numeric":[
                  {
                     "@index":"1",
                     "@name":"Amount"
                  },
                  {
                     "@index":"2",
                     "@name":"DaysPastDue"
                  }
               ]
            }
         }
      }
   }
}

The POST request sends something very similar back (ordering of elements
shouldn't matter hopefully). 

{
   "d.definition":{
      "@repeating":"false",
      "@filename":"credit-line-increase-data",
      "@index":"0",
      "@name":"Credit Line Increase Data",
      "d.structure":{
         "@repeating":"false",
         "@index":"0",
         "@name":"CreditLineIncConversation",
         "d.symbolic":[
            {
               "@index":"0",
               "@name":"ReasonForIncrease"
            },
            {
               "@index":"4",
               "@name":"TermsConds"
            }
         ],
         "d.numeric":[
            {
               "@index":"1",
               "@name":"AmountAppliedFor"
            },
            {
               "@index":"2",
               "@name":"AmountOffered"
            }
         ],
         "d.boolean":[
            {
               "@index":"3",
               "@name":"CustApprovesCreditCheck",
               "type":"BOOLEAN"
            },
            {
               "@index":"5",
               "@name":"CustAgreesToTermsConds",
               "type":"BOOLEAN"
            }
         ],
         "d.structure":{
            "@repeating":"false",
            "@index":"6",
            "@name":"CreditCheck",
            "d.symbolic":{
               "@index":"0",
               "@name":"DateOfCreditCheck"
            },
            "d.structure":{
               "@repeating":"true",
               "@index":"1",
               "@name":"CreditLines",
               "d.symbolic":{
                  "@index":"0",
                  "@name":"LineType"
               },
               "d.numeric":[
                  {
                     "@index":"1",
                     "@name":"Amount"
                  },
                  {
                     "@index":"2",
                     "@name":"DaysPastDue"
                  }
               ]
            }
         }
      },
      "d.structure":{
         "d.symbolic":[
            {
               "@index":"0",
               "@name":"ReasonForIncrease"
            },
            {
               "@index":"4",
               "@name":"TermsConds"
            }
         ],
         "@repeating":"false",
         "@index":"0",
         "@name":"CreditLineIncConversation",
         "d.boolean":[
            {
               "@index":"3",
               "@name":"CustApprovesCreditCheck",
               "type":"BOOLEAN"
            },
            {
               "@index":"5",
               "@name":"CustAgreesToTermsConds",
               "type":"BOOLEAN"
            }
         ],
         "d.numeric":[
            {
               "@index":"1",
               "@name":"AmountAppliedFor"
            },
            {
               "@index":"2",
               "@name":"AmountOffered"
            }
         ],
         "d.structure":{
            "@repeating":"false",
            "@index":"6",
            "@name":"CreditCheck",
            "d.symbolic":{
               "@index":"0",
               "@name":"DateOfCreditCheck"
            },
            "d.structure":{
               "@repeating":"true",
               "@index":"1",
               "@name":"CreditLines",
               "d.symbolic":{
                  "@index":"0",
                  "@name":"LineType"
               },
               "d.numeric":[
                  {
                     "@index":"1",
                     "@name":"Amount"
                  },
                  {
                     "@index":"2",
                     "@name":"DaysPastDue"
                  }
               ]
            }
         }
      }
   }
}

The bug that I'm currently seeing is that the "symbolic", "boolean" and
"numeric" arrays in the "CreditLineIncConversation" aren't getting converted
from JSON to Java properly. In fact, they're completely dropped. Here's the
resulting JSON after the save has been made:

{
   "d.definition":{
      "@filename":"credit-line-increase-data",
      "@repeating":"false",
      "@index":"0",
      "@name":"Credit Line Increase Data",
      "d.structure":{
         "@repeating":"false",
         "@index":"0",
         "@name":"CreditLineIncConversation",
         "d.structure":{
            "@repeating":"false",
            "@index":"6",
            "@name":"CreditCheck",
            "d.symbolic":{
               "@index":"0",
               "@name":"DateOfCreditCheck"
            },
            "d.structure":{
               "@repeating":"true",
               "@index":"1",
               "@name":"CreditLines",
               "d.symbolic":{
                  "@index":"0",
                  "@name":"LineType"
               }
            }
         }
      }
   }
}

I tried looking at CXF's JAX-RS Documentation (specifically the json array
serialization issues section) and making the following change in my
configuration.

@@ -45,8 +45,17 @@
     <bean id="jsonProvider"
class="org.apache.cxf.jaxrs.provider.JSONProvider">
         <property name="namespaceMap" ref="jsonNamespaceMap"/>
         <property name="serializeAsArray" value="true"/>
+           <property name="arrayKeys" ref="jsonKeys"/>     
     </bean>
 
+       <util:list id="jsonKeys">
+         <value>structure</value>
+         <value>numeric</value>
+         <value>symbolic</value>
+         <value>date</value>
+         <value>boolean</value>
+       </util:list>
+

Unfortunately, this didn't work. 

The class that I'm trying to populate is defined as:

@XmlRootElement(name = "definition")
public class DataDefinition extends Structure {

}

It's parent (Structure), looks as follows:

public class Structure extends Field {
                
        @XmlAttribute(required = false)
        boolean repeating = false;
        
        public boolean isRepeating() {
                return repeating;
        }

        @XmlElements( { @XmlElement(name = "structure", type = Structure.class),
                @XmlElement(name = "numeric", type = NumericField.class),
                @XmlElement(name = "symbolic", type = SymbolicField.class),
                @XmlElement(name = "date", type = DateField.class),
                @XmlElement(name = "boolean", type = BooleanField.class) })
        private List<Field> fields;

        public List<Field> getFields() {
                return fields;
        }
        
        public void setFields(List<Field> fields) {
                this.fields = fields;
        }
        
        public Map<String, Field> getFieldsAsMap() {
                Map<String, Field> fieldMap = new HashMap<String, Field>();
                for (Field field : getFields()) {
                        fieldMap.put(field.getName(), field);
                }
                return fieldMap;
        }
}

I'd appreciate any pointers on what I need to do to make this work.

Thanks!

Matt
-- 
View this message in context: 
http://www.nabble.com/Issues-marshalling-a-JSON-String-to-Java-Objects-%28works-fine-from-Java-to-JSON%29-tp25531242p25531242.html
Sent from the cxf-user mailing list archive at Nabble.com.

Reply via email to