当值为 'true' 或 'false' 时,JSON 提供程序构建错误的字符串字段

标签 json rest jaxb cxf

我有一个问题。请你帮助我好吗。 我有一个应用程序:CXF+Spring+JAXB+REST。我尝试使用 JSONProvider 类生成响应 有一个 bean 类:

@XmlRootElement
class Foo {
@XmlElement
private String bar;
}

当我设置字段值时:

setBar("true")

setBar("false");

JSONProvider 返回给我:

"bar":false

但是,我希望

"bar":"false"

因为我使用String类型。我该怎么办?

最佳答案

注意:我是EclipseLink JAXB (MOXy) JAXB (JSR-222) 的领导者和成员专家组。

JAXB (JSR-222) 规范不涵盖 JSON 绑定(bind)。在 REST/JAX-RS 上下文中,由提供者将 JAXB 映射规则应用到 JSON 表示。目前正在使用 3 种不同的方法:

  1. 将 JAXB 实现与类似 Jettison 的库结合使用。 Jettison 实现 StAX 接口(interface),但解释 JSON。这种方法的优点是它可以与任何 JAXB 实现一起使用来生成/使用 JSON,这种方法的缺点是 Jettison 没有足够的信息来进行完美的 JSON 表示。 Jettison 接收到 String "true" ,但不知道相应的 Java 类型是什么,因此它决定将其表示为 JSON bool 值,因为它可能是大多数时候所需的输出。
  2. REST/JAX-RS 实现利用特定的 JAXB 实现来生成 JSON。此方法与第一种方法类似,不同之处在于 REST/JAX-RS 提供程序对 JAXB 提供程序进行专有调用,以便对 JSON 表示形式做出更有根据的猜测。
  3. JAXB 实现提供 JSON 绑定(bind)实现。目前,EclipseLink MOXy 是唯一支持 JSON 绑定(bind)的 JAXB 实现。

MOXy 示例

下面是一个带有 Stringboolean 字段的域对象。我还添加了用 @XmlSchemaType 注释的字段,可用于覆盖默认表示形式。

package forum11145933;

import javax.xml.bind.annotation.*;

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Root {

    String barString;

    boolean barBoolean;

    @XmlSchemaType(name="boolean")
    String barStringWithXmlTypeBoolean;

    @XmlSchemaType(name="string")
    boolean barBooleanWithXmlTypeString;

}

jaxb.properties

要将 MOXy 指定为您的 JAXB 提供程序,您需要在与域模型相同的包中添加一个名为 jaxb.properties 的文件,其中包含以下条目:

javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory

演示

以下代码演示了如何将域对象编码(marshal)为 JSON。请注意,MOXy 不存在编译时依赖性。

package forum11145933;

import javax.xml.bind.*;

public class Demo {

    public static void main(String[] args) throws Exception {
        JAXBContext jc = JAXBContext.newInstance(Root.class);

        Root root = new Root();
        root.barString = "true";
        root.barBoolean = true;
        root.barStringWithXmlTypeBoolean = "true";
        root.barBooleanWithXmlTypeString = true;

        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.setProperty("eclipselink.media-type", "application/json");
        marshaller.marshal(root, System.out);
    }

}

输出

以下是运行演示代码的输出。请注意 booleanString 属性是如何正确写出的。另请注意,使用 @XmlSchemaType 注释使我们能够将 boolean 编码为 String,反之亦然。

{
   "root" : {
      "barString" : "true",
      "barBoolean" : true,
      "barStringWithXmlTypeBoolean" : true,
      "barBooleanWithXmlTypeString" : "true"
   }
}

MOXy 和 JAX-RS

MOXy 包含 MOXyJsonProvider,可用于在 JAX-RS 环境中启用 MOXy 作为 JSON 提供程序:

关于当值为 'true' 或 'false' 时,JSON 提供程序构建错误的字符串字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11145933/

相关文章:

php - 从 PHP/MySQL 自定义 JSON 数据的格式

c# - 如何使用 Litjson 解析 json 数组?

java - 为什么@RequestBody不需要arg构造函数?

java - JAXB:如何避免 xmlns:xsi 的重复命名空间定义

java - 包装 JAXBElement 实例的字符串

返回未定义的 JavaScript 对象

javascript - 如何从json中删除双引号

java javax.net.ssl.SSLHandshakeException : No subject alternative names present

web-services - REST:映射 404 HTTP 状态代码

java - JDK17 + Spring Boot Starter Web 服务 : Implementation of JAXB-API has not been found on module path or classpath