6

我有这个@XmlRootElement 类人。

    @XmlRootElement
    class Person {
        private String desc;
    }

并且返回内容是

    {"Person": {"desc": "abc"} }

而且我真的不想要根包装器,所以我希望内容看起来像

    {"desc": "abc"}

我可以通过 JaxB 完成此操作吗?如果是这样,怎么做?谢谢!

4

2 回答 2

4

注意: 我是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 提供者来完成您的用例。

Java 模型

以下是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

演示代码

演示

演示代码中有几点需要注意:

  1. JAXBContextProperties.MEDIA_TYPE属性用于将 MOXy 置于 JSON 绑定模式。
  2. JAXBContextProperties.JSON_INCLUDE_ROOT属性用于告诉 MOXy 省略根元素。
  3. 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"
}
于 2013-08-26T13:14:56.130 回答
3

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,您只需将其关闭即可。

于 2013-08-24T17:34:55.467 回答