作为生产者角色的消息客户端,还需要接收来自业务系统的事件,然后将其转换为请求消息,发送给服务端。
这里我们做一个控制器,对外接收rest请求,业务系统传入事件(必填)与单据标识(非必填,某些事件为全局,无标识的概念)。为方便处理,我们约定将事件的编码与消息主题编码保持一致。
当我们模拟业务系统(生产者)请求地址http://localhost:10001/event?event=lms.transportbill.consignmentbill.create&id=1时,就会触发消息客户端向服务器端推送一条消息。
/**
* 接收事件控制器
* @author wqliu
* @date 2022-1-18 16:14
**/
@RestController
@RequestMapping("/event")
public class ReceiveEventController {
//TODO:方便测试,暂时使用get请求,后续考虑调整为post
@GetMapping
public String receive(String event,String id){
//数据验证
if(StringUtils.isBlank(event)){
throw new RuntimeException("事件不能为空");
}
//根据消息主题查找发送器
try {
MessageSender messageSender = (MessageSender) MessageSenderFactory.createSender(event);
messageSender.setContent(id);
messageSender.sendMessage();
return "ok";
}catch (MessageException e){
throw new RuntimeException(e.getErrorMessage());
}
}
}
相关代码,采用简单工厂模式实现的发送器工厂
/**
* 消息发送器工厂
* @author wqliu
* @date 2022-01-18 9:07
**/
public class MessageSenderFactory {
private MessageSenderFactory(){};
public static MessageSender createSender(String topic){
//使用反射技术获取类
Class<MessageSender> messageSender=null;
try {
//根据消息主题获取对应的消息处理类名
ApiMessageTopicService service = SpringUtil.getBean(ApiMessageTopicService.class);
String senderName = service.getHandlerByCode(topic);
messageSender = (Class<MessageSender>) Class.forName(senderName);
//返回消息发送器类的实例
return messageSender.newInstance();
}
catch (CustomException e){
throw new MessageException("S101",e.getMessage());
}catch (Exception e){
throw new MessageException("S102","消息发送器不存在");
}
}
}