Hi

I'm having problems with reproducing this issue. I thought I'd do a quick
test this evening but I proved to be wrong :-)
First I had to modify a bit the classes for a basic test to even start
working, to bypass JAXB complaints.
So here's what I have now.
testIt() results in

{"ns1.definition": {"@repeating":"false","@index":"0","@name":"Credit Line
Increase Data",
   
"ns1.structure":{"@repeating":"false","@index":"2","@name":"CreditLineIncConversation",
         "ns1.symbolic":[
              {"@index":"0","@name":"ReasonForIncrease"},
              {"@index":"4","@name":"TermConds"}
         ]
    }
  }
}

which is a simpler but a similar structure instance. 

@Test
    public void testIt() throws Exception {
        JSONProvider p = new JSONProvider();
        //p.setSerializeAsArray(true);
        //p.setArrayKeys(Collections.singletonList("structure"));
        
        DataDefinition dd = new DataDefinition();
        dd.setName("Credit Line Increase Data");
        List<Field> fields = new ArrayList<Field>();
        Structure s = new Structure();
        s.setIndex(2);
        s.setName("CreditLineIncConversation");
        List<Field> fields2 = new ArrayList<Field>();
        SymbolicField sf1 = new SymbolicField();
        sf1.setIndex(0);
        fields2.add(sf1);
        sf1.setName("ReasonForIncrease");
        SymbolicField sf2 = new SymbolicField();
        sf2.setIndex(4);
        sf2.setName("TermConds");
        fields2.add(sf2);
        s.setFields(fields2);
        fields.add(s);
        
        dd.setFields(fields);
        
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        
        p.writeTo(dd, (Class)DataDefinition.class, DataDefinition.class,
DataDefinition.class.getAnnotations(), 
                  MediaType.APPLICATION_JSON_TYPE, new MetadataMap<String,
Object>(), os);
        
        String str = os.toString();
        System.out.println(str);
    }


readIt() tries to read this data :

    @Test
    public void readIt() throws Exception {
        String s =
"{\"ns1.definition\":{\"@repeating\":\"false\",\"@index\":\"0\",\"@name\":"
            + "\"Credit Line Increase
Data\",\"ns1.structure\":{\"@repeating\":\"false\",\"@index\":\"2\","
            +
"\"@name\":\"CreditLineIncConversation\",\"ns1.symbolic\":[{\"@index\":\"0\",\"@name\":"
            +
"\"ReasonForIncrease\"},{\"@index\":\"4\",\"@name\":\"TermConds\"}]}}}";
        
        JSONProvider p = new JSONProvider();
        Map<String, String> namespaceMap = new HashMap<String, String>();
        namespaceMap.put("http://bla";, "ns1");
        p.setNamespaceMap(namespaceMap);
        byte[] bytes = s.getBytes();
        Object object = p.readFrom((Class)DataDefinition.class,
DataDefinition.class, 
                                   DataDefinition.class.getAnnotations(), 
                                          null, null, new
ByteArrayInputStream(bytes));
        DataDefinition dd = (DataDefinition)object;
        Field struct = dd.getFieldsAsMap().get("CreditLineIncConversation");
     }

     but gets a ClassCastException at 
     DataDefinition dd = (DataDefinition)object;

     because it is a Structure object.

     and here're the slightly updated classes :    


    @XmlRootElement(name = "definition", namespace = "http://bla";)
    public static class DataDefinition extends Structure {

    }

    @XmlRootElement(name = "definition", namespace = "http://bla";)
    @XmlSeeAlso({DataDefinition.class, SymbolicField.class})
    
    public static class Structure extends Field {
                   
            @XmlAttribute(required = false)
            boolean repeating = false;
           
            public boolean isRepeating() {
                    return repeating;
            }

            @XmlElements( { @XmlElement(name = "structure",
namespace="http://bla";, type = Structure.class),
                    @XmlElement(name = "numeric", namespace="http://bla";,
type = NumericField.class),
                    @XmlElement(name = "symbolic", namespace="http://bla";,
type = SymbolicField.class),
                    @XmlElement(name = "date", namespace="http://bla";, type
= DateField.class),
                    @XmlElement(name = "boolean", namespace="http://bla";,
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 : fields) {
                            fieldMap.put(field.name, field);
                    }
                    return fieldMap;
            }
    } 
    @XmlSeeAlso({DataDefinition.class, Structure.class})
    public static abstract class Field implements Serializable {

        @XmlAttribute
        String name;

//        public String getName() {
//        return name;
//        }

        public void setName(String name) {
        this.name = name;
        }

            @XmlAttribute(required = false)
            long index;

//            public long getIndex() {
//                return index;
//            }
//
            public void setIndex(long index) {
                this.index = index;
            }
        }

    @XmlRootElement(name = "symbolic", namespace = "http://bla";)
        public static class SymbolicField extends Field {

        }

        public static class NumericField extends Field {

        }
        
        public static class DateField extends Field {

        }
        
        public static class BooleanField extends Field {

        } 


Please send me more info which can help me in reproducing it...

Cheers, Sergey


mraible wrote:
> 
> 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-tp25531242p25620282.html
Sent from the cxf-user mailing list archive at Nabble.com.

Reply via email to