![](/img/trans.png)
[英]java.lang.ClassCastException: class model - Error in springboot kafka integration while sending JSON object as message in topic
[英]Error while sending a JSON object as message on kafka
我是一名试图了解 apache kafka 的学生。 我正在尝试发送JSON 8828282995402888作为一条消息,使用Kafka在spring启动启动,使用java启动。但是,当我尝试发送我的888361616168888888888888888888888888888888888888888888888888888号8888888 88888888888888888882615705700.AST88888888号88888 8888888888888888882在 application.properties 文件中。 例外是:
java.lang.ClassCastException: class com.example.demo.model.BookES cannot be cast to class java.lang.String (com.example.demo.model.BookES is in unnamed module of loader 'app'; java.lang.String is in module java.base of loader 'bootstrap')
我的 application.properties 文件是
server.port=8081
spring.kafka.consumer.bootstrap-servers=localhost:9092
spring.kafka.consumer.group-id=myGroup
spring.kafka.consumer.auto-offset-reset=earliest
spring.kafka.consumer.key-deserializer=org.apache.kafka.common.serialization.StringDeserializer
spring.kafka.consumer.value-deserializer=org.springframework.kafka.support.serializer.JsonDeserializer
spring.kafka.producer.bootstrap-servers=localhost:9092
spring.kafka.producer.key-serializer=org.apache.common.serialization.StringSerializer
spring.kafka.producer.value-serializer=org.springframework.kafka.support.serializer.JsonSerializer
我的 controller class 我正在尝试发送消息
@PostMapping("/publish")
public ResponseEntity<String> publish(@RequestBody BookES bookES){
logger.info("in publish method");
kafkaProducer.sendMessage(bookES);
return ResponseEntity.ok("Json message sent to kafka topic");
}
我的 Kafka 生产者 class 具有 sendMessage 方法:
package com.example.demo.kafka;
import org.apache.kafka.clients.admin.NewTopic;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.kafka.support.KafkaHeaders;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.stereotype.Service;
import com.example.demo.controller.BookController;
import com.example.demo.model.Book;
import com.example.demo.model.BookES;
@Service
public class KafkaProducer {
@Autowired
private NewTopic topic;
Logger logger = LoggerFactory.getLogger(KafkaProducer.class);
private String topicName = "bookmanagement";
@Autowired
private KafkaTemplate<String, BookES> kafkaTemplate;
public void sendMessage(BookES bookES) {
logger.info("in sendMessage method");
logger.info(String.format("Message sent -> %s",bookES.toString()));
Message<BookES> message = MessageBuilder.withPayload(bookES).setHeader(KafkaHeaders.TOPIC, topic.name()).build();
kafkaTemplate.send(message);
}
}
我的 model class:
package com.example.demo.model;
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.Document;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@Document(indexName="my-application")
@Data
@AllArgsConstructor
@NoArgsConstructor
@Getter
@Setter
public class BookES{
@Override
public String toString() {
return "BookES [bookId=" + bookId + ", bookName=" + bookName + ", description=" + description + "]";
}
@Id
private String bookId;
private String bookName;
private String description;
public String getBookId() {
// TODO Auto-generated method stub
return this.bookId;
}
public String getBookName() {
return bookName;
}
public void setBookName(String bookName) {
this.bookName = bookName;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public void setBookId(String bookId) {
this.bookId = bookId;
}
}
我的项目在github链接: github链接
我尝试使用不同的注释(如@JsonSerializer 等)对我的 model class 进行注释,但没有成功。 我在 postman 上尝试发帖时得到的回复是:
{
"timestamp": "2022-11-22T11:24:30.738+00:00",
"status": 500,
"error": "Internal Server Error",
"message": "Can't convert value of class com.example.demo.model.BookES to class org.apache.kafka.common.serialization.StringSerializer specified in value.serializer",
"path": "/books/publish"
}
您需要提供自己的序列化程序,可以将BookES
序列化为字节数组。 这是我用作通用 Json 序列化程序的 class。 它应该可以很好地处理您的 class:
package ***;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.mgnt.utils.JsonUtils;
import org.apache.kafka.common.errors.SerializationException;
import org.apache.kafka.common.serialization.Serializer;
import org.springframework.stereotype.Component;
import java.nio.charset.StandardCharsets;
@Component
public class GenericJsonSerializer implements Serializer<Object> {
@Override
public byte[] serialize(String s, Object obj) {
byte[] result;
try {
result = JsonUtils.writeObjectToJsonString(obj).getBytes(StandardCharsets.UTF_8);
} catch (JsonProcessingException e) {
throw new SerializationException("Error occurred while serializing " + obj.getClass().getCanonicalName() + " to byte[]", e);
}
return result;
}
}
在您的属性中,您需要将此 class 注册为您的解串器。 请注意,当您回读消息时,如果您希望将其读取为BookES
class ,则需要提供反序列化器 class ,它将采用字节数组并将其转换回 class BookES
。 (您将必须实施org.apache.kafka.common.serialization.Deserializer
接口)。 在我的示例中,我使用了来自开源 Java 库JsonUtils
(由我编写和维护)的 class JsonUtils。 您可以轻松替换它,只需使用 Json-Jackson 库中的ObjectMapper
class 或使用 GSON 库。 但使用JsonUtils
可能会更简单。 如果您想在此处使用它,请参阅 JsonUtils class 的 Javadoc 。 MgntUtils 库可以作为Maven 工件或在Github上获得
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.