Java 7,Jersey 2.17 + Jersey-media-moxy 2.17
所有JAXB类都具有相同的命名空间。 FindResponse和ApipeApipe类位于不同的包中,两个包的package-info类具有相同的注释:
@javax.xml.bind.annotation.XmlSchema(namespace = "xmlapi_1.0", elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)
FindResponse类具有@XmlElementRoot,
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
})
@XmlRootElement(name = "findResponse")
public class FindResponse {
而ApipeApipe类
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "apipe.Apipe")
public class ApipeApipe extends VllVll {
FindResponse的ObjectFactory:
public FindResponse createFindResponse() {
return new FindResponse();
}
ApipeApipe的ObjectFactory:
@XmlElementDecl(namespace = "xmlapi_1.0", name = "apipe.Apipe")
public JAXBElement<ApipeApipe> createApipeApipe(ApipeApipe value) {
return new JAXBElement<ApipeApipe>(new QName("xmlapi_1.0", "apipe.Apipe"), ApipeApipe.class, null, value);
}
自定义MoxyJsonConfigResolver:
@Provider
public class MdmMoxyJsonConfigResolver implements ContextResolver<MoxyJsonConfig> {
private final MoxyJsonConfig config;
public MdmMoxyJsonConfigResolver() {
final Map<String, String> namespacePrefixMapper = new HashMap<String, String>();
namespacePrefixMapper.put(javax.xml.XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, "xsi");
namespacePrefixMapper.put("xmlapi_1.0", "");
config = new MoxyJsonConfig()
.setNamespacePrefixMapper(namespacePrefixMapper)
.setNamespaceSeparator(':')
.setAttributePrefix("@")
.setValueWrapper("value")
.property(JAXBContextProperties.JSON_WRAPPER_AS_ARRAY_NAME, true)
.setFormattedOutput(true)
.setIncludeRoot(true)
.setMarshalEmptyCollections(true);
}
@Override
public MoxyJsonConfig getContext(Class<?> type) {
return config;
}
}
Json输出:
{
"findResponse" : {
"result" : {
"ns0:lag.Interface" : [ {
"ns0:objectFullName" : "network:35.121.34.101:lag:interface-31",
"ns0:selfAlarmed" : true,
"ns0:name" : "interface-31",
"ns0:administrativeState" : "portInService",
"ns0:baseMacAddress" : "00-00-00-00-00-00",
"ns0:cleiCode" : "N/A",
"ns0:displayedName" : "Lag 31",
"ns0:equipmentCategory" : "port",
"ns0:equipmentState" : "equipmentOperationallyDown",
"ns0:hardwareFailureReason" : "N/A"}]
}}}
我在MoxyJsonConfig中将名称空间前缀设置为空白,它似乎不起作用。如何摆脱名称空间前缀,尤其是前置于属性的名称前缀?
我添加了一个测试来检查XML格式的输出:
代码:
@Test
public void testMoxyJaxb() throws Exception {
ApipeApipe apipe = findService.findByOfn(ApipeApipe.class, "svc-mgr:service-96849");
FindResponse findResponse = getFindResponse(Arrays.asList(apipe));
{
javax.xml.bind.JAXBContext jaxbContext = javax.xml.bind.JAXBContext.newInstance(getClassesToBeBound());
Marshaller marshaller = jaxbContext.createMarshaller();
System.out.println("javax.xml.bind.JAXBContext output: ");
marshaller.marshal(findResponse, System.out);
System.out.println("");
}
{
Map<String, Object> properties = new HashMap<String, Object>();
properties.put(JAXBContextProperties.DEFAULT_TARGET_NAMESPACE, "xmlapi_1.0");
javax.xml.bind.JAXBContext jaxbContext = org.eclipse.persistence.jaxb.JAXBContextFactory.createContext(getClassesToBeBound(), properties);
org.eclipse.persistence.jaxb.JAXBMarshaller marshaller = (org.eclipse.persistence.jaxb.JAXBMarshaller)jaxbContext.createMarshaller();
Map<String, Object> nsPrefix = new HashMap<String, Object>();
// nsPrefix.put(XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, "xsi");
nsPrefix.put("xmlapi_1.0", "");
marshaller.setProperty(MarshallerProperties.NAMESPACE_PREFIX_MAPPER, nsPrefix);
System.out.println("org.eclipse.persistence.jaxb.JAXBContextFactory output: ");
marshaller.marshal(findResponse, System.out);
System.out.println("");
}
{
System.out.println("org.springframework.oxm.jaxb.Jaxb2Marshaller output: ");
Result result = new StringResult();
jaxb.marshal(findResponse, result);
System.out.println(result.toString());
System.out.println("");
}
}
输出:
javax.xml.bind.JAXBContext output:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><findResponse xmlns="xmlapi_1.0"><result><apipe.Apipe><objectFullName>svc-mgr:service-96849</objectFullName><selfAlarmed>false</selfAlarmed><name>service-96849</name><groupPointer></groupPointer><id>96849</id><serviceId>500</serviceId><subscriberPointer>subscriber:1</subscriberPointer><administrativeState>down</administrativeState><description>N/A</description><displayedName>APIPE 500</displayedName><aggrOperationalState>down</aggrOperationalState><compositeSvcId>0</compositeSvcId><compositeSvcPointer></compositeSvcPointer><configuredNumberOfSites>0</configuredNumberOfSites><customerName>Default customer</customerName><mtuInconsistent>false</mtuInconsistent><numberOfCircuitsInconsistent>false</numberOfCircuitsInconsistent><numberOfConnector>0</numberOfConnector><numberOfInterfacesInconsistent>false</numberOfInterfacesInconsistent><numberOfSites>0</numberOfSites><numberOfSitesInconsistent>false</numberOfSitesInconsistent><olcState>maintenance</olcState><operationalFlags/><sasEntityName>A-pipe Service #500</sasEntityName><subscriberId>1</subscriberId><vcType>atmvcc</vcType></apipe.Apipe></result></findResponse>
org.eclipse.persistence.jaxb.JAXBContextFactory output:
<?xml version="1.0" encoding="UTF-8"?><findResponse xmlns="xmlapi_1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><result><apipe.Apipe xmlns:ns0="xmlapi_1.0"><objectFullName>svc-mgr:service-96849</objectFullName><selfAlarmed>false</selfAlarmed><name>service-96849</name><groupPointer></groupPointer><id>96849</id><serviceId>500</serviceId><subscriberPointer>subscriber:1</subscriberPointer><administrativeState>down</administrativeState><description>N/A</description><displayedName>APIPE 500</displayedName><aggrOperationalState>down</aggrOperationalState><compositeSvcId>0</compositeSvcId><compositeSvcPointer></compositeSvcPointer><configuredNumberOfSites>0</configuredNumberOfSites><customerName>Default customer</customerName><mtuInconsistent>false</mtuInconsistent><numberOfCircuitsInconsistent>false</numberOfCircuitsInconsistent><numberOfConnector>0</numberOfConnector><numberOfInterfacesInconsistent>false</numberOfInterfacesInconsistent><numberOfSites>0</numberOfSites><numberOfSitesInconsistent>false</numberOfSitesInconsistent><olcState>maintenance</olcState><operationalFlags/><sasEntityName>A-pipe Service #500</sasEntityName><subscriberId>1</subscriberId><vcType>atmvcc</vcType></apipe.Apipe></result></findResponse>
org.springframework.oxm.jaxb.Jaxb2Marshaller output:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><findResponse xmlns="xmlapi_1.0"><result><apipe.Apipe><objectFullName>svc-mgr:service-96849</objectFullName><selfAlarmed>false</selfAlarmed><name>service-96849</name><groupPointer></groupPointer><id>96849</id><serviceId>500</serviceId><subscriberPointer>subscriber:1</subscriberPointer><administrativeState>down</administrativeState><description>N/A</description><displayedName>APIPE 500</displayedName><aggrOperationalState>down</aggrOperationalState><compositeSvcId>0</compositeSvcId><compositeSvcPointer></compositeSvcPointer><configuredNumberOfSites>0</configuredNumberOfSites><customerName>Default customer</customerName><mtuInconsistent>false</mtuInconsistent><numberOfCircuitsInconsistent>false</numberOfCircuitsInconsistent><numberOfConnector>0</numberOfConnector><numberOfInterfacesInconsistent>false</numberOfInterfacesInconsistent><numberOfSites>0</numberOfSites><numberOfSitesInconsistent>false</numberOfSitesInconsistent><olcState>maintenance</olcState><operationalFlags/><sasEntityName>A-pipe Service #500</sasEntityName><subscriberId>1</subscriberId><vcType>atmvcc</vcType></apipe.Apipe></result></findResponse>
org.eclipse.persistence.jaxb.JAXBMarshaller输出的标记上还有一个名称空间属性。在其他两个编组的输出中并不存在。这是名称空间前缀被添加到JSON输出的属性名称的原因吗?