JAXB 用于自然返回 JSON 或 XML 的列表

2023-11-21

我使用 MOXy 和 Jersey 来实现 RESTful API,并希望自然地返回 JSON 和 XML 的列表,这意味着 XML 包含整个集合以及集合项的元素标签,而 JSON 包含仅用于收藏的标签。

例如,我想返回带有嵌套的设施和位置列表的“组织”资源。作为 XML:

<organisation>
  <id>1</id>
  <name>XYZ</name>
  <facilities>
    <facility>
      <id>1</id>
      <text>Telephone</text>
    </facility>
    <facility>
      <id>3</id>
      <text>Whiteboard</text>
    </facility>
  </facilities>
  <locations>
    <location>
      <id>1</id>
      <kind>REGION</kind>
      <name>London</name>
    </location>
    <location>
      <id>2</id>
      <kind>REGION</kind>
      <name>Manchester</name>
    </location>
  </locations>
</organisation>

作为 JSON:

{
  "id": 1,
  "name": "XYZ",
  "facilities": [
    {
      "id": 1,
      "text": "Telephone"
    },
    {
      "id": 3,
      "text": "Whiteboard"
    }
  ],
  "locations": [
    {
      "id": 1,
      "kind": "REGION",
      "name": "London"
    },
    {
      "id": 2,
      "kind": "REGION",
      "name": "Manchester"
    }
  ]
}

不幸的是,我似乎无法获得允许我返回 XML 和 JSON 输出的代码库。如果我使用类来包装嵌套列表,则 XML 显示正确,但 JSON 显示不正确(请参阅下面的“ExternalFacilities”)。如果我将嵌套列表定义为ArrayList子类,则 JSON 显示正确,但 XML 不正确(请参阅下面的“ExternalLocations”)。

XML 示例显示“设施”列表正确,但“位置”列表不正确

请注意,没有包含“位置”列表的 XML 元素(与“设施”列表一样),并且每个位置都有一个复数元素名称。

<organisation>
  <id>1</id>
  <name>XYZ</name>
  <facilities>
    <facility>
      <id>1</id>
      <text>Telephone</text>
    </facility>
    <facility>
        <id>3</id>
        <text>Whiteboard</text>
    </facility>
  </facilities>
  <locations>
    <id>1</id>
    <kind>REGION</kind>
    <name>London</name>
  </locations>
  <locations>
    <id>2</id>
    <kind>REGION</kind>
    <name>Manchester</name>
  </locations>
</organisation>

JSON 示例显示“位置”列表正确,但“设施”列表不正确

请注意,“设施”列表是一个包含 JSON 数组的 JSON 对象,而我只需要 JSON 数组(具有复数元素名称)。

{
  "id": 1,
  "name": "XYZ",
  "facilities": {
    "facility": [
        {
            "id": 1,
            "text": "Telephone"
        },
        {
            "id": 3,
            "text": "Whiteboard"
        }
    ]
  },
  "locations": [
    {
      "id": 1,
      "kind": "REGION",
      "name": "London"
    },
    {
      "id": 2,
      "kind": "REGION",
      "name": "Manchester"
    }
  ]
}

上面的示例是使用相同的代码生成的,只是更改 Accept HTTP 标头以使 Jersey 返回 JSON 而不是 XML。以下是课程摘录:

外部组织.java

@XmlRootElement(name="organisation")
@XmlAccessorType(XmlAccessType.FIELD)
public class ExternalOrganisation {

   private String             name;
   private ExternalFacilities facilities;
   private ExternalLocations  locations;

   ...

}

外部设施.java

@XmlRootElement(name="facilities")
public class ExternalFacilities {
  @XmlElementRef
  private List<ExternalFacility> list;
  ...
}

外部位置.java

@XmlRootElement(name="locations")
public class ExternalLocations extends ArrayList<ExternalLocation> {
  ...
}

外部设施.java

@XmlRootElement(name="facility")
@XmlType(propOrder={"id", "uri", "kind", "text"})
public class ExternalFacility extends ExternalBase {
    // id inherited
    private String text;
    ....
}

外部位置.java

@XmlRootElement(name="location")
@XmlType(propOrder={"id", "kind", "name"})
public class ExternalLocation extends ExternalBase {
    // id inherited
    @XmlElement private LocationKind kind;
    @XmlElement private String       name;
    ...
}

乍一看类似于这个问题但我并不想混合列表中的对象类型。


您可以执行以下操作来获取所需的 XML 和 JSON 表示形式:

步骤#1 - 杠杆@XMLElementWrapper

代替:

@XmlRootElement(name="organisation")
@XmlAccessorType(XmlAccessType.FIELD)
public class ExternalOrganisation {

   private String             name;
   private ExternalFacilities facilities;
   private ExternalLocations  locations;

   ...

}

您可以执行以下操作@XmlElementWrapper (see: http://blog.bdoughan.com/2010/09/jaxb-collection-properties.html):

@XmlRootElement(name="organisation")
@XmlAccessorType(XmlAccessType.FIELD)
public class ExternalOrganisation {

   private String             name;

   @XmlElementWrapper
   @XmlElementRef
   private List<ExternalFacility> facilities;

   @XmlElementWrapper
   @XmlElementRef
   private List<ExternalLocation>  locations;

   ...

}

步骤 #2 - 利用 MOXy 的包装器作为数组名称属性

通过将包装器指定为数组名称属性,MOXy 将使用来自@XmlElementWrapper作为 JSON 数组名称。

import java.util.*;
import javax.ws.rs.core.Application;
import org.eclipse.persistence.jaxb.rs.MOXyJsonProvider;

public class YourApplication  extends Application {

    @Override
    public Set<Class<?>> getClasses() {
        HashSet<Class<?>> set = new HashSet<Class<?>>(1);
        set.add(YourService.class);
        return set;
    }

    @Override
    public Set<Object> getSingletons() {
        MOXyJsonProvider moxyJsonProvider = new MOXyJsonProvider();
        moxyJsonProvider.setWrapperAsArrayName(true);

        HashSet<Object> set = new HashSet<Object>(1);
        set.add(moxyJsonProvider);
        return set;
    }

} 

了解更多信息

  • http://blog.bdoughan.com/2013/03/binding-to-json-xml-handling-collections.html
  • http://blog.bdoughan.com/2013/06/moxy-is-new-default-json-binding.html
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

JAXB 用于自然返回 JSON 或 XML 的列表 的相关文章

随机推荐

  • 如何判断一棵二叉树是否完整?

    完全二叉树被定义为其中每个级别 可能除了最深的级别 都被完全填充的二叉树 在最深层 所有节点必须尽可能位于左侧 我认为一个简单的递归算法将能够判断给定的二叉树是否完整 但我似乎无法弄清楚 如同 height t if t NULL then
  • 从关系中选择最常见的值 - SQL 语句

    我的数据库中有一个表 其中包含许多记录 某些记录的其中一列共享相同的值 例如 id name software 1 john photoshop 2 paul photoshop 3 gary textmate 4 ade firework
  • 从 Google App Engine 导出/导入数据存储

    我想将 App Engine 中运行的数据存储导出到应用程序的本地 独立 版本中 有人知道我该怎么做吗 我一直在 App Engine 仪表板中查找 但找不到它 查看文档上传和下载数据
  • 如何通过 RDP 连接到我的 Azure 云服务? [关闭]

    Closed 这个问题不符合堆栈溢出指南 目前不接受答案 正如我所读到的 每个 Azure 云服务背后都有一个虚拟机 对吗 我知道 对于虚拟机 我可以单击 连接 按钮来获取 rdp 文件以进行远程登录 但是 对于我的云服务 正在运行 连接
  • Firebase 存储对象的下载 URL 是否永久存在?

    当您将文件上传到 Firebase 的存储然后询问对象 URL 时 您会得到一个可公开访问的 URL 例如http firebasestorage googleapis com v0 b appname o filename alt med
  • Android:在哪里可以找到 RadioButton Drawable?

    好的 我正在尝试创建一个名为的自定义视图CheckedRelativeLayout 它的目的与CheckedTextView 以便能够在您想要选择的项目列表中或在Spinner 现在一切正常 我延长了RelativeLayout并实施了Ch
  • 是否可以代表用户在我的网站上禁用第三方 cookie?

    我有一个从另一个网站加载资源的网站 我已经能够确定 第三方网站在用户的浏览器上放置cookie 如果我在浏览器设置中禁用第三方 Cookie 则第三方网站将无法再在浏览器上放置 Cookie 该资源仍然可以正常工作 我想知道我是否可以从我的
  • 内核崩溃后获取 Linux 内核调试信息

    有没有办法在内核崩溃发生后获取内核以前的调试信息 我正在尝试开发一个内核模块 它基本上捕获内核网络堆栈内IP层中的IP数据包 经过一些修改后 我必须将相同的数据包发送回NIC进行传输 在所有这些过程中 我在以下的帮助下编写调试信息print
  • 在div中隐藏滚动条

    有没有办法使用CSS隐藏滚动条同时仍保留其功能 甚至使其透明或与背景颜色相同也可以 我必须在 JavaScript 中执行此操作吗 className overflow auto overflow y hidden 我相信用户必须使用鼠标滚
  • 当绑定的列表视图没有项目时显示一些文本

    以下是我的列表视图的语法 它绑定到一个类
  • 在 FreeAndNil 之后使用对象时会发生什么?

    在我的Delphi7中这段代码 var MStr TMemoryStream FreeAndNil MStr MStr Size 0 生成 AV 模块 Project1 exe 中地址 0041D6D1 处的访问冲突 读取地址 000000
  • HttpListener 服务器标头 c#

    我正在尝试为个人项目编写一个 C http 服务器 我想知道如何将返回的服务器标头从 Microsoft HTTPAPI 2 0 更改为其他内容 public class HttpWebServer private HttpListener
  • 使用单击一次部署时出现安装问题

    我有一个 Wpf 应用程序 我希望将其部署在远程服务器上 以前我使用 VS2010 因此创建 setup msi 文件并部署到其他计算机上会很容易 目前我有VS2012 它没有设置部署选项 另外 我还阅读了有关 clickonce 应用程序
  • 如何在iOs中将UITabbarController添加到UIViewController

    如何用TabbarController推送Viewcontroller 在Viewcontroller XIB中 我创建了UITabbarController 然后我推送这个ViewController 但它没有出现UITabbarCont
  • 在 Java 中转义 SQL 字符串

    背景 我目前正在为企业 CMS 数据库 业务对象 开发 Java 前端 目前 我正在构建一个功能来允许用户构建自定义数据库查询 我已经实施了措施 以确保用户只能使用已批准用户访问的可用列和运算符的子集进行选择 例如 可以选择 SI EMAI
  • 将 string 转换为 int 而不丢失开头的零

    I tried int parse 和convert class 将字符串转换为int 当我正在转换时 我一开始就失去了 0 这是我不想要的 例如 09999 变成 9999 我不想要这个 我想保持原样 我怎样才能做到这一点 myNumbe
  • 任何编程语言中的变量名是否占用内存空间

    e g int a 3 1 and int a long variable name used instead of small one 3 2 1 和 2 哪一个将获得更多的内存空间或将获得相等的空间 在 C 和大多数静态编译语言中 变量
  • CollapsingToolBarLayout 与 TabLayout 和 ViewPager

    我尝试使用 CordinatorLayout 和 CollapsingToolbarLayout TabLayout 和 ViewPager 创建类似于图像中的布局 我的布局无法正确呈现 这是我的布局
  • 无法加载此类文件——rack/handler/puma

    我的设置和错误 当我使用rackup 和puma 启动Sinatra 应用程序时出现错误 我的config ru文件看起来像这样 s puma require controller main rb run Sinatra Applicati
  • JAXB 用于自然返回 JSON 或 XML 的列表

    我使用 MOXy 和 Jersey 来实现 RESTful API 并希望自然地返回 JSON 和 XML 的列表 这意味着 XML 包含整个集合以及集合项的元素标签 而 JSON 包含仅用于收藏的标签 例如 我想返回带有嵌套的设施和位置列