当我使用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"
}
email
和name
在我的有效负载对象中都具有值,并且我看不到字段的任何奇怪之处。但是显然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问题。我将更新标签。
答案 0 :(得分:0)
这是一条完整的红色鲱鱼,但我会发布答案以防万一。星号不是由杰克逊ObjectMapper
中的任何异常引起的。它们也不是由OSGi配置中任何奇怪的类路径问题引起的。我花了很长时间寻找那些问题,却一无所获。
它们是由conversionRule
配置中的logback
引起的,该配置旨在掩盖那些特定字段以免出现在日志中。这是一个合理的要求,但是我不知道要嵌入OSGi插件的服务器正在执行此操作。事实证明,当我关闭该转换时,这些字段就很好了。当我运行桌面测试时,他们有一个更简单的logback
配置,其中没有包含conversionRule
,因此它从未出现在此处。