我从jaxb模型中生成休息响应(使用Jersey)。对于某些响应,生成的XML将名称空间前缀(ns2)添加到名称空间属性,尽管它们都存在于同一名称空间中。但对于其他人来说,这完全没问题。
通过我的分析,我认为当一个复杂元素(另一个jaxb模型)被使用时会发生这种情况。但所有这些模型都在package-info.java中的相同名称空间中声明。
这是代码。
XYZModel.class
package int.xyxp.model;
@XmlType(name="xyztype")
@XmlRootElement(name="xyz")
@XmlSeeAlso({XModel.class, YModel.class, Z.class})
@XmlAccessorType(XmlAccessType.FIELD)
public class XYZModel extends VModel {
@XmlElement(name="code")
private String code;
@XmlElementWrapper(name="refs", namespace="http://reference.com/ref")
@XmlElementRef
private List<XModel> refs = new ArrayList<XModel>(0);
//continues
package-info.java
@javax.xml.bind.annotation.XmlSchema(
namespace = "http://reference.com/ref",
elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)
package int.xyxp.model;
生成XML
<?xml version="1.0" encoding="UTF-8" standalone="true"?>
<ns2:xyz version="1.0" xmlns:ns2="http://reference.com/ref">
<ns2:code>15</ns2:code>
<ns2:refs/>
</ns2:xyz>
预期的XML(没有前缀,假设默认命名空间)。
<?xml version="1.0" encoding="UTF-8" standalone="true"?>
<xyz version="1.0" xmlns="http://reference.com/ref">
<code>15</code>
<refs/>
</xyz>
任何想法。感谢。
[编辑]
在我尝试插入我首选的命名空间前缀后,它甚至都不起作用。所以package-info.java可能只用于命名空间而不是用于选择命名空间前缀。
package-info.java
@javax.xml.bind.annotation.XmlSchema(
namespace = "http://reference.com/ref",
xmlns = {
@javax.xml.bind.annotation.XmlNs(prefix = "ref", namespaceURI = "http://reference.com/ref"),
},
elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)
package int.xyxp.model;
答案 0 :(得分:0)
注意:我已覆盖MessageBodyWriter以提供我自己的命名空间(“my”)。即使我返回空“”,默认情况下它为空时也需要ns2。因此,如果您想拥有自己的命名空间而不是默认的“ns2”,则此答案有效。
import java.io.IOException;
import java.io.OutputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import javax.ws.rs.Produces;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.ext.ContextResolver;
import javax.ws.rs.ext.MessageBodyWriter;
import javax.ws.rs.ext.Provider;
import javax.ws.rs.ext.Providers;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import com.sun.xml.internal.bind.marshaller.NamespacePrefixMapper;
@Produces(value=MediaType.APPLICATION_XML)
public class WSNamespaceWriter implements MessageBodyWriter<Object>{
@Context
protected Providers providers;
public boolean isWriteable(Class<?> type, Type genericType,
Annotation[] annotations, MediaType mediaType) {
System.out.println("Calling MessageWriter writetable--> " + type.getName());
return true;
}
public void writeTo(Object object, Class<?> type, Type genericType,
Annotation[] annotations, MediaType mediaType,
MultivaluedMap<String, Object> httpHeaders,
OutputStream entityStream) throws IOException,
WebApplicationException {
try {
System.out.println("Calling MessageWriter-->");
ContextResolver<JAXBContext> resolver
= providers.getContextResolver(JAXBContext.class, mediaType);
JAXBContext jaxbContext;
if(null == resolver || null == (jaxbContext = resolver.getContext(type))) {
jaxbContext = JAXBContext.newInstance(type);
}
Marshaller m = jaxbContext.createMarshaller();
NamespacePrefixMapper mapper = new NamespacePrefixMapper() {
public String getPreferredPrefix(String namespaceUri, String suggestion, boolean requirePrefix) {
System.out.println ("Called NAMESPACE----------" + namespaceUri);
if ("http://www.example.com".equals(namespaceUri)
|| ("").equals(namespaceUri)) {
System.out.println ("Called NAMESPACE return --------");
return "my"; // my own namespace
}
System.out.println ("Called NAMESPACE return ns--------");
return "";
}
};
m.setProperty("com.sun.xml.internal.bind.namespacePrefixMapper", mapper);
m.marshal(object, entityStream);
} catch(JAXBException jaxbException) {
throw new WebApplicationException(jaxbException);
}
}
public long getSize(Object t, Class<?> type, Type genericType,
Annotation[] annotations, MediaType mediaType) {
return -1;
}
}