java - 将 JSON 反序列化为类实例
问题描述
我有一个通过 RabbitMQ 作为消息发送的类,在发件人服务上,它的定义如下:
public final class User implements Serializable {
private String nome;
private String cognome;
public User(@JsonProperty("nome") String nome,
@JsonProperty("cognome") String cognome) {
this.nome = nome;
this.cognome = cognome;
}
public String getNome() {
return nome;
}
public String getCognome() {
return cognome;
}
public User(){}
}
在接收器服务上:
@Document
public class Persona {
@Id
@JsonProperty
public ObjectId id;
private String nome;
private String cognome;
public String getId() {
return id.toHexString();
}
public void setId(ObjectId id) {
this.id = id;
}
public String getNome() {
return nome;
}
public void setNome(String nome) {
this.nome = nome;
}
public String getCognome() {
return cognome;
}
public void setCognome(String cognome) {
this.cognome = cognome;
}
public Persona(ObjectId id, String nome, String cognome) {
this.id = id;
this.nome = nome;
this.cognome = cognome;
}
public Persona(){}
}
在接收器控制器中,我有以下方法,它应该接收该消息,将其转换为一个对象,并将其保存在数据库中,它看起来像:
@RabbitListener(queues = {"default_parser_q"})
public void receiveMessage(final Message message){
ObjectMapper mapper = new ObjectMapper()
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
.configure(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES, false);
mapper.readValue(message.getBody(), Persona.class);
System.out.println(message.toString() + "the message has been received");
}
问题是我在该readValue()
方法上遇到了异常,特别是:
未处理的异常:java.io.IOException、com.fasterxml.jackson.core.JsonParseException、com.fasterxml.jackson.databind.JsonMappingException
在这种情况下发送的消息(JSON)是:
{
'nome': "John",
'cognome': "Doe"
}
我在这里做错了什么?
编辑:根据要求添加堆栈跟踪。
com.fasterxml.jackson.databind.exc.MismatchedInputException:无法构造实例
demo.com.fetcherservice.models.Persona
(although at least one Creator exists): no String-argument constructor/factory method to deserialize from String value ('{ "nome": "John", "cognome": "Doe" }') at [Source: (byte[])""{\n\t\t\t\"nome\": \"John\",\n\t\t\t\"cognome\": \"Doe\"\n\t\t}""; line: 1, column: 1] at com.fasterxml.jackson.databind.exc.MismatchedInputException.from(MismatchedInputException.java:63) at com.fasterxml.jackson.databind.DeserializationContext.reportInputMismatch(DeserializationContext.java:1343) at com.fasterxml.jackson.databind.DeserializationContext.handleMissingInstantiator(DeserializationContext.java:1032) at com.fasterxml.jackson.databind.deser.ValueInstantiator._createFromStringFallbacks(ValueInstantiator.java:371) at com.fasterxml.jackson.databind.deser.std.StdValueInstantiator.createFromString(StdValueInstantiator.java:323) at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromString(BeanDeserializerBase.java:1373) at com.fasterxml.jackson.databind.deser.BeanDeserializer._deserializeOther(BeanDeserializer.java:171) at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:161) at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4013) at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3091) at kdmforce.com.fetcherservice.services.FetcherService.receiveMessage(FetcherService.java:23) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.springframework.messaging.handler.invocation.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:171) at org.springframework.messaging.handler.invocation.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:120) at org.springframework.amqp.rabbit.listener.adapter.HandlerAdapter.invoke(HandlerAdapter.java:50) at org.springframework.amqp.rabbit.listener.adapter.MessagingMessageListenerAdapter.invokeHandler(MessagingMessageListenerAdapter.java:196) at org.springframework.amqp.rabbit.listener.adapter.MessagingMessageListenerAdapter.onMessage(MessagingMessageListenerAdapter.java:129) at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:1552) at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.actualInvokeListener(AbstractMessageListenerContainer.java:1478) at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:1466) at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.doExecuteListener(AbstractMessageListenerContainer.java:1461) at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.executeListener(AbstractMessageListenerContainer.java:1410) at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.doReceiveAndExecute(SimpleMessageListenerContainer.java:870) at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.receiveAndExecute(SimpleMessageListenerContainer.java:854) at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.access$1600(SimpleMessageListenerContainer.java:78) at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.mainLoop(SimpleMessageListenerContainer.java:1137) at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.run(SimpleMessageListenerContainer.java:1043) at java.lang.Thread.run(Thread.java:748) com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance ofdemo.com.fetcherservice.models.Persona
(尽管至少存在一个 Creator):在 [Source: (byte[ ])""{\n\t\t\t\"nome\": \"John\",\n\t\t\t\"cognome\": \"Doe\"\n\t\t }""; line: 1, column: 1] at com.fasterxml.jackson.databind.exc.MismatchedInputException.from(MismatchedInputException.java:63) at com.fasterxml.jackson.databind.DeserializationContext.reportInputMismatch(DeserializationContext.java:1343) at com .fasterxml.jackson.databind.DeserializationContext.handleMissingInstantiator(DeserializationContext.java:1032) 在 com.fasterxml.jackson.databind.deser。
解决方案
它看起来像我在 Kafka 中看到的行为,因为您也在使用 Spring,我认为它是相同的。
您的发送端将对象转换为 Json,然后将其作为字符串发送 - 因此错误消息 ( \"nome\": \"John\",\n\t\t\t\"cognome\": \"Doe\"
) 中的转义引号。
您需要在发送方声明 JsonSerializer 然后将其传递给您的User
, 或者 - 如果您手动创建 Json 字符串 - 声明它是一个字节数组,因此 Spring 不会尝试转义引号和空格。