我们的系统利用Jackson(Java 11)对来自外部源的对象进行反序列化。当我们收到有效载荷时,它是字符串(UTF-8)格式。它无法反序列化并发生异常(MismatchedInputException)
无法构造“对象”的实例(尽管至少存在一个创建者):没有从字符串值反序列化的字符串参数构造函数/工厂方法('{
堆栈技术:
Java 11
杰克逊2.9.8
Google Cloud(平台)
我们最终使用了多个replaceAll语句,只是为了使有效负载处于允许将字符串转换为杰克逊对象的状态。代码真的很香...
我不确定这是否有帮助,但是有效负载是从Google PubSub Subscription提取的。所以我有一个消息接收者在订阅上监听。我最初使用Springs JacksonPubSubMessageConverter,但是抛出了上面的异常。我自己滚动,在下面添加了replaceAll(..),现在看来已经解决了问题。
public class ABCMessageReceiver implements MessageReceiver {
private PubsubMessageConverter converter;
public void receiveMessage(PubsubMessage message, AckReplyConsumer consumer) {
Person person = converter.fromPubSubMessage(message, Person.class);
...
}
}
payload = "{\n \"general\": {\n \"aggregatorId\": \"111111111111\",\n \"communityId\": \"30303030\",\n \"dateStamp\": \"2019-07-09\",\n \"comments\": \"Testing E2E1\"\n },\n \"prospect\": {\n \"firstName\": \"Joe\",\n \"lastName\": \"Smith\",\n \"nickName\": \"\",\n \"email\": \"joe.smith@sample.com\",\n \"gender\": \"MALE\",\n \"maritalStatus\": \"SINGLE\",\n \"dateOfBirth\": \"1956-06-15\",\n \"veteranStatus\": \"NOTAVETERAN\",\n \"address\": {\n \"address1\": \"100 Acme Street \",\n \"address2\": \"Suite 2300\",\n \"city\": \"Acme City\",\n \"state\": \"WI\",\n \"zip\": \"53214\"\n },\n \"phones\": [\n {\n \"number\": \"4145551212\",\n \"type\": \"WORK\"\n }\n ],\n \"financial\": {\n \"budgetAmount\": 2639,\n \"budgetFrequency\": \"MONTHLY\",\n \"medicaid\": true,\n \"medicare\": true,\n \"ltcPolicy\": false,\n \"homeowner\": true,\n \"vaAid\": false\n },\n \"prospectNeeds\": {\n \"desiredCareLevel\": \"AL\"\n }\n },\n \"tour\": {\n \"date\": \"2019-07-14T17:00:00.000Z\",\n \"notes\": \"Testing tour notes 1\"\n }\n}"
payload = payload.replaceAll("\\\\\"", "\"");
payload = payload.replaceAll("\\\\n", "");
payload = payload.substring(1);
payload = payload.substring(0, payload.length()-1);
我不喜欢开销字符串的替换,但是它似乎暂时可以使用,直到获得需要支持的另一个字符串置换为止。
最佳答案
我要感谢@Andreas和其他提供评论的人。起初,编码方面没有联系,第二天我不得不再谈。是的,如果生产者提交了格式正确的JSON,我会喜欢的。这是我为使其工作而要做的,不是最好的解决方案,但它可以工作。我扩展了JacksonPubSubMessageConverter.java并创建了一个新的未编码版本。
UnencodedJacksonPubSubMessageConverter.java
...
public <T> T fromPubSubMessage(PubsubMessage message, Class<T> payloadType) {
try {
String payload = message.getData().toStringUtf8();
payload = removeQuotesIfNecessary(unescapePayload(payload));
return (T) this.objectMapper.readerFor(payloadType).readValue(payload);
}
catch (IOException ex) {
throw new PubSubMessageConversionException("JSON deserialization of an object of type " + payloadType.getName() + " failed.", ex);
}
}
private String removeQuotesIfNecessary(String payload) {
if (payload != null && payload.startsWith("\"") && payload.endsWith("\"")) {
return payload.substring(1).substring(0, payload.length()-2);
}
return payload;
}
private String unescapePayload(String payload) {
if (payload != null)
return StringEscapeUtils.unescapeJson(payload);
return payload;
}