JAXB / Jersey如何解组布尔值?

时间:2013-09-09 12:52:43

标签: glassfish jersey jaxb2 glassfish-4

我遇到一些RESTful服务的问题,这些服务在参数中采用传输对象(基本上是一个将被解组为POJO的XML对象)。

@XmlRootElement(name = "myPojo")
public class MyPojo {
    @XmlElement(name = "myField")
    private Boolean myBoolean;

    public void setMyBoolean(Boolean bool) {
        myBoolean = bool;
    }

    public Boolean getMyBoolean()  {
        return myBoolean;
    }
}

服务是这样的:

public class MyRestService {

    @PUT
    @Path("somewhere")
    @Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
    @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
    public Response update(MyPojo pojo) {
        System.out.println("Boolean value: " + pojo.getMyBoolean();
    }
}

如果我发布此XML片段:

<myPojo>
    <myField>false</myField>
</myPojo>

我得到了:

Boolean value: false

如果我发布这个XML片段:

<myPojo>
    <myField>FALSE</myField>
</myPojo>

我得到了:

Boolean value: null

我使用Jersey 1.9.1和JAXB 2.2.7在Glassfish 4下运行该代码。此外,在Glassfish 2下,我得到了一个不同的行为,其中大写和小写都按预期解组。

所以,我真的很想知道发生了什么以及为什么布尔的编组不同。

提前致谢

2 个答案:

答案 0 :(得分:2)

我今天遇到了同样的问题,当解析&#34; FaLsE&#34;时,JAXB返回null。或&#34; True&#34;在布尔字段上。不幸的是,升级到2.2.7或更高版本(截至今天的2.2.11)并没有帮助我。当我深入研究源代码时,似乎解析逻辑发生在DatatypeConverterImpl.java中。并且没有可以改变其大写行为的配置。

Link to JAXB DatatypeConverterImpl.java

我找到(并且有效)的解决方案是定义一个新的BooleanAdapter并要求JAXB使用它。在适配器中,您可以定义适合您的应用程序的任何转换逻辑。

自定义BooleanAdapter.java

public class BooleanAdapter extends XmlAdapter<String, Boolean> {

    @Override
    public Boolean unmarshal(String v) throws Exception {
        if (StringUtils.isBlank(v))
            return null;
        return Boolean.valueOf(v);
    }

    @Override
    public String marshal(Boolean v) throws Exception {
        if (v == null)
            return null;
        return v.toString();
    }
}

您的模型对象

@XmlElement(name = "myField")
@XmlJavaTypeAdapter(BooleanAdapter.class)
public Boolean getMyBoolean() {
    return myBoolean;
}

答案 1 :(得分:1)

经过多次调查后,我们发现我们使用的JAXB版本2.2似乎包含一个错误,它将布尔值序列化并不像预期的那样。我的意思是,例如:FaLsE将被转换为空值。

升级到2.2.7版已解决了我们的问题。