Flink中kafkaconnector自定义序列化与反序列化
对象与String自行互转进行生产与消费
当我们对Flink的kafka-connector有了一个大概的认识,并且能够对String,Json等类型的数据进行一个生产和消费操作后,能够想到的是那么对于更复杂的对象的生产与消费呢,比如某一个自定义的对象(POJO类),乃至任意的一个Object。
首先,我们发现可以很简单地发送String到kafka中,从其中去进行一个String类型地消费也很简单。那么首先可以想到的是,可以将对象信息转化为String然后当我们使用的时候也可以用String还原为对象信息。也就是说我们不借用kafka的自定义序列化和反序列化工具,自己根据需要对对象进行字符串化以及反字符串化,比如我们可以在数据类中定义一个tostring和fromString方法,注意,这个数据类要继承Serializable:
import com.ververica.flinktraining.exercises.datastream_java.utils.GeoUtils;
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
import java.io.Serializable;
import java.util.Locale;
/**
* A TaxiRide is a taxi ride event. There are two types of events, a taxi ride start event and a
* taxi ride end event. The isStart flag specifies the type of the event.
*
* A TaxiRide consists of
* - the rideId of the event which is identical for start and end record
* - the type of the event (start or end)
* - the time of the event
* - the longitude of the start location
* - the latitude of the start location
* - the longitude of the end location
* - the latitude of the end location
* - the passengerCnt of the ride
* - the taxiId
* - the driverId
*
*/
public class TaxiRide implements Comparable<TaxiRide>, Serializable {
private static transient DateTimeFormatter timeFormatter =
DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss").withLocale(Locale.US).withZoneUTC();
public TaxiRide() {
this.startTime = new DateTime();
this.endTime = new DateTime();
}
public TaxiRide(long rideId, boolean isStart, DateTime startTime, DateTime endTime,
float startLon, float startLat, float endLon, float endLat,
short passengerCnt, long taxiId, long driverId) {
this.rideId = rideId;
this.isStart = isStart;
this.startTime = startTime;
this.endTime = endTime;
this.startLon = startLon;
this.startLat = startLat;
this.endLon = endLon;
this.endLat = endLat;
this.passengerCnt = passengerCnt;
this.taxiId = taxiId;
this.driverId = driverId;
}
public long rideId;
public boolean isStart;
public DateTime startTime;
public DateTime endTime;
public float startLon;
public float startLat;
public float endLon;
public float endLat;
public short passengerCnt;
public long taxiId;
public long driverId;
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(rideId).append(",");
sb.append(isStart ? "START" : "END").append(",");
sb.append(startTime.toString(timeFormatter)).append(",");
sb.append(endTime.toString(timeFormatter)).append(",");
sb.append(startLon).append(",");
sb.append(startLat).append(",");
sb.append(endLon).append(",");
sb.append(endLat).append(",");
sb.append(passengerCnt).append(",");
sb.append(taxiId).append(",");
sb.append(driverId);
return sb.toString();
}
public static TaxiRide fromString(String line) {
String[] tokens = line.split(",");
if (tokens.length != 11) {
throw new RuntimeException("Invalid record: " + line);
}
TaxiRide ride = new TaxiRide();
try {
ride.rideId = Long.parseLong(tokens[0]);
switch (tokens[1]) {
case "START":
ride.isStart = true;
ride.startTime = DateTime.parse(tokens[2], timeFormatter);
ride.endTime = DateTime.parse(tokens[3], timeFormatter);
break;
case "END":
ride.isStart = false;
ride.endTime = DateTime.parse(tokens[2], timeFormatter);
ride.startTime = DateTime.parse(tokens[3], timeFormatter);
break;
default:
throw new RuntimeException("Invalid record: " + line);