如何更改@kafkastreamssstatestore的默认serdes?我知道,在Kafka流云的新版本3.0.1中,方法如下所述:https://cloud.spring.io/spring-cloud-static/spring-cloud-stream-binder-kafka/3.0.1.RELEASE/reference/html/spring-cloud-stream-binder-kafka.html#_state_store.但由于我使用的是2.1.12,请您提供一些代码示例。我找了很多地方都没找到。
@kafkastreamssstatestore(名称=DEDUP\u STORE,类型=kafkastreamssstatestoreproperties.StoreType.KEYVALUE,keySerde=“”?????“”,valueSerde=“???”)这也没有帮助。
https://www.bountysource.com/issues/87943127-consider-changing-the-default-serdes-of-kafkastreamsstatestore
我尝试了:
@KafkaStreamsStateStore(name = DEDUP_STORE, type = KafkaStreamsStateStoreProperties.StoreType.KEYVALUE, keySerde = "VALUE_SERDE", valueSerde = "VALUE_SERDE")
public class CustomSerde {
static public final class CustomSerdes extends WrapperSerde<Entity> {
public CustomSerdes () {
super(new JsonPOJOSerializer<Entity>(), new JsonPOJODeserializer<Entity>());
}
}
}
public static final String VALUE_SERDE = "CustomSerde$CustomSerdes";
public class JsonPOJODeserializer<T> implements Deserializer<T> {
private ObjectMapper objectMapper = new ObjectMapper();
private Class<T> tClass;
/**
* Default constructor needed by Kafka
*/
public JsonPOJODeserializer() {
}
@SuppressWarnings("unchecked")
@Override
public void configure(Map<String, ?> props, boolean isKey) {
tClass = (Class<T>) props.get("JsonPOJOClass");
}
@Override
public T deserialize(String topic, byte[] bytes) {
if (bytes == null)
return null;
T data;
try {
data = objectMapper.readValue(bytes, tClass);
} catch (Exception e) {
throw new SerializationException(e);
}
return data;
}
@Override
public void close() {
}
}
public class JsonPOJOSerializer<T> implements Serializer<T> {
private final ObjectMapper objectMapper = new ObjectMapper();
private Class<T> tClass;
/**
* Default constructor needed by Kafka
*/
public JsonPOJOSerializer() {
}
@SuppressWarnings("unchecked")
@Override
public void configure(Map<String, ?> props, boolean isKey) {
tClass = (Class<T>) props.get("JsonPOJOClass");
}
@Override
public byte[] serialize(String topic, T data) {
if (data == null)
return null;
try {
return objectMapper.writeValueAsBytes(data);
} catch (Exception e) {
throw new SerializationException("Error serializing JSON
message", e);
}
}
@Override
public void close() {
}
}
但不起作用。请告知。
找到了一个帮助我的解决方案:
@SuppressWarnings({"WeakerAccess", "unused"})
public class PageViewTypedDemo {
/**
* A serde for any class that implements {@link JSONSerdeCompatible}. Note that the classes also need to
* be registered in the {@code @JsonSubTypes} annotation on {@link JSONSerdeCompatible}.
*
* @param <T> The concrete type of the class that gets de/serialized
*/
public static class JSONSerde<T extends JSONSerdeCompatible> implements Serializer<T>, Deserializer<T>, Serde<T> {
private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
@Override
public void configure(final Map<String, ?> configs, final boolean isKey) {}
@SuppressWarnings("unchecked")
@Override
public T deserialize(final String topic, final byte[] data) {
if (data == null) {
return null;
}
try {
return (T) OBJECT_MAPPER.readValue(data, JSONSerdeCompatible.class);
} catch (final IOException e) {
throw new SerializationException(e);
}
}
@Override
public byte[] serialize(final String topic, final T data) {
if (data == null) {
return null;
}
try {
return OBJECT_MAPPER.writeValueAsBytes(data);
} catch (final Exception e) {
throw new SerializationException("Error serializing JSON message", e);
}
}
@Override
public void close() {}
@Override
public Serializer<T> serializer() {
return this;
}
@Override
public Deserializer<T> deserializer() {
return this;
}
}
/**
* An interface for registering types that can be de/serialized with {@link JSONSerde}.
*/
@SuppressWarnings("DefaultAnnotationParam") // being explicit for the example
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "_t")
@JsonSubTypes({
@JsonSubTypes.Type(value = PageView.class, name = "pv"),
@JsonSubTypes.Type(value = UserProfile.class, name = "up"),
@JsonSubTypes.Type(value = PageViewByRegion.class, name = "pvbr"),
@JsonSubTypes.Type(value = WindowedPageViewByRegion.class, name = "wpvbr"),
@JsonSubTypes.Type(value = RegionCount.class, name = "rc")
})
public interface JSONSerdeCompatible {
}
// POJO classes
static public class PageView implements JSONSerdeCompatible {
public String user;
public String page;
public Long timestamp;
}
static public class UserProfile implements JSONSerdeCompatible {
public String region;
public Long timestamp;
}
static public class PageViewByRegion implements JSONSerdeCompatible {
public String user;
public String page;
public String region;
}
static public class WindowedPageViewByRegion implements JSONSerdeCompatible {
public long windowStart;
public String region;
}
static public class RegionCount implements JSONSerdeCompatible {
public long count;
public String region;
}
public static void main(final String[] args) {
final Properties props = new Properties();
props.put(StreamsConfig.APPLICATION_ID_CONFIG, "streams-pageview-typed");
props.put(StreamsConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092");
props.put(StreamsConfig.DEFAULT_TIMESTAMP_EXTRACTOR_CLASS_CONFIG, JsonTimestampExtractor.class);
props.put(StreamsConfig.DEFAULT_KEY_SERDE_CLASS_CONFIG, JSONSerde.class);
props.put(StreamsConfig.DEFAULT_WINDOWED_KEY_SERDE_INNER_CLASS, JSONSerde.class);
props.put(StreamsConfig.DEFAULT_VALUE_SERDE_CLASS_CONFIG, JSONSerde.class);
props.put(StreamsConfig.DEFAULT_WINDOWED_VALUE_SERDE_INNER_CLASS, JSONSerde.class);
props.put(StreamsConfig.CACHE_MAX_BYTES_BUFFERING_CONFIG, 0);
props.put(StreamsConfig.COMMIT_INTERVAL_MS_CONFIG, 1000);
// setting offset reset to earliest so that we can re-run the demo code with the same pre-loaded data
props.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest");
final StreamsBuilder builder = new StreamsBuilder();
final KStream<String, PageView> views = builder.stream("streams-pageview-input", Consumed.with(Serdes.String(), new JSONSerde<>()));
final KTable<String, UserProfile> users = builder.table("streams-userprofile-input", Consumed.with(Serdes.String(), new JSONSerde<>()));
final KStream<WindowedPageViewByRegion, RegionCount> regionCount = views
.leftJoin(users, (view, profile) -> {
final PageViewByRegion viewByRegion = new PageViewByRegion();
viewByRegion.user = view.user;
viewByRegion.page = view.page;
if (profile != null) {
viewByRegion.region = profile.region;
} else {
viewByRegion.region = "UNKNOWN";
}
return viewByRegion;
})
.map((user, viewRegion) -> new KeyValue<>(viewRegion.region, viewRegion))
.groupByKey(Grouped.with(Serdes.String(), new JSONSerde<>()))
.windowedBy(TimeWindows.of(Duration.ofDays(7)).advanceBy(Duration.ofSeconds(1)))
.count()
.toStream()
.map((key, value) -> {
final WindowedPageViewByRegion wViewByRegion = new WindowedPageViewByRegion();
wViewByRegion.windowStart = key.window().start();
wViewByRegion.region = key.key();
final RegionCount rCount = new RegionCount();
rCount.region = key.key();
rCount.count = value;
return new KeyValue<>(wViewByRegion, rCount);
});
// write to the result topic
regionCount.to("streams-pageviewstats-typed-output");
final KafkaStreams streams = new KafkaStreams(builder.build(), props);
final CountDownLatch latch = new CountDownLatch(1);
// attach shutdown handler to catch control-c
Runtime.getRuntime().addShutdownHook(new Thread("streams-pipe-shutdown-hook") {
@Override
public void run() {
streams.close();
latch.countDown();
}
});
try {
streams.start();
latch.await();
} catch (final Throwable e) {
e.printStackTrace();
System.exit(1);
}
System.exit(0);
}
}
在上面的代码段中,您有以下内容:
@KafkaStreamsStateStore(name = DEDUP_STORE, type = KafkaStreamsStateStoreProperties.StoreType.KEYVALUE, keySerde = "VALUE_SERDE", valueSerde = "VALUE_SERDE")
究竟什么是VALUE\u SERDE?它是否实现了Serde接口?只要它实现了一个适当的Serde接口,就应该可以工作。活页夹在内部将此值向下传递给StoreBuilder。您是否有任何错误?如果您仍然面临问题,请与我们共享一个小样本应用程序,我们可以进一步研究它。
我使用的是tomcat,每当我转到一个servlet无法处理的方向时,我都想做其他事情,比如显示默认错误: 我在哪里可以处理这个问题¿? 先谢谢你了
问题内容: 我想在侦听器中指定可侦听的默认端口。是否有比在内部解析并插入配置的端口更容易的修复方法? 目标是运行时不必每次都指定地址和端口,而要从中获取参数。 问题答案: 使用以下命令创建一个bash脚本: 将其保存为runserver并与manage.py放在同一目录中 并运行为
问题内容: 尝试更改列的数据类型并设置新的默认值时遇到以下错误: 错误1064(42000):您的SQL语法有错误;检查与您的MySQL服务器版本相对应的手册,以在第1行的’VARCHAR(255)NOT NULL SET DEFAULT’{}’‘附近使用正确的语法 问题答案: 同样的第二种可能性(感谢juergen_d):
在尝试更改列的数据类型并设置新的默认值时,我遇到以下错误: 错误1064(42000):您的SQL语法中有错误;查看与您的MySQL server版本相对应的手册,以了解第1行“varchar(255)NOT NULL SET DEFAULT”{}“附近使用的正确语法
当启动一个流浪者盒子时,“默认”这个名字来自哪里? 有没有办法设定这个?
我正在使用Spring Boot 2.4.4,我会将默认Web服务器Tomcat更改为undertow或JHetty,但我发现同时使用Gradle或Maven非常困难。 一份旧的文档介绍了如何做到这一点,但我确信一切都改变了,因为现在tomcat、undertow和jetty配置嵌入到核心库中: https://docs.spring.io/spring-boot/docs/2.1.9.RELEA