上一篇文章链接https://blog.csdn.net/rico_zhou/article/details/79857625
这篇主要实现发送数据到后台功能,后台发送数据功能见下一篇文章,kafka服务的搭建详见另一篇文章。
https://blog.csdn.net/rico_zhou/article/details/79866076
kafka服务ip为192.168.1.140,端口port为默认9092。
上一篇基本GUI界面已实现,现在开始书写监听代码。
还是类KafkaMainGUI,先写几个方法,获取前台参数,校验前台参数
获取前台参数
// get base set
private BaseMsg getBaseMsg() {
BaseMsg baseMsg = new BaseMsg();
baseMsg.setKafkaIp(tt1.getText().trim());
baseMsg.setKafkaPort(tt2.getText().trim());
baseMsg.setKafkaGroupId(tt3.getText().trim());
baseMsg.setKafkaTopic(tt4.getText().trim());
baseMsg.setKafkaAccount(tt5.getText().trim());
baseMsg.setKafkaTimes(tt6.getText().trim());
baseMsg.setKafkaKey(tt7.getText().trim());
baseMsg.setKafkaIsDefault(jrb1.isSelected());
baseMsg.setKafkaMessage(jta1.getText().trim());
baseMsg.setKafkaStartId(tt8.getText().trim());
return baseMsg;
}
校验前台参数
private int checkParams(BaseMsg baseMsg) {
if (!utils.checkBase1(baseMsg, 0)) {
return 1;
}
if (!utils.checkBase2(baseMsg, 0)) {
return 2;
}
if (!utils.checkIp(baseMsg.getKafkaIp())) {
return 3;
}
if (!utils.checkAccTimeId(baseMsg)) {
return 4;
}
if (!baseMsg.isKafkaIsDefault()) {
if (!utils.checkMsg(baseMsg.getKafkaMessage())) {
return 5;
}
}
return 0;
}
在Utils类中写各种具体的检验方法
// basecheck
public boolean checkBase1(BaseMsg baseMsg, int i) {
// not null ""
if ("".equals(baseMsg.getKafkaIp()) || "".equals(baseMsg.getKafkaPort()) || "".equals(baseMsg.getKafkaGroupId())
|| "".equals(baseMsg.getKafkaTopic())) {
return false;
}
if (i == 0) {
if ("".equals(baseMsg.getKafkaAccount()) || "".equals(baseMsg.getKafkaTimes())
|| "".equals(baseMsg.getKafkaKey()) || "".equals(baseMsg.getKafkaStartId())) {
return false;
}
}
return true;
}
public boolean checkBase2(BaseMsg baseMsg, int i) {
// only number
if (!baseMsg.getKafkaPort().matches("^[0-9]*$")) {
return false;
}
if (i == 0) {
if (!baseMsg.getKafkaAccount().matches("^[0-9]*$") || !baseMsg.getKafkaTimes().matches("^[0-9]*$")
|| !baseMsg.getKafkaStartId().matches("^[0-9]*$")) {
return false;
}
}
return true;
}
// checkip
public boolean checkIp(String ip) {
// 定义正则表达式
String regex = "^(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|[1-9])\\." + "(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\."
+ "(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\." + "(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)$";
if (ip.matches(regex)) {
return true;
} else {
return false;
}
}
public boolean checkAccTimeId(BaseMsg baseMsg) {
if (baseMsg.getKafkaAccount().startsWith("0") || baseMsg.getKafkaTimes().startsWith("0")) {
return false;
}
if (baseMsg.getKafkaAccount().length() > 9 || baseMsg.getKafkaTimes().length() > 9
|| baseMsg.getKafkaStartId().length() > 9) {
return false;
}
return true;
}
public boolean checkMsg(String kafkaMessage) {
if ("".equals(kafkaMessage)) {
return false;
}
if (!checkJson(kafkaMessage)) {
return false;
}
return true;
}
private boolean checkJson(String kafkaMessage) {
try {
JSONObject jsonStr = JSONObject.parseObject(kafkaMessage);
return true;
} catch (Exception e) {
return false;
}
}
接下来监听开始按钮,KafkaMainGUI类
@Override
public void actionPerformed(ActionEvent e) {
// 监听开始
if (e.getSource().equals(button1)) {
// get params
baseMsg = getBaseMsg();
// check
int flag = checkParams(baseMsg);
if (flag == 0) {
button1.setEnabled(false);
button2.setEnabled(true);
button3.setEnabled(false);
jpbProcessLoading1.setVisible(true);
// jpbProcessLoading1.setIndeterminate(true); //
// 设置进度条为不确定模式,默认为确定模式
jpbProcessLoading1.setString("正在发送,请耐心等待...");
jpbProcessLoading1.setValue(0);
// start times
KafkaMainGUI.isRunning = true;
thread = new CountThread();
thread.start();
sw1 = new SwingWorker<ReturnMsg, String>() {
// 此方法是耗时任务
@Override
protected ReturnMsg doInBackground() throws Exception {
ReturnMsg returnMsg = null;
returnMsg = smk.kafkaController(baseMsg);
return returnMsg;
}
// done
protected void done() {
ReturnMsg returnMsg = null;
try {
returnMsg = get();
} catch (Exception e) {
e.printStackTrace();
}
thread.stop();
// jpbProcessLoading1.setIndeterminate(false);
if (returnMsg != null) {
if (returnMsg.isCompleted) {
jpbProcessLoading1.setString("发送完成!");
JOptionPane.showMessageDialog(null, "发送完成!共" + returnMsg.getComTimes() + "条", "提示消息",
JOptionPane.WARNING_MESSAGE);
} else {
jpbProcessLoading1.setString("发送中止!");
JOptionPane.showMessageDialog(null, "发送中止!共" + returnMsg.getComTimes() + "条", "提示消息",
JOptionPane.WARNING_MESSAGE);
}
} else {
jpbProcessLoading1.setString("发送失败!");
JOptionPane.showMessageDialog(null, "发送失败!请检查!", "提示消息", JOptionPane.WARNING_MESSAGE);
}
button1.setEnabled(true);
button2.setEnabled(false);
button3.setEnabled(true);
}
};
sw1.execute();
} else if (flag == 1) {
JOptionPane.showMessageDialog(null, "不能为空!请重新填写!", "提示消息", JOptionPane.WARNING_MESSAGE);
} else if (flag == 2) {
JOptionPane.showMessageDialog(null, "相关参数只能是数字!请重新填写!", "提示消息", JOptionPane.WARNING_MESSAGE);
} else if (flag == 3) {
JOptionPane.showMessageDialog(null, "IP不正确!请重新填写!", "提示消息", JOptionPane.WARNING_MESSAGE);
} else if (flag == 4) {
JOptionPane.showMessageDialog(null, "条数,间隔时间,初始ID超过范围!请重新填写!", "提示消息", JOptionPane.WARNING_MESSAGE);
} else if (flag == 5) {
JOptionPane.showMessageDialog(null, "Message格式不正确!请重新填写!", "提示消息", JOptionPane.WARNING_MESSAGE);
}
}
}
这里简单介绍下SwingWorker线程,此线程安全,专门处理swing后台耗时任务,这样前台依然可以操作,但此线程不容易中止,所以设置一个全局静态变量isRunning来控制线程。
此线程有三个方法:
doInBackground():专门处理耗时任务,启动线程开始调用此方法。
done():此方法是后台耗时任务完成后调用接收返回值,get()即可获取。
process():此方法可以在任务中动态的接收返回值。
再另起一个线程实时显示获取条数
// 实时显示发送的条数
private class CountThread extends Thread {
private CountThread() {
setDaemon(true);
}
@Override
public void run() {
jlb11.setVisible(true);
while (KafkaMainGUI.isRunning) {
jlb11.setText("Times:" + SendMsgKafka.TIMES);
jpbProcessLoading1.setValue(100 * SendMsgKafka.TIMES / Integer.valueOf(baseMsg.getKafkaAccount()));
}
}
}
同理,我们写消费数据的代码,在方法actionPerformed(ActionEvent e)中添加如下代码
// 监听接收
if (e.getSource().equals(button4)) {
// get params
baseMsg2 = getBaseMsg2();
// check
int flag = checkParams2(baseMsg2);
if (flag == 0) {
button4.setEnabled(false);
button5.setEnabled(true);
button6.setEnabled(false);
jpbProcessLoading2.setVisible(true);
jpbProcessLoading2.setIndeterminate(true); // 设置进度条为不确定模式,默认为确定模式
jpbProcessLoading2.setString("正在接收,请耐心等待...");
// start times
KafkaMainGUI.isRunning2 = true;
sw2 = new SwingWorker<String, String>() {
int times2 = 0;
// 此方法是耗时任务
@Override
protected String doInBackground() throws Exception {
Properties props = smk.kafkaController2(baseMsg2);
// smk.kafkaController3(baseMsg2);
KafkaConsumer<String, String> kafkaConsumer = new KafkaConsumer<>(props);
kafkaConsumer.subscribe(Arrays.asList(baseMsg2.getKafkaTopic()));
while (true) {
ConsumerRecords<String, String> records = kafkaConsumer.poll(100);
for (ConsumerRecord<String, String> record : records) {
System.out.println("topic: " + record.topic() + " key: " + record.key() + " value: "
+ record.value() + " partition: " + record.partition());
// 实时发送到前台
publish("topic: " + record.topic() + " key: " + record.key() + " value: "
+ record.value() + " partition: " + record.partition());
}
if (!KafkaMainGUI.isRunning2) {
// close connection
kafkaConsumer.close();
return "1";
}
}
}
// done
protected void done() {
String f = "0";
try {
f = get();
} catch (Exception e) {
e.printStackTrace();
}
if ("1".equals(f)) {
// thread2.stop();
jpbProcessLoading2.setIndeterminate(false);
jpbProcessLoading2.setString("中止接收!");
button4.setEnabled(true);
button5.setEnabled(false);
button6.setEnabled(true);
}
}
@Override
protected void process(List<String> msgs) {
if (SwingUtilities.isEventDispatchThread()) {
jlb16.setVisible(true);
for (String msg : msgs) {
times2++;
jlb16.setText("Times:" + times2);
jta2.append(msg.toString() + "\r\n");
}
}
}
};
sw2.execute();
} else if (flag == 1) {
JOptionPane.showMessageDialog(null, "不能为空!请重新填写!", "提示消息", JOptionPane.WARNING_MESSAGE);
} else if (flag == 2) {
JOptionPane.showMessageDialog(null, "相关参数只能是数字!请重新填写!", "提示消息", JOptionPane.WARNING_MESSAGE);
} else if (flag == 3) {
JOptionPane.showMessageDialog(null, "IP不正确!请重新填写!", "提示消息", JOptionPane.WARNING_MESSAGE);
}
}
这里我们选择直接在方法doInBackground()中处理逻辑以便于前台实时获取实时显示
同理,监听两个面板的中止
// 监听中止
if (e.getSource().equals(button5)) {
KafkaMainGUI.isRunning2 = false;
button4.setEnabled(true);
button5.setEnabled(false);
button6.setEnabled(true);
}
// 监听中止
if (e.getSource().equals(button2)) {
KafkaMainGUI.isRunning = false;
button1.setEnabled(true);
button2.setEnabled(false);
button3.setEnabled(true);
thread.stop();
}
监听重置
// 监听重置
if (e.getSource().equals(button3)) {
tt1.setText("");
tt2.setText("");
tt3.setText("");
tt4.setText("");
tt5.setText("");
tt6.setText("");
tt7.setText("");
tt8.setText("");
jta1.setText("");
jlb11.setText("");
jlb11.setVisible(false);
jpbProcessLoading1.setVisible(false);
jpbProcessLoading1.setValue(0);
jrb1.setSelected(true);
jta1.setVisible(false);
button1.setEnabled(true);
button2.setEnabled(false);
button3.setEnabled(true);
}
// 监听重置
if (e.getSource().equals(button6)) {
tt9.setText("");
tt10.setText("");
tt11.setText("");
tt12.setText("");
jta2.setText("");
jlb16.setText("");
jlb16.setVisible(false);
jpbProcessLoading2.setVisible(false);
button4.setEnabled(true);
button5.setEnabled(false);
button6.setEnabled(true);
}
监听清除缓存
// 监听清除缓存
if (e.getSource().equals(button7)) {
jta2.setText("");
jlb16.setText("");
}
基本监听就是这样了,代码并不全,源码链接GitHub下载:
https://github.com/ricozhou/msgkafka
下一章实现后台发送,消费kafka数据。