The only way to reliably convert json to xml and back is to use type hints in xml. the default converter does not. This 1. throws everything after the first property 2. mixes lists of individual elements with properties when moving from xml to json
I redefined the transconversion classes using the json-util library, which converts json-xml-containing type hints as element attributes so that there is no ambiguity.
this way we can use an intelligent proxy server (i.e. content route and mediate during transportation and payload) for ALL json-based support services via WSO2 without problems
This solves the problem (I think the camel does this by default).
Here is the pom file and code:
put the jar in / repository / components / lib
you must update the messageformatter and messagebuilder mappings for the content type "application / json" in axis2.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <name>wso2 json/xml converter</name> <groupId>xyz</groupId> <artifactId>wso2converter</artifactId> <version>1.0.0-SNAPSHOT</version> <packaging>jar</packaging> <properties> <jdk.version>1.6</jdk.version> </properties> <build> <finalName>wso2converter</finalName> <resources> <resource> <filtering>false</filtering> <directory>src/main/resources</directory> </resource> </resources> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>${jdk.version}</source> <target>${jdk.version}</target> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-enforcer-plugin</artifactId> <version>1.0.1</version> <executions> <execution> <id>enforce-jdk</id> <phase>validate</phase> <goals> <goal>display-info</goal> <goal>enforce</goal> </goals> <configuration> <rules> <requireJavaVersion> <version>[${jdk.version},)</version> </requireJavaVersion> </rules> </configuration> </execution> </executions> </plugin> </plugins> </build> <dependencies> <dependency> <groupId>net.sf.json-lib</groupId> <artifactId>json-lib</artifactId> <version>2.3</version> <classifier>jdk15</classifier> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-io</artifactId> <version>1.3.2</version> <type>jar</type> <scope>compile</scope> </dependency> <dependency> <groupId>org.apache.ws.commons.axiom</groupId> <artifactId>axiom-api</artifactId> <version>1.2.13</version> </dependency> <dependency> <groupId>org.apache.axis2</groupId> <artifactId>axis2-kernel</artifactId> <version>1.6.2</version> </dependency> <dependency> <groupId>xom</groupId> <artifactId>xom</artifactId> <version>1.1</version> </dependency> <dependency> <groupId>org.apache.synapse</groupId> <artifactId>synapse-core</artifactId> <version>2.1.0</version> </dependency> <dependency> <groupId>com.sun.jersey</groupId> <artifactId>jersey-json</artifactId> <version>1.1.5</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.8.2</version> </dependency> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.13</version> </dependency> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.4</version> <scope>test</scope> </dependency> </dependencies> </project>
package abwso2; import java.io.InputStream; import net.sf.json.JSON; import net.sf.json.JSONSerializer; import net.sf.json.xml.XMLSerializer; import org.apache.axiom.om.OMElement; import org.apache.axiom.om.util.AXIOMUtil; import org.apache.axis2.AxisFault; import org.apache.axis2.builder.Builder; import org.apache.axis2.context.MessageContext; import org.apache.commons.io.IOUtils; import org.apache.log4j.BasicConfigurator; import org.apache.log4j.Logger; public class WsoJtoX implements Builder { Logger logger = Logger.getLogger("abwso2converter"); @Override public OMElement processDocument(InputStream is, String contentType, MessageContext messageContext) throws AxisFault { String jsonData = ""; try { jsonData = IOUtils.toString(is,"UTF-8"); String output = process(jsonData); OMElement e = AXIOMUtil.stringToOM(output); return e; } catch (Exception e) { logger.error("error converting json string " + jsonData, e); if (e instanceof AxisFault) { throw (AxisFault) e; } throw new AxisFault("(B"+counter+") error converting json to xml", e); } } static int counter=0; public String process(String jsonData) throws AxisFault { try { String tran = "__ns__"; jsonData=jsonData.replace("\r", "").trim();
package abwso2; import java.io.IOException; import java.io.OutputStream; import java.io.UnsupportedEncodingException; import java.net.URL; import net.sf.json.JSON; import net.sf.json.xml.XMLSerializer; import org.apache.axiom.om.OMElement; import org.apache.axiom.om.OMOutputFormat; import org.apache.axiom.om.util.AXIOMUtil; import org.apache.axis2.AxisFault; import org.apache.axis2.Constants; import org.apache.axis2.context.MessageContext; import org.apache.axis2.transport.MessageFormatter; import org.apache.log4j.BasicConfigurator; import org.apache.log4j.Logger; public class WsoXtoJ implements MessageFormatter { Logger logger = Logger.getLogger("abwso2converter"); private static int counter=0; public String convert(String xData) { counter++; if (logger.isDebugEnabled()) { logger.debug("\n]]]]] (A"+counter+") converting xml\n " + xData + "\n-----"); } try { String tran = "__ns__"; XMLSerializer serializer = new XMLSerializer(); OMElement e = AXIOMUtil.stringToOM(xData); OMElement b = (OMElement) e.getChildrenWithLocalName("Body").next(); b = (OMElement) b.getChildElements().next(); String xfrag = b.toStringWithConsume(); String str = ""; JSON j = serializer.read(xfrag); str = j.toString(); String nstr = str.replaceAll("\"([a-zA-Z0-9_]+)" + tran + "([a-zA-Z0-9]+)\"(\\s*)(:)", "\"$1:$2\"$3:"); //", "\"$1:$2\""); if (logger.isDebugEnabled()) { logger.debug("\n----- (A"+counter+") to json\n" + nstr+"\n[[[[["); } return nstr; } catch (Exception e) { throw new RuntimeException(e); } } @Override public String formatSOAPAction(MessageContext msgCtxt, OMOutputFormat format, String soapActionString) { return null; } @Override public byte[] getBytes(MessageContext ctx, OMOutputFormat format) throws AxisFault { String env=""; try { OMElement element = ctx.getEnvelope().getBody().getFirstElement(); String payload = this.convert(element.toString()); return payload.getBytes(format.getCharSetEncoding()); } catch (UnsupportedEncodingException e) { logger.error("(A"+counter+") error converting xml to json "+ctx.getEnvelope().toString()); throw AxisFault.makeFault(e); } } @Override public String getContentType(MessageContext msgCtxt, OMOutputFormat format, String soapActionString) { String contentType = (String) msgCtxt.getProperty(Constants.Configuration.CONTENT_TYPE); String encoding = format.getCharSetEncoding(); if (contentType == null) { contentType = (String) msgCtxt.getProperty(Constants.Configuration.MESSAGE_TYPE); } if (encoding != null) { contentType += "; charset=" + encoding; } return contentType; } @Override public URL getTargetAddress(MessageContext msgCtxt, OMOutputFormat format, URL targetURL) throws AxisFault { return targetURL; } @Override public void writeTo(MessageContext msgCtxt, OMOutputFormat format, OutputStream out, boolean preserve) throws AxisFault { try { out.write(this.getBytes(msgCtxt, format)); out.flush(); } catch (IOException e) { throw AxisFault.makeFault(e); } } }