我有这个@XmlRootElement 类人。
@XmlRootElement
class Person {
private String desc;
}
并且返回内容是
{"Person": {"desc": "abc"} }
而且我真的不想要根包装器,所以我希望内容看起来像
{"desc": "abc"}
我可以通过 JaxB 完成此操作吗?如果是这样,怎么做?谢谢!
我有这个@XmlRootElement 类人。
@XmlRootElement
class Person {
private String desc;
}
并且返回内容是
{"Person": {"desc": "abc"} }
而且我真的不想要根包装器,所以我希望内容看起来像
{"desc": "abc"}
我可以通过 JaxB 完成此操作吗?如果是这样,怎么做?谢谢!
注意: 我是EclipseLink JAXB (MOXy)负责人,也是JAXB (JSR-222)专家组的成员。
正如esseplymale JAXB (JSR-222) 所回答的那样,涵盖了 XML 而非 JSON 绑定。然而,JAXB 经常被直接使用(一个 JAXB impl 与 Jettison 之类的东西一起用于将 JSON 转换为 StAX 事件/从 StAX 事件转换,请参阅: http://blog.bdoughan.com/2011/04/jaxb-and-json-via-jettison。 html)和间接(解释 JAXB 注释子集的 JSON 绑定实现)在此空间中。
下面是您如何通过利用 EclipseLink MOXy 作为您的 JAXB 提供者来完成您的用例。
人
以下是Person
您问题中的课程。我添加了@XmlAccessorType(XmlAccessType.FIELD)
注释,这样我就可以避免添加访问器方法(参见: http ://blog.bdoughan.com/2011/06/using-jaxbs-xmlaccessortype-to.html )。
import javax.xml.bind.annotation.*;
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
class Person {
private String desc;
}
jaxb.properties
您使用 MOXy 作为您的 JAXB 提供程序,您需要包含一个jaxb.properties
在与域模型相同的包中调用的文件,其中包含以下条目(请参阅:http ://blog.bdoughan.com/2011/05/specifying-eclipselink-moxy-as -your.html )。
javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory
演示
演示代码中有几点需要注意:
JAXBContextProperties.MEDIA_TYPE
属性用于将 MOXy 置于 JSON 绑定模式。JAXBContextProperties.JSON_INCLUDE_ROOT
属性用于告诉 MOXy 省略根元素。unmarshal
当根元素被省略时,您需要通过使用带Class
参数的方法之一告诉 MOXy 您正在解组的类型。import java.util.*;
import javax.xml.bind.*;
import javax.xml.transform.stream.StreamSource;
import org.eclipse.persistence.jaxb.JAXBContextProperties;
public class Demo {
public static void main(String[] args) throws Exception {
Map<String, Object> properties = new HashMap<String, Object>(2);
properties.put(JAXBContextProperties.MEDIA_TYPE, "application/json");
properties.put(JAXBContextProperties.JSON_INCLUDE_ROOT, false);
JAXBContext jc = JAXBContext.newInstance(new Class[] {Person.class}, properties);
Unmarshaller unmarshaller = jc.createUnmarshaller();
StreamSource json = new StreamSource("src/forum18417466/input.json");
Person person = unmarshaller.unmarshal(json, Person.class).getValue();
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(person, System.out);
}
}
输入.json/输出
{
"desc" : "abc"
}
JAXB 是 XML 的 API,而不是 JSON。
但是,有一些 JSON 库(至少是 Jackson)可以利用 JAXB 注释。我不知道您使用的是哪一个,所以我不知道如何最好地提供帮助。(如果您将它与 Jersey 框架一起使用,它将使用 Jackson 进行 JSON 序列化。)您将需要配置您正在使用的任何 JSON 库,以便能够配置 JSON 输出中根元素的“包装”。
我编写了这个快速的 Groovy 脚本来在 Jackson 中进行测试:
@Grab('com.fasterxml.jackson.core:jackson-databind:2.2.2')
import javax.xml.bind.annotation.XmlRootElement
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.databind.SerializationFeature
@XmlRootElement
public class Person {
public String desc = "howdy"
}
Person p = new Person()
ObjectMapper om = new ObjectMapper().enable(SerializationFeature.WRAP_ROOT_VALUE)
println om.writeValueAsString(p)
如上所述,它输出 JSON:
{"Person":{"desc":"howdy"}}
如果你拿出.enable(SerializationFeature.WRAP_ROOT_VALUE)
它给你的部分:
{"desc":"howdy"}
因此,如果您使用的是 Jackson,那么在幕后使用的 ObjectMapper 似乎已设置为WRAP_ROOT_VALUE
,您只需将其关闭即可。