一、对接供应商模块开发
供应商对接模块chongba_recharge_supplier主要负责的就是调用外部的供应商系统进行充值下单,这种调用是一种基于HTTP协议的调用。
此外在供应商对接模块中主要是实现的业务逻辑有:
1:余额或押金不足情况下的失败轮转
2:网络故障/充值失败重试,需要添加一个重试任务
3:重试次数到达阈值后停止供应商对接
4:供应商异步回调,订单状态修改
二、对接供应商服务接口定义
chongba_recharge_supplier监听到支付成功消息之后,接收到的消息:RechargeRequest,具体对接的不直接写在监听类中,单独定义一个对接供应商服务接口
步骤1:在chongba_recharge_supplier模块下创建包:com.chongba.supplier.inf,在该包下创建充吧系统对接供应商接口:SupplierService,接口中定义一个对接方法:void recharge(RechargeRequest rechargeRequest);
public interface SupplierService { /** * 对接供应商下单 * @param rechargeRequest */ public void recharge(RechargeRequest rechargeRequest); }
步骤2:在chongba_recharge_supplier模块下创建包:com.chongba.supplier.service,在该包下创建一个接口的实现类:SupplierServiceImpl
@Slf4j @Service public class SupplierServiceImpl implements SupplierService{ @Override public void recharge(RechargeRequest rechargeRequest) { } }
步骤3:配置供应商系统的接口地址,在实际业务中调用第三方系统接口大都基于HTTP协议调用,充吧系统在模块中模拟了两个供应商,注意这个模块并没有在充吧的注册中心去注册,因为我们模拟的是外部系统,所以我们要调用外部系统必须得知道系统接口的调用地址;
在application-dev.yml中配置如下:
supplier: apis: { "jisuapi": "http://127.0.0.1:8090/jisuapi/mobilerecharge/recharge", "juheapi": "http://127.0.0.1:8090/juheapi/recharge" }
步骤4:编写配置类读取配置,在chongba_recharge_supplier模块下创建包:com.chongba.supplier.conf,在该包下创建配置类:SupplierConfig
@Data @Component @ConfigurationProperties(prefix = "supplier") public class SupplierConfig { private Map<String,String> apis; //加载供应商api地址 }
步骤5:在对接服务实现类:SupplierServiceImpl中注入配置类SupplierConfig,并测试配置能否正常读取
@Slf4j @Service public class SupplierServiceImpl implements SupplierService{ @Autowired private SupplierConfig supplierConfig; @PostConstruct public void init(){ System.out.println("加载到的配置如下:"+supplierConfig.getApis()); } @Override public void recharge(RechargeRequest rechargeRequest) { } }
运行启动类:SupplierApplication,查看控制台输出:
三、对接供应商逻辑编写
配置正常加载之后需要编写对接供应商的处理逻辑,先将代码结构实现,然后补充细节
1).编写对接逻辑分发方法:doDispatchSupplier(RechargeRequest rechargeRequest),根据供应商编号进行分发
2).编写对接聚合的方法:doPostJuhe(RechargeRequest rechargeRequest)
3).编写对接极速的方法:doPostJisu(RechargeRequest rechargeRequest)
对接第三方其实就是向第三方系统接口地址发起HTTP请求,我们可以使用HttpClient、PostMan等工具。
步骤1:在启动类SupplierApplication中向容器注入RestTemplate
@Bean public RestTemplate restTemplate(){ return new RestTemplate(); }
步骤2:整体对接代码结构如下:
@Autowired private RestTemplate restTemplate; @Override public void recharge(RechargeRequest rechargeRequest) { doDispatchSupplier(rechargeRequest); } /** * 对接逻辑分发 * @param rechargeRequest */ private void doDispatchSupplier(RechargeRequest rechargeRequest) { //设置供应商的调用地址: String url = supplierConfig.getApis().get(rechargeRequest.getSupply()); rechargeRequest.setRechargeUrl(url); //根据需要对接的供应商的编号确定不同的对接方式---不同的api需要传递的参数类型和参数名称等各不相同 if(Constants.juheapi.equals(rechargeRequest.getSupply())){ //对接聚合 doPostJuhe(rechargeRequest); }else if(Constants.jisuapi.equals(rechargeRequest.getSupply())) { //对接极速 doPostJisu(rechargeRequest); } } private void doPostJuhe(RechargeRequest rechargeRequest) { //聚合要求传递的是json格式的数据 //创建并设置请求头 HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); //创建请求实体 HttpEntity httpEntity = new HttpEntity(JSON.toJSONString(rechargeRequest),headers); //发送请求 ResponseEntity<String> responseEntity = restTemplate.postForEntity(rechargeRequest.getRechargeUrl(), httpEntity, String.class); //获得结果 String body = responseEntity.getBody(); System.out.println(body); } private void doPostJisu(RechargeRequest rechargeRequest) { }
然后注意:在我们监听类中监听到消息之后,要去调用我们供应商对接服务接口方法:
@Component @Slf4j @RocketMQMessageListener(topic = "pay",consumerGroup = "order-paid-consumer") public class PayRocketListener implements RocketMQListener<RechargeRequest>{ @Autowired private SupplierService supplierService; /** * 监听消息: * @param rechargeRequest */ @Override public void onMessage(RechargeRequest rechargeRequest) { log.info("PayRocketListener 监听到了消息,{}",rechargeRequest); supplierService.recharge(rechargeRequest); } }
启动测试:
启动chongba_recharge_web工程,chongba_recharge_mock工程,chongba_recharge_supplier工程
访问:http://localhost:191/ 进行充值,查看结果
步骤3:供应商返回结果封装处理:对于供应商的返回结果数据我们可以统一封装处理
对进行泛型的反序列化,使用TypeReference可以明确的指定反序列化的类型
@Override public void recharge(RechargeRequest rechargeRequest) { Result<RechargeResponse> result = doDispatchSupplier(rechargeRequest); if(result !=null){ } } /** * 对接逻辑分发 * @param rechargeRequest */ private Result<RechargeResponse> doDispatchSupplier(RechargeRequest rechargeRequest) { //设置供应商的调用地址: String url = supplierConfig.getApis().get(rechargeRequest.getSupply()); rechargeRequest.setRechargeUrl(url); //根据需要对接的供应商的编号确定不同的对接方式---不同的api需要传递的参数类型和参数名称等各不相同 if(Constants.juheapi.equals(rechargeRequest.getSupply())){ //对接聚合 return doPostJuhe(rechargeRequest); }else if(Constants.jisuapi.equals(rechargeRequest.getSupply())) { //对接极速 return doPostJisu(rechargeRequest); } return null; } private Result<RechargeResponse> doPostJuhe(RechargeRequest rechargeRequest) { //聚合要求传递的是json格式的数据 //创建并设置请求头 HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); //创建请求实体 HttpEntity httpEntity = new HttpEntity(JSON.toJSONString(rechargeRequest),headers); //发送请求 ResponseEntity<String> responseEntity = restTemplate.postForEntity(rechargeRequest.getRechargeUrl(), httpEntity, String.class); //获得结果 /*String body = responseEntity.getBody();// Result<RechargeResponse> Result result = JSON.parseObject(body, Result.class);//因为泛型的问题可能会导致出现问题 System.out.println(body);*/ Result<RechargeResponse> result = JSON.parseObject(responseEntity.getBody(), new TypeReference<Result<RechargeResponse>>(){}); return result; } // 对接极速 private Result<RechargeResponse> doPostJisu(RechargeRequest rechargeRequest) { return null; }
四、对接供应商测试
业务逻辑:
选择手机充值进行话费充值。进行充值,然后生成订单并支付成功。支付成功后,对接供应商模块,发送消息到供应商平台,然后接收聚合供应商返回的消息。进行处理。
选择充值:
进行充值:
充值话费成功:
对接供应商模块,发送消息到供应商平台,然后接收聚合供应商返回的消息(余额不足)。对接成功。