我正在建造一个POC。我为Google Plus创建了传递代理服务。 不使用任何代理服务我得到这是我的输出:
{
"kind":"plus#person",
"etag":"\"ExituU7aUpmkkfyD52VulzptThw/4J1clegrhxYC2fsJOu2XWCs1Ewg\"",
"id":"117488614303967062311",
"displayName":"Abhi NeoN",
"name":{
"familyName":"NeoN",
"givenName":"Abhi"
},
"tagline":"hey guys ! ssup!! check out ma recnt videos... uploaded",
"gender":"male",
"aboutMe":"\u003cb\u003ehie, abhishek - ma full name \u003c/b\u003e\u003cdiv\u003e\u003cb\u003em a DANCER ,\u003c/b\u003e\u003c/div\u003e\u003cdiv\u003e\u003cb\u003ei luv ma dancing .\u003c/b\u003e\u003c/div\u003e\u003cdiv\u003e\u003cb\u003ei care ma dancing ,\u003c/b\u003e\u003c/div\u003e\u003cdiv\u003e\u003cb\u003ei jus hv a gr8 thng in me dats ma dancing.\u003c/b\u003e\u003c/div\u003e",
"relationshipStatus":"single",
"url":"https://plus.google.com/117488614303967062311",
"image":{
"url":"https://lh6.googleusercontent.com/-tF-ip0tUxD4/AAAAAAAAAAI/AAAAAAAAAAA/WKI3USUh_DA/photo.jpg?sz=50"
},
"urls":[
{
"value":"https://plus.google.com/117488614303967062311",
"type":"profile"
},
{
"value":"https://www.googleapis.com/plus/v1/people/117488614303967062311",
"type":"json"
}
],
"organizations":[
{
"name":"our lady of nazareth high school",
"title":"science",
"type":"school"
},
{
"name":"",
"title":"BLUEBYTES",
"type":"work"
}
]
}
但是当我尝试使用简单的传递服务来做同样的事情时,我只得到:
{
"kind":"plus#person"
}
我在wso2esb网站上看到他们有一个错误,并且解决该错误的解释是收到的json数据格式不正确。 但现在我该如何解决这个问题。我的意思是他们可以在esb将其转换为json数据之前操纵json数据。
答案 0 :(得分:5)
我们已在最新版本的ESB(版本4.5.0)中解决了此问题。默认情况下,它附带了JSONMessageFormatter / JSONBuilder,它可以处理具有多个密钥的JSON有效负载。
我们还提出了另一种处理消息流的解决方案,涉及不同类型的JSON< - > XML(或JSON< - > JSON)转换。 JSONStreamBuilder
和JSONStreamFormatter
可用于使用'script'介体实现此类方案。看看ESB 4.5.0中的示例#441。
运行样本#441;
JSONStreamBuilder
和JSONStreamFormatter
作为构建器和
存储库/ conf / axis2 / axis2.xml文件中的JSON格式化程序ant newjsonclient
”答案 1 :(得分:3)
这是当前axis2 JSON构建器/格式化程序的限制之一。我们目前正在为JSON开发一个新的构建器/格式化程序对,它不会转换JSON< - > XML。相反,它(构建器)将JSON消息存储为流,并且脚本介体可用于从该流构建JSON对象。例如,如果我们在ESB中发送{“a”:“x”,“b”:“y”}作为请求,我们可以使用javascript将此请求作为JSON对象进行操作。
var a = mc.getJSON().a.toString();
var b = mc.getJSON().b.toString();
mc.setPayloadXML(
<m:A xmlns:m="http://example.json">
<m:a>{a}</m:a>
<m:b>{b}</m:b>
</m:A>);
类似地,mc.setJSON()
方法可用于设置任意JSON对象。
答案 2 :(得分:3)
将json可靠地转换为xml并再次返回的唯一方法是通过在xml中使用类型提示。默认转换器不会这样做。它 1.在第一个财产之后丢弃一切 2.从xml到json
时,将单个元素列表与属性混淆我使用json-util库重新实现了transconversion类,它将json转换为包含类型提示的xml作为元素属性,以确保没有歧义。
通过这种方式,我们可以通过WSO2为所有基于json的休息服务提供智能代理(即内容路由和调解传输和有效负载),而不会出现问题
这解决了这个问题(我认为camel默认是这样做的。)
这是pom文件和代码:
将jar放入/ repository / components / lib
您必须更新axis2.xml中内容类型“application / json”的messageformatter和messagebuilder映射
<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>x.y.z</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>
<!--scope>provided</scope-->
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
package a.b.wso2;
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("a.b.wso2converter");
@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();
//jsonData=jsonData.replace("\n", "");
String decoded = (jsonData.replaceAll("\"([a-zA-Z0-9_]*)\\:([a-zA-Z0-9]*)\"(\\s*)(:)", "\"$1" + tran + "$2\"$3:"));
counter++;
if (logger.isDebugEnabled()) {
logger.debug("\n>>>>> (B"+counter+") converting json\n " + jsonData + "\n====");
}
XMLSerializer serializer = new XMLSerializer();
JSON json = JSONSerializer.toJSON(decoded);
String xml = serializer.write(json);
//add in the soap stuff
StringBuilder sb = new StringBuilder();
sb.append("<soap:Envelope xmlns:soap=\"http://www.w3.org/2001/12/soap-envelope\" soap:encodingStyle=\"http://www.w3.org/2001/12/soap-encoding\"> <soap:Body>");
sb.append(xml.replace("<?xml version=\"1.0\" encoding=\"UTF-8\"?>", ""));
sb.append("</soap:Body></soap:Envelope>");
if (logger.isDebugEnabled()) {
logger.debug("\n==== (B"+counter+") to xml\n" + sb.toString()+"\n<<<<<");
}
return sb.toString();
} catch (Exception e) {
throw new AxisFault("(B"+counter+") error transforming json to xml", e);
}
}
}
package a.b.wso2;
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("a.b.wso2converter");
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);
}
}
}
答案 3 :(得分:2)
我遇到了同样的问题。
根据我的经验,WSO2 ESB的JSON解析器(基于Axis2-json)仅支持JSON的一个子集:
JSON必须以“{”开头,即根处不能有JSONArray。
仅考虑第一个键值对。这是因为JSON映射到类似XML的数据结构,并且XML必须具有根,因此第一个键值对被视为root。
第一个键值对的值不能是数组。这是因为转换器必须知道每个值应该使用哪个XML标记:
例如:...... {“key”:[“val1”,“val2”,...]} - &gt; &LT;密钥GT; VAL1&LT; /密钥GT;&LT;密钥GT; val2的&LT; /密钥GT; ....
我在这里遇到同样的问题,想找到一个解决方法。我的想法是创建一个新的JSONBuilder(构建内部SOAP消息构造的解析器)和JSONFormatter(序列化器)来使用虚拟根(例如{“ root ”:...}})伪造解析器。