如果我没记错的话,我必须做一些事情才能将命名空间标识符正确写入生成的 XML。
1) 创建了一个 JaxbFactory,它配置并返回一个自定义编组器(顺便说一句,解组器也是如此)。我省略了下面的 getters/and unmarshalling 设置...
//constructor
public JaxbFactory() throws Exception {
context = JAXBContext.newInstance(ResourceDto.class);
// Setup the marshaller
marshaller = context.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
marshaller.setProperty(Marshaller.JAXB_SCHEMA_LOCATION, XmlMetadataConstants.XML_SCHEMA_LOCATION); // this schema location is used in generating the schema-location property in the xml
}
2) 该工厂类对泽西岛“不可见”。为了使其可见,我创建了一个 MarshallerProvider。看起来像这样:
@Provider
public class ResourceJaxbMarshallerProvider implements ContextResolver<Marshaller> {
// injected by Spring
private ResourceJaxbFactory ResourceJaxbFactory;
private ResourceStatusJaxbFactory ResourceStatusJaxbFactory;
/*
* ----------------------------------------
* Setters (for Spring injected properties)
* ----------------------------------------
*/
public void setResourceJaxbFactory(ResourceJaxbFactory ResourceJaxbFactory) {
this.ResourceJaxbFactory = ResourceJaxbFactory;
}
public void setResourceStatusJaxbFactory(ResourceStatusJaxbFactory ResourceStatusJaxbFactory) {
this.ResourceStatusJaxbFactory = ResourceStatusJaxbFactory;
}
/*
* ------------------------
* Interface Implementation
* ------------------------
*/
public Marshaller getContext(Class<?> type) {
if (type == ResourceDto.class)
return ResourceJaxbFactory.getMarshaller();
else if (type == ResourceStatusDto.class)
return ResourceStatusJaxbFactory.getMarshaller();
else
return null;
}
}
我已经使用 Jersey/Spring Servlet 将 Jersey 连接到 Spring,因此由 Spring 创建的任何 @Provider 类都会被 Jersey 自动识别。在我的 Spring applicationContext.xml 中,我所要做的就是实例化资源提供者。反过来,它会从工厂抢走 marshaller。
3) 我发现关键的另一件事是我必须在包含我的资源的根包中创建一个 package-info.java 文件。看起来像这样:
/*
* Note that this file is critical for ensuring that our ResourceDto object is
* marshalled/unmarshalled with the correct namespace. Without this, marshalled
* classes produce XML files without a namespace identifier
*/
@XmlSchema(namespace = XmlMetadataConstants.XML_SCHEMA_NAMESPACE, elementFormDefault = XmlNsForm.QUALIFIED)
package com.yourcompany.resource;
import javax.xml.bind.annotation.XmlNsForm;
至少我认为这是我需要做的所有事情,我不记得每一个片段。我确实记得 package-info.java 是最后一个关键的齿轮,它把它们结合在一起。
希望对您有所帮助。我花了太多时间来挖掘这一切的信息。在我希望它进行正确的 xml 模式验证(以及对模式无效输入的体面错误报告)之前,Jersey 非常简单。一旦我开始沿着这条路走下去,泽西岛就从脑残容易变成了体面的困难。大部分困难是从网上各种帖子中找出所有细节。希望这将帮助您走得更远,更快。 :-)