JSON输出包含星号而不是值

时间:2019-09-02 09:11:14

标签: java json jackson osgi

当我使用com.fasterxml.jackson.databind.ObjectMapper.writeValueAsString(payload)从对象获取json字符串时,我发现某些字段带有星号而不是值。像这样:

{
    "id": "25495867-1404-412d-9488-ce495bd468de",
    "createdDate": "2019-09-01T22:27:46.000Z",
    "updatedDate": "2019-09-01T22:27:46.000Z",
    "externalKey": "testhc1",
    "email": **********************,
    "name": ************,
    "currency": "NZD"
}

emailname在我的有效负载对象中都具有值,并且我看不到字段的任何奇怪之处。但是显然jackson代码可以。不仅会掩盖值,而且生成的星号也不会用引号引起来,因此对于成功解析此过程的另一端来说,它们不是有效的json

有人知道是什么触发了这种行为吗?我花了整整一天时间在看代码,却什么也没找到。有效负载对象没有注释,但是我尝试了其他可以正常工作的未注释对象。


编辑1029/09/03 我正在编写的代码是Killbill的插件,在该环境之外运行时,其行为似乎有所不同。我写了一个小测试:

UUID accountId = UUID.fromString("25495867-1404-412d-9488-ce495bd468de");
DefaultAccount account = new DefaultAccount(
        accountId, "external", "abc@gmail.com",
        "fred smith", 4, Currency.NZD, null, false, 
        20, null, new DateTime(), DateTimeZone.UTC,
        Locale.getDefault().toString(), "addr1", 
        "addr2", "companyName", "city",
        "stateOrProvince", "country", 
        "postalCode", "phone", "notes", false);
try {
    String json = invoiceNotificationHttpClient.getMapper().writeValueAsString(account);
    logger.info("testMapper: {} " ,json);
} catch (JsonProcessingException e) {
    logger.error(e.getMessage(),e);
}

直接运行测试的结果(即在KillBill外部)给了我期望的结果,即

{
    "id": "25495867-1404-412d-9488-ce495bd468de",
    "externalKey": "external",
    "email": "abc@gmail.com",
    "name": "fred smith",
    "firstNameLength": 4,
    "currency": "NZD",
...
}

我得到了这个确切的代码并将其粘贴到我的插件中。您可以看到我只是实例化一个类并在其上运行映射器。作为插件运行时,结果是这样的:

{
    "id": "25495867-1404-412d-9488-ce495bd468de",
    "externalKey": "external",
    "email": ***************,
    "name": ************,
    "firstNameLength": 4,
    "currency": "NZD",
...
}

有我的星号。所以它不是类本身,看起来可能是映射器。所以我看了一下。

映射器确实来自框架,但是我有这个来源。我扩展给定的类org.killbill.billing.plugin.util.http.HttpClient以产生我的InvoiceNotificationHttpClient。所以在我的课上有一个方法:

    protected ObjectMapper createObjectMapper() {
        return super
                .createObjectMapper()
                .registerModule(new JodaModule())
                .disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
    }   

这正在调用超类,并添加了我需要的Joda。在超类中:

    protected ObjectMapper createObjectMapper() {
        final ObjectMapper mapper = new ObjectMapper();

        // Tells the serializer to only include those parameters that are not null
        mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);

        // Allow special characters
        mapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_CONTROL_CHARS, true);

        // Write dates using a ISO-8601 compliant notation
        mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);

        return mapper;
    }

这对我来说似乎很高兴。无论如何,它应该与我独立运行时的一样。


再次编辑2019-09-03

当我作为插件运行时,我开始认为我必须使用另一个ObjectMapper。我将上述ObjectMapper的实例化和配置移到了插件中自己的方法中,并尝试将其作为测试。同样的技术仍然可以很好地独立运行,并且在插件中不起作用。因此,new ObjectMapper()在这些环境下似乎给了我一些不同的东西。现在这可能是一个OSGi问题。我将更新标签。

1 个答案:

答案 0 :(得分:0)

这是一条完整的红色鲱鱼,但我会发布答案以防万一。星号不是由杰克逊ObjectMapper中的任何异常引起的。它们也不是由OSGi配置中任何奇怪的类路径问题引起的。我花了很长时间寻找那些问题,却一无所获。

它们是由conversionRule配置中的logback引起的,该配置旨在掩盖那些特定字段以免出现在日志中。这是一个合理的要求,但是我不知道要嵌入OSGi插件的服务器正在执行此操作。事实证明,当我关闭该转换时,这些字段就很好了。当我运行桌面测试时,他们有一个更简单的logback配置,其中没有包含conversionRule,因此它从未出现在此处。