Java Jackson 解析异常 -(尽管至少存在一个 Creator):没有从字符串值反序列化的字符串参数构造函数/工厂方法
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/50831335/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Hymanson parsing exception -(although at least one Creator exists): no String-argument constructor/factory method to deserialize from String value
提问by SUMIT
- Spring Boot Version : 1.5.10
- Hymanson Version : 2.9.5
- Lombok Version : 1.18.0
- Spring Boot 版本:1.5.10
- Hyman逊版本:2.9.5
- 龙目岛版本:1.18.0
I have a scenario where I am sending payload using kafka. On receiving that payload, I am trying to assert whether both payload at receiver and sender end are same or not.
我有一个使用 kafka 发送有效负载的场景。在接收该有效载荷时,我试图断言接收方和发送方的有效载荷是否相同。
First I have created a class which will be passed as payload. Structure of the class is gievn below. Used lombok plugin version is 1.18.0.
首先,我创建了一个将作为有效负载传递的类。类的结构如下。使用的 lombok 插件版本是 1.18.0。
@Builder
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
public class MyDummyClass implements Serializable{
private static final long serialVersionUID = -4181985100899233094L;
private String data;
private String id;
}
For the above pojo I have created an unit test where I am passing a string and trying to convert that from String to object which is working without any issue.
对于上面的 pojo,我创建了一个单元测试,我在其中传递一个字符串并尝试将它从 String 转换为对象,该对象可以正常工作。
@Test
public void shouldBeAbleToConvertStringToDesiredObjectType() throws IOException {
String s = "{\r\n \"data\" : \"foo\",\r\n \"id\" : \"xyz\"\r\n}";
MyDummyClass myDummyClass = convertValue(s, MyDummyClass.class);
assertThat(myDummyClass.getData(), is("foo"));
}
Also Hymanson mapper configuration is given below below.
下面还给出了 Hymanson 映射器配置。
private static final ObjectMapper mapper = new ObjectMapper();
static {
mapper.configure(SerializationFeature.INDENT_OUTPUT, true);
mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
mapper.disable(FAIL_ON_UNKNOWN_PROPERTIES);
mapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
mapper.enable(ACCEPT_EMPTY_STRING_AS_NULL_OBJECT);
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
mapper.configure(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT, true);
mapper.setVisibility(PropertyAccessor.FIELD, Visibility.ANY);
// Skip the Null Values
mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
mapper.disableDefaultTyping();
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX"); //YYYY-MM-DDThh:mm:ss.sTZD (e.g. 1997-07-16T19:20:30.45.003+01:00)
dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
mapper.setDateFormat(dateFormat);
}
Now coming to main problem statement. So in my another test case where I am sending payload through kafka and after receiving the response from the kafka topic, I am trying to convert incoming Stringdata to the desired MyDummyClass class type. In my test case I have put logger statement to see what value I am receiving. I can see I am getting the exactly same string value mentioned in the above test case. But during parsing of that text to desired MyDummyClasstype I am getting error (although at least one Creator exists): no String-argument constructor/factory method to deserialize from String value.
现在进入主要问题陈述。因此,在我通过 kafka 发送有效负载的另一个测试用例中,在收到来自 kafka 主题的响应后,我尝试将传入的String数据转换为所需的MyDummyClass类类型。在我的测试用例中,我已经放置了 logger 语句来查看我收到的值。我可以看到我得到了上面测试用例中提到的完全相同的字符串值。但是在将该文本解析为所需的MyDummyClass类型期间,我收到错误(尽管至少存在一个 Creator):没有从字符串值反序列化的字符串参数构造函数/工厂方法。
@Test
public void messageWithAnyContractObjectCanBeConvertedToSameObjectAtTheListenerEnd() throws InterruptedException, IOException, JSONException {
String correlationID = UUID.randomUUID().toString();
String id = UUID.randomUUID().toString();
MyDummyClass actualPayload = MyDummyClass.builder().data("foo").id("xyz").build();
Message message = MessageBuilder.withAnyMessage()
.withNoHeader(BaseHeader.builder().ID(id).correlationID(correlationID).sendToDestination("my-topic").build())
.payload(actualPayload)
.build();
messagePublisher.publishMessage(message, DEFAULT_PUBLISHER_OPTIONS);
String recordedString = records.poll(10, TimeUnit.SECONDS).value();
LOGGER.info("Receiving Response {}", recordedString);
MyDummyClass recordedValue = convertValue(recordedString, MyDummyClass.class);
assertThat(recordedValue.getData(), is(actualPayload.getData()));
}
回答by SUMIT
Finally I was able to solve this problem. This issue was a result of wrong code written in side my publisher code where, first I was encrypting my payload by converting my entried payload as json object (using Hymanson), later I was again storing that json payload inside object with header and trying to convert that object into string(again using Hymanson converter). In this process, I was converting entire payload to string twice, as a result I was introducing extra \r\n
into my payload which I was sending through kafka. While converting back to object from json to object, this extra \r\n
was causing the problem what I pasted earlier.
最后我能够解决这个问题。这个问题是由于在我的发布者代码中编写了错误的代码,首先我通过将我输入的有效负载转换为 json 对象(使用 Hymanson)来加密我的有效负载,后来我再次将该 json 有效负载存储在带有标头的对象中并尝试将该对象转换为字符串(再次使用Hyman逊转换器)。在这个过程中,我将整个有效载荷转换为字符串两次,因此我在\r\n
我通过 kafka 发送的有效载荷中引入了额外的内容。在从 json 转换回对象到对象时,这个额外\r\n
的问题导致了我之前粘贴的问题。
As a solution, I have stored the already converted json object into another object with Hymanson annotation @JsonRawData. This prevent adding extra \r\n
.
作为解决方案,我已将已转换的 json 对象存储到另一个带有 Hymanson 注释@JsonRawData 的对象中。这可以防止添加额外的\r\n
.