【发布时间】:2011-10-18 09:44:42
【问题描述】:
我是 RestEasy 和 JAXB 的新手。我认为它们非常易于使用,只要您控制要通过 Web 服务公开的所有来源。
但是现在我有一个问题。我有无法(不应该)使用 JAXB 注释进行注释的数据传输对象,但我仍然希望它们编组为 XML。
最简单的方法或最佳实践是什么?
感谢任何帮助或评论。
巴拉兹
【问题讨论】:
标签: java rest jaxb marshalling resteasy
我是 RestEasy 和 JAXB 的新手。我认为它们非常易于使用,只要您控制要通过 Web 服务公开的所有来源。
但是现在我有一个问题。我有无法(不应该)使用 JAXB 注释进行注释的数据传输对象,但我仍然希望它们编组为 XML。
最简单的方法或最佳实践是什么?
感谢任何帮助或评论。
巴拉兹
【问题讨论】:
标签: java rest jaxb marshalling resteasy
我遇到了同样的问题:我从持久层获取了实体对象(已经包含真实数据),但它们来自第 3 方类,我无法使用 @XmlRootElement 对其进行注释,也无法更改获取代码。
对我来说,只需将它们包裹在 JAXBElement 中就可以了。所以,RESTful 方法:
@GET
@Path("/listAll")
@Produces(MediaType.APPLICATION_XML); // "application/xml"
public List<Person> getPersonList() {
return persistenceLayer.fetchAllPerson();
}
更改为:
@GET
@Path("/listAll")
@Produces(MediaType.APPLICATION_XML); // "application/xml"
public List<JAXBElement<Person>> getPersonList() {
List<Person> ps = persistenceLayer.fetchAllPerson();
List<JAXBElement<Person>> jaxbeps = new ArrayList<JAXBElement<Person>>(ps.size());
for (Person p : ps) {
jaxbeps.add(jaxbeWrapp(p));
}
return jaxbeps;
}
以及使用的泛型方法(当然,你可以内联它):
public static <T> JAXBElement<T> jaxbeWrapp(T obj) {
Class<T> clazz = (Class<T>) obj.getClass();
return new JAXBElement<T>(new QName(obj.getClass().getName().toLowerCase()), clazz, obj);
}
就是这样!希望对您有所帮助!
【讨论】:
注意:我是EclipseLink JAXB (MOXy) 领导,也是JAXB 2 (JSR-222) 专家组的成员。
您可以使用 MOXy 的映射文档 JAXB 扩展来提供元数据。然后你可以在 JAX-RS 中使用ContextResolver 来引导JAXBContext。
package blog.bindingfile.jaxrs;
import java.io.*;
import java.util.*;
import javax.ws.rs.Produces;
import javax.ws.rs.ext.ContextResolver;
import javax.ws.rs.ext.Provider;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import org.eclipse.persistence.jaxb.JAXBContextFactory;
import blog.bindingfile.Customer;
@Provider
@Produces({"application/xml", "application/json"})
public class CustomerContextResolver implements ContextResolver<JAXBContext> {
private JAXBContext jc;
public CustomerContextResolver() {
ClassLoader cl = Customer.class.getClassLoader();
Map<String, Object> props = new HashMap<String, Object>(1);
props.put(JAXBContextFactory.ECLIPSELINK_OXM_XML_KEY, "blog/bindingfile/binding.xml");
jc = JAXBContext.newInstance(new Class[] {Customer.class} , props);
}
public JAXBContext getContext(Class<?> clazz) {
if(Customer.class == clazz) {
return jc;
}
return null;
}
}
详细示例
【讨论】: