我正在尝试集成Spring Cloud Streams,并使用RabbitMQ作为代理在服务之间发布自定义Java对象。我要发布的对象如下:
这只是一个包装对象,原始对象被放置在
请注意,
在消费者端,我收到了以下信息:
我尝试使用
在消息转换之前,我会记录它:
我尝试将
我尝试使用以下方式启用取消引用字段:
我尝试了这篇博客和一些类似的SO问题提供的解决方案,但都没有解决。我错过了什么吗?
public class AppMessageEnvelope implements Serializable {
...
private Object messageBody;
private Date sentAt = new Date();
...
// setters and getters
}
这只是一个包装对象,原始对象被放置在
messageBody
中。我放在messageBody
中的对象看起来像:public class Job {
...
private String message;
private Map<MyEnum, String> myMap;
...
}
请注意,
AppMessageEnvelope
和Job
都在一个不同的模型项目中,该项目作为Maven依赖项导入发布者和订阅者Spring Boot项目中,因此模型完全相同。
在生产者中,我将对象发布为:
@EnableBinding(Source.class)
public class JobDistributor {
private final Source jobQueue;
@Autowired
public JobDistributor(Source jobQueue) {
this.jobQueue = jobQueue;
}
public AppMessageEnvelope publishJob(AppMessageEnvelope message) {
LOG.info("Sending message: {}.", message);
jobQueue.output().send(MessageBuilder.withPayload(message).build());
return message;
}
}
在消费者端,我收到了以下信息:
@Component
@EnableBinding(Sink.class)
public class JobConsumer {
private final JobManager jobManager;
private final ObjectMapper objectMapper;
@Autowired
public JobConsumer(
JobManager jobManager, ObjectMapper objectMapper) {
this.jobManager = jobManager;
this.objectMapper = objectMapper;
}
@StreamListener(target = Sink.INPUT)
public void processData(AppMessageEnvelope messageEnvelope) {
LOG.info("Envelope received: {}.", messageEnvelope);
try {
TypeReference<Job> mapType = new TypeReference<Job>() {};
Job job = objectMapper.readValue(messageEnvelope.getMessageBody().toString(), mapType);
jobManager.processRequest(job);
} catch (Exception ex) {
LOG.error("Couldn't convert to correct object for processing: {}.", ex);
}
}
}
我尝试使用
TypeReference
将内部对象转换为正确的对象,但是我收到了以下错误提示:JobConsumer - Couldn't convert to correct object for processing: {}.
com.fasterxml.jackson.core.JsonParseException: Unexpected character ('i' (code 105)): was expecting double-quote to start field name
at [Source: (StringReader); line: 1, column: 3]
在消息转换之前,我会记录它:
JobConsumer - Envelope received: AppMessageEnvelope{..., messageBody={id=5bf3a7302dbe9c7cf9927c60, jobId=8c0bfcb0b21248e694b5cd52337a1f9e, submittedAt=2018-11-20T06:18:24+0000, lastUpdatedOn=null, message=null, ..., fileContentMap={FILE_BYTES=JVBERi0xLjUKJb/3ov}}, sentAt=Tue Nov 20 11:48:24 IST 2018}
我尝试将
ObjectMapper
配置为:@Autowired
private ObjectMapper objectMapper() {
JsonFactory factory = new JsonFactory();
factory.enable(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES);
return new ObjectMapper(factory);
}
我尝试使用以下方式启用取消引用字段:
objectMapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
我尝试了这篇博客和一些类似的SO问题提供的解决方案,但都没有解决。我错过了什么吗?
messageEnvelope.getMessageBody().toString()
和messageEnvelope.getMessageBody().getClass()
时,会打印什么内容? - JB NizetmessageEnvelope.getMessageBody().toString()
这里。你假设它会给出一个JSON字符串。(错误也指出了同样的问题,即JSON属性没有以")"开头)。你能打印这个值并验证一下吗? 此外,你可以使用ObjectMapper从messageEnvelope.getMessageBody()
获取一个JSON字符串,然后将其映射到所需的pojo上。 - RaRa