我正在尝试使用MOXy JAXB在Apache CFX项目中解组一些JSON / XML。以下请求给我带来了麻烦:
{"CC.ConsumerPersistAppDataRequest" : {
"SessionId" : "42",
"AppData" : [
{"AppDatum" : {
"TimeStamp" : 1384548486,
"Value" : "Some kind of String would go here"}},
{"AppDatum" : {
"TimeStamp" : 1384548578,
"Value" : "I hope I am understanding this format correctly!"}},
{"AppDatum" : {
"TimeStamp" : 1384549696,
"Value" : "One more time for the road..."}}],
"MetaDataTags" : ["dumb", "dummy", "data"]}
}
此处,AppData作为List< AppDatum>进行解组,但该列表仅包含最后一个元素。值得注意的是,“MetaDataTags”元素被正确地解组为List< String>大小为3。
令人惊讶的是,尽管“AppData”应该期望List< AppDatum>,但是可以提交具有相同结果的以下请求。 (我不禁觉得这是相关的):
{"CC.ConsumerPersistAppDataRequest" : {
"SessionId" : "42",
"AppData" : {
"AppDatum" : {
"TimeStamp" : 1384548486,
"Value" : "Some kind of String would go here"
}
}
}}
这个XML等价物(或我看到的XML等价物)按预期解析:
<?xml version="1.0" encoding="UTF-8"?>
<cc:ConsumerPersistAppDataRequest xmlns:cc="http://org/alg/ari/pnd/introspect/webservices/consumercomms">
<SessionId>42</SessionId>
<AppData>
<AppDatum>
<TimeStamp>1384548486</TimeStamp>
<Value>Some kind of String would go here</Value>
</AppDatum>
<AppDatum>
<TimeStamp>1384548578</TimeStamp>
<Value>I hope I am understanding this format correctly!</Value>
</AppDatum>
<AppDatum>
<TimeStamp>1384549696</TimeStamp>
<Value>One more time for the road...</Value>
</AppDatum>
</AppData>
<MetaDataTags>dumb dummy data</MetaDataTags>
</cc:ConsumerPersistAppDataRequest>
有问题的JAXB类(由XJC生成,评论已被删除):
package org.alg.ari.pnd.introspect.webservices.consumercomms;
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlList;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
"sessionId",
"appData",
"metaDataTags"
})
@XmlRootElement(name = "ConsumerPersistAppDataRequest")
public class ConsumerPersistAppDataRequest {
@XmlElement(name = "SessionId", required = true)
protected String sessionId;
@XmlElement(name = "AppData", required = true)
protected ConsumerPersistAppDataRequest.AppData appData;
@XmlList
@XmlElement(name = "MetaDataTags", required = true)
protected List<String> metaDataTags;
public String getSessionId() {
return sessionId;
}
public void setSessionId(String value) {
this.sessionId = value;
}
public ConsumerPersistAppDataRequest.AppData getAppData() {
return appData;
}
public void setAppData(ConsumerPersistAppDataRequest.AppData value) {
this.appData = value;
}
public List<String> getMetaDataTags() {
if (metaDataTags == null) {
metaDataTags = new ArrayList<String>();
}
return this.metaDataTags;
}
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
"appDatum"
})
public static class AppData {
@XmlElement(name = "AppDatum", required = true)
protected List<ConsumerPersistAppDataRequest.AppData.AppDatum> appDatum;
public List<ConsumerPersistAppDataRequest.AppData.AppDatum> getAppDatum() {
if (appDatum == null) {
appDatum = new ArrayList<ConsumerPersistAppDataRequest.AppData.AppDatum>();
}
return this.appDatum;
}
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
"timeStamp",
"value"
})
public static class AppDatum {
@XmlElement(name = "TimeStamp")
protected long timeStamp;
@XmlElement(name = "Value", required = true)
protected String value;
public long getTimeStamp() {
return timeStamp;
}
public void setTimeStamp(long value) {
this.timeStamp = value;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
}
}
和我的MoxyJsonProvider bean
<bean id="moxy-json-provider"
class="org.eclipse.persistence.jaxb.rs.MOXyJsonProvider">
<property name="attributePrefix" value="@" />
<property name="formattedOutput" value="true" /> <!-- set to false for production! -->
<property name="includeRoot" value="true" />
<property name="marshalEmptyCollections" value="false" />
<property name="valueWrapper" value="$" />
<property name="namespacePrefixMapper" ref="json-ns-mapper" />
</bean>
知道可能导致此问题的原因是什么?这是MOXy 2.5.1版本中的错误吗?或者我需要设置一个“开关”吗?
答案 0 :(得分:0)
根据您的映射,下面的内容将是预期的JSON文档:
{
"CC.ConsumerPersistAppDataRequest" : {
"SessionId" : "42",
"AppData" : {
"AppDatum" : [ {
"TimeStamp" : 1384548486,
"Value" : "Some kind of String would go here"
}, {
"TimeStamp" : 1384548578,
"Value" : "I hope I am understanding this format correctly!"
}, {
"TimeStamp" : 1384549696,
"Value" : "One more time for the road..."
} ]
},
"MetaDataTags" : "dumb dummy data"
}
}
以下是我根据您的内容编写的独立示例,以读取XML并输出相应的JSON:
import java.io.File;
import java.util.*;
import javax.xml.bind.*;
import org.eclipse.persistence.jaxb.MarshallerProperties;
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(ConsumerPersistAppDataRequest.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
File xml = new File("src/forum20056524/input.xml");
ConsumerPersistAppDataRequest result = (ConsumerPersistAppDataRequest) unmarshaller.unmarshal(xml);
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(MarshallerProperties.MEDIA_TYPE, "application/json");
marshaller.setProperty(MarshallerProperties.JSON_ATTRIBUTE_PREFIX, "@");
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.setProperty(MarshallerProperties.JSON_INCLUDE_ROOT, true);
marshaller.setProperty(MarshallerProperties.JSON_MARSHAL_EMPTY_COLLECTIONS, false);
marshaller.setProperty(MarshallerProperties.JSON_VALUE_WRAPPER, "$");
Map<String, String> jsonNsMapper = new HashMap<String, String>(1);
jsonNsMapper.put("http://org/alg/ari/pnd/introspect/webservices/consumercomms", "CC");
marshaller.setProperty(MarshallerProperties.NAMESPACE_PREFIX_MAPPER, jsonNsMapper);
marshaller.marshal(result, System.out);
}
}