我有一个火花流上下文,可以从Kafka Consumer获取数据流。数据包含JSON对象。我需要将其转换为自定义Java对象,以便进行一些处理。有没有简单的方法可以做到这一点?基本上,我想要一种将JavaRDD转换为普通字符串的方法,以便可以使用gson.fromJSON将其转换为简单的POJO类对象。
我尝试了一些方法,但是遇到了Serilaization问题
JavaDStream jds = stream.map(x-> x.value());
jds.foreachRDD(x -> System.out.println(x.count()));
jds.foreachRDD(new VoidFunction<JavaRDD<String>>() {
private static final long serialVersionUID = 1L;
@Override
public void call(JavaRDD<String> rdd) {
rdd.foreach(a -> {
TransactionData tr = gson.fromJson(a, TransactionData.class);
}
);
}
TransactionData是一个普通的Java bean类,具有两个字段id和amount以及它们的getter / setter方法
在上面的代码中,我在序列化方面遇到错误。 这是错误: org.apache.spark.SparkException:任务无法序列化原因:java.io.NotSerializableException:com.google.gson.Gson序列化堆栈:-对象不可序列化(类:com.google.gson.Gson,值:{serializeNulls: falsefactories:[Factory [typeHierarchy = com.google.gson.JsonElement,adapter = com.google.gson.internal.bind.TypeAdapters $ 25 @ 35c645ea]。...
关于如何解决此问题的任何想法?
答案 0 :(得分:0)
这里的问题是Gson不可序列化,可以通过避免Gson序列化并仅在处理期间创建实例来解决。可以创建Gson的包装器类,并在主代码中使用;在示例中使用Car类代替TransactionData:
public class CarConverter implements Serializable {
transient Gson gson;
private Gson getGson() {
if (gson == null) {
gson = new Gson();
}
return gson;
}
public JavaRDD<Car> convert(JavaRDD<String> rdd) {
return rdd.map(a -> getGson().fromJson(a, Car.class));
}
}
用法示例:
List<String> data = Lists.newArrayList("{\"brand\":\"Jeep\", \"doors\": 3}", "{\"brand\":\"Slavuta\", \"doors\": 4}");
JavaRDD<String> rdd = jsc().parallelize(data);
CarConverter converter = new CarConverter();
JavaRDD<Car> result = converter.convert(rdd);