首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何将JAXB对象列表的序列化定制为JSON?

如何将JAXB对象列表的序列化定制为JSON?
EN

Stack Overflow用户
提问于 2010-02-04 20:06:59
回答 1查看 51.5K关注 0票数 55

我正在使用Jersey为服务器组件创建一个REST web服务。

我希望在列表中序列化的带JAXB注释的对象如下所示:

代码语言:javascript
复制
@XmlRootElement(name = "distribution")
@XmlType(name = "tDistribution", propOrder = {
    "id", "name"
})
public class XMLDistribution {
    private String id;
    private String name;
    // no-args constructor, getters, setters, etc
}

我有一个REST资源来检索一个发行版,如下所示:

代码语言:javascript
复制
@Path("/distribution/{id: [1-9][0-9]*}")
public class RESTDistribution {
    @GET
    @Produces("application/json")
    public XMLDistribution retrieve(@PathParam("id") String id) {
        return retrieveDistribution(Long.parseLong(id));
    }
    // business logic (retrieveDistribution(long))
}

我还有一个REST资源来检索所有发行版的列表,如下所示:

代码语言:javascript
复制
@Path("/distributions")
public class RESTDistributions {
    @GET
    @Produces("application/json")
    public List<XMLDistribution> retrieveAll() {
        return retrieveDistributions();
    }
    // business logic (retrieveDistributions())
}

我使用ContextResolver来自定义JAXB序列化,目前的配置如下:

代码语言:javascript
复制
@Provider
@Produces("application/json")
public class JAXBJSONContextResolver implements ContextResolver<JAXBContext> {
    private JAXBContext context;
    public JAXBJSONContextResolver() throws Exception {
        JSONConfiguration.MappedBuilder b = JSONConfiguration.mapped();
        b.nonStrings("id");
        b.rootUnwrapping(true);
        b.arrays("distribution");
        context = new JSONJAXBContext(b.build(), XMLDistribution.class);
    }
    @Override
    public JAXBContext getContext(Class<?> objectType) {
        return context;
    }
}

REST资源和上下文解析器都可以工作。这是第一个输出的示例:

代码语言:javascript
复制
// path: /distribution/1
{
  "id": 1,
  "name": "Example Distribution"
}

这正是我想要的。以下是该列表的输出示例:

代码语言:javascript
复制
// path: /distributions
{
  "distribution": [{
    "id": 1,
    "name": "Sample Distribution 1"
  }, {
    "id": 2,
    "name": "Sample Distribution 2"
  }]
}

但这并不是我想要的。

我不明白为什么会有一个封闭的distribution标签。我想在上下文解析器中使用.rootUnwrapping(true)删除它,但显然这只删除了另一个封闭标记。这是.rootUnwrapping(false)的输出

代码语言:javascript
复制
// path: /distribution/1
{
  "distribution": {
    "id": 1,
    "name": "Example Distribution"
  }
} // not ok
// path: /distributions
{
  "xMLDistributions": {
    "distribution": [{
      "id": 1,
      "name": "Sample Distribution 1"
    }, {
      "id": 2,
      "name": "Sample Distribution 2"
    }]
  }
}

我还必须将.arrays("distribution")配置为始终获得一个JSON数组,即使只有一个元素。

理想情况下,我希望将以下内容作为输出:

代码语言:javascript
复制
// path: /distribution/1
{
  "id": 1,
  "name": "Example Distribution"
} // currently works
// path: /distributions
[{
  "id": 1,
  "name": "Sample Distribution 1"
}, {
  "id": 2,
  "name": "Sample Distribution 2"
}]

我试图返回一个List<XMLDistribution>、一个XMLDistributionList (列表的包装器)、一个XMLDistribution[],但是我找不到一种方法来以我需要的格式获得一个简单的JSON数组。

我还尝试了JSONConfiguration.natural()JSONConfiguration.mappedJettison()等返回的其他符号,但无法得到任何与我需要的内容相似的内容。

有没有人知道是否可以配置JAXB来做这件事?

EN

回答 1

Stack Overflow用户

发布于 2013-04-16 04:43:57

Jonhatan的答案很棒,对我非常有用。

这只是一个升级:

如果您使用的是杰克逊的2.x版(例如2.1版),则类为com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider,,因此web.xml为:

代码语言:javascript
复制
<init-param>
  <param-name>com.sun.jersey.config.property.packages</param-name>
  <param-value>your.project.packages;com.fasterxml.jackson.jaxrs.json</param-value>
</init-param>
票数 13
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2199453

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档