Hi,
At the moment you need to add a duplicate entry to the namespace map on
the read side, and bind the same namespace to the 'ns2' prefix.
I've committed a fix (CXF-4296) to avoid it.
A lot of the test code below is redundant (to do with setting class
names and maps). Also note that setting a namespace map is not required
anymore on the write side, unless you need to control the prefixes as in
this test. I'll update the docs...
Here is the updated code the works after the merge:
@Test
public void testWriteReadDerivedNamespace() throws Exception {
JSONProvider<Base1> provider = new JSONProvider<Base1>();
provider.setMarshallAsJaxbElement(true);
Map<String, String> namespaceMap = new HashMap<String, String>();
namespaceMap.put("http://derivedtest", "derivedtestnamespace");
provider.setNamespaceMap(namespaceMap);
Base1 b = new Derived1("base", "derived");
ByteArrayOutputStream bos = new ByteArrayOutputStream();
provider.writeTo(b, Base1.class, Base1.class,
new Annotation[0], MediaType.APPLICATION_JSON_TYPE,
new MetadataMap<String, Object>(), bos);
readBase(bos.toString());
}
private void readBase(String data) throws Exception {
JSONProvider<Base1> provider = new JSONProvider<Base1>();
provider.setUnmarshallAsJaxbElement(true);
Map<String, String> namespaceMap = new HashMap<String, String>();
namespaceMap.put("http://derivedtest", "derivedtestnamespace");
provider.setNamespaceMap(namespaceMap);
ByteArrayInputStream is = new
ByteArrayInputStream(data.getBytes());
Base1 base = provider.readFrom(
Base1.class, Base1.class,
new Annotation[0], MediaType.APPLICATION_JSON_TYPE,
new MetadataMap<String, String>(), is);
assertEquals("base", base.getBase1Field());
}
Cheers, SErgey
On 07/05/12 14:11, Govindaram PS wrote:
Thanks Sergey. Your comment helped a lot.
But I am having issues in managing derived objects with namespace.
This is the test case.
@Test
public void testWriteReadDerivedNamespace() throws Exception {
JSONProvider<Base1> provider = new JSONProvider<Base1>();
provider.setMarshallAsJaxbElement(true);
provider.setUnmarshallAsJaxbElement(true);
Map<String, String> namespaceMap = new HashMap<String, String>();
namespaceMap.put("http://derivedtest", "derivedtestnamespace");
provider.setNamespaceMap(namespaceMap);
List<String> classnames = new ArrayList<String>();
classnames.add(Base1.class.getName());
classnames.add(Derived1.class.getName());
provider.setJaxbElementClassNames(classnames);
Map<String, String> jaxbEleClassMap = new HashMap<String, String>();
jaxbEleClassMap.put(Base1.class.getName(), "{http://derivedtest
}bas");
jaxbEleClassMap.put(Derived1.class.getName(), "{http://derivedtest
}der1");
provider.setJaxbElementClassMap(jaxbEleClassMap);
Base1 b = new Derived1("base", "derived");
ByteArrayOutputStream bos = new ByteArrayOutputStream();
provider.writeTo(b, Base1.class, Base1.class,
new Annotation[0], MediaType.APPLICATION_JSON_TYPE,
new MetadataMap<String, Object>(), bos);
readBase(bos.toString());
}
private void readBase(String data) throws Exception {
JSONProvider<Base1> provider = new JSONProvider<Base1>();
provider.setMarshallAsJaxbElement(true);
provider.setUnmarshallAsJaxbElement(true);
Map<String, String> namespaceMap = new HashMap<String, String>();
namespaceMap.put("http://derivedtest", "derivedtestnamespace");
provider.setNamespaceMap(namespaceMap);
List<String> classnames = new ArrayList<String>();
classnames.add(Base1.class.getName());
classnames.add(Derived1.class.getName());
provider.setJaxbElementClassNames(classnames);
Map<String, String> jaxbEleClassMap = new HashMap<String, String>();
jaxbEleClassMap.put(Base1.class.getName(), "{http://derivedtest
}basenamespace");
jaxbEleClassMap.put(Derived1.class.getName(), "{http://derivedtest
}dernamespace");
provider.setJaxbElementClassMap(jaxbEleClassMap);
ByteArrayInputStream is = new ByteArrayInputStream(data.getBytes());
Base1 base = provider.readFrom(
Base1.class, Base1.class,
new Annotation[0], MediaType.APPLICATION_JSON_TYPE,
new MetadataMap<String, String>(), is);
assertEquals("base", base.getBase1Field());
}
The Bean class are:
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "Base1"
, namespace = "http://derivedtest"
)
@XmlSeeAlso({Derived1.class })
public class Base1 {
protected String base1Field;
Base1() { }
Base1(String base) {
base1Field = base;
}
public String getBase1Field() {
return base1Field;
}
public void setBase1Field(String value) {
this.base1Field = value;
}
}
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "Derived1"
, namespace = "http://derivedtest"
)
public class Derived1
extends Base1 {
protected String derived1Field;
Derived1() { }
public Derived1(String base, String derived) {
super(base);
derived1Field = derived;
}
public String getDerived1Field() {
return derived1Field;
}
public void setDerived1Field(String value) {
this.derived1Field = value;
}
}
provider.writeTo serialize as follows.
{"derivedtestnamespace.bas":{"@xsi.type":"ns2
:Derived1","base1Field":"base","derived1Field":"derived"}}
During unmarsalling it is throwing the following exception:
javax.ws.rs.WebApplicationException:
java.lang.IllegalArgumentException:*prefix ns2 is not bound to a
namespace
*
at
org.apache.cxf.jaxrs.provider.json.JSONProvider.readFrom(JSONProvider.java:246)
at
org.apache.cxf.jaxrs.provider.json.JSONProviderTest.readBase(JSONProviderTest.java:149)
at
org.apache.cxf.jaxrs.provider.json.JSONProviderTest.testWriteReadDerivedNamespace(JSONProviderTest.java:126)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at
org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
at
org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at
org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at
org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at
org.junit.runners.BlockJUnit4ClassRunner.runNotIgnored(BlockJUnit4ClassRunner.java:79)
at
org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:71)
at
org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
at
org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at
org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: java.lang.IllegalArgumentException: prefix ns2 is not bound to a
namespace
at
com.sun.xml.bind.DatatypeConverterImpl._parseQName(DatatypeConverterImpl.java:385)
at
com.sun.xml.bind.v2.runtime.unmarshaller.XsiTypeLoader.parseXsiType(XsiTypeLoader.java:92)
at
com.sun.xml.bind.v2.runtime.unmarshaller.XsiTypeLoader.startElement(XsiTypeLoader.java:70)
at
com.sun.xml.bind.v2.runtime.unmarshaller.ProxyLoader.startElement(ProxyLoader.java:55)
at
com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext._startElement(UnmarshallingContext.java:481)
at
com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext.startElement(UnmarshallingContext.java:459)
at
com.sun.xml.bind.v2.runtime.unmarshaller.InterningXmlVisitor.startElement(InterningXmlVisitor.java:71)
at
com.sun.xml.bind.v2.runtime.unmarshaller.StAXStreamConnector.handleStartElement(StAXStreamConnector.java:242)
at
com.sun.xml.bind.v2.runtime.unmarshaller.StAXStreamConnector.bridge(StAXStreamConnector.java:176)
at
com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:360)
at
com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:339)
at
org.apache.cxf.jaxrs.provider.json.JSONProvider.readFrom(JSONProvider.java:222)
... 25 more
I don't how namespace ns2 jumps in.
Please help.
Thanks,
Govind
On Fri, May 4, 2012 at 7:55 PM, Sergey Beryozkin<[email protected]>wrote:
Hi
On 04/05/12 10:52, Govindaram PS wrote:
When the json data includes namespace, marshalling to json string and
unmarshling the same string is failing.
The test case to verify is below. This test case can be directly executed
in cxf/rt/frontend/jaxrs/src/**test/java/org/apache/cxf/**jaxrs/provider/
**JSONProviderTest.java
let me know if anything wrong in this test case.
Base1 class has no XMLRootElement annotation, so the following applies:
http://cxf.apache.org/docs/**jax-rs-data-bindings.html#JAX-**
RSDataBindings-**HandlingJAXBbeanswithoutXmlRoo**tElementannotations<http://cxf.apache.org/docs/jax-rs-data-bindings.html#JAX-RSDataBindings-HandlingJAXBbeanswithoutXmlRootElementannotations>
,
I used marshallAsJaxbElement and unmarshallAsJaxbElement properties
instead, but the class map property can do too
Cheers, Sergey
@Test
public void testWriteReadNamespace() throws Exception {
JSONProvider<Base1> provider = new JSONProvider<Base1>();
Map<String, String> namespaceMap = new HashMap<String, String>();
namespaceMap.put("http://**derivedtest<http://derivedtest>",
"ns1");
provider.setNamespaceMap(**namespaceMap);
List<String> classnames = new ArrayList<String>();
classnames.add(Base1.class.**getName());
provider.**setJaxbElementClassNames(**classnames);
Base1 b = new Base1("base");
ByteArrayOutputStream bos = new ByteArrayOutputStream();
provider.writeTo(b, Base1.class, Base1.class,
new Annotation[0], MediaType.APPLICATION_JSON_**
TYPE,
new MetadataMap<String, Object>(), bos);
readBase(bos.toString());
}
private void readBase(String data) throws Exception {
JSONProvider<Base1> provider = new JSONProvider<Base1>();
Map<String, String> namespaceMap = new HashMap<String, String>();
namespaceMap.put("http://**derivedtest<http://derivedtest>",
"ns1");
provider.setNamespaceMap(**namespaceMap);
List<String> classnames = new ArrayList<String>();
classnames.add(Base1.class.**getName());
provider.**setJaxbElementClassNames(**classnames);
ByteArrayInputStream is = new ByteArrayInputStream(data.**
getBytes());
Base1 base = provider.readFrom(
Base1.class, Base1.class,
new Annotation[0], MediaType.APPLICATION_JSON_**
TYPE,
new MetadataMap<String, String>(), is);
assertEquals("base", base.getBase1Field());
}
@XmlAccessorType(**XmlAccessType.FIELD)
@XmlType(name = "Base1", namespace = "http://derivedtest")
public static class Base1 {
protected String base1Field;
Base1() { }
Base1(String base) {
base1Field = base;
}
public String getBase1Field() {
return base1Field;
}
public void setBase1Field(String value) {
this.base1Field = value;
}
}
--
Sergey Beryozkin
Talend Community Coders
http://coders.talend.com/
Blog: http://sberyozkin.blogspot.com
--
Sergey Beryozkin
Talend Community Coders
http://coders.talend.com/
Blog: http://sberyozkin.blogspot.com