You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在jPOS TransactionResponse中获取多参与者响应并对比?

你碰到的这个问题其实是典型的上下文键冲突——两个查询参与者共用同一个Constants.RESPONSE_KEY存储响应,后面的调用自然会把前面的结果覆盖掉。解决思路很直接:给每个主机的响应分配独立的存储键,然后在响应组装阶段分别取出这两个响应,对比字段39后再生成最终结果。下面是具体的修改步骤:

第一步:新增独立的响应存储常量

先在你的Constants类里添加两个专属键,用来区分两个主机的响应:

public class Constants {
    // 保留原有常量
    public static final String REQUEST_KEY = "REQUEST_KEY";
    public static final String RESPONSE_KEY = "RESPONSE_KEY";
    // 新增两个主机响应的专属标识
    public static final String HOST1_RESPONSE_KEY = "HOST1_RESPONSE_KEY";
    public static final String HOST2_RESPONSE_KEY = "HOST2_RESPONSE_KEY";
}

第二步:修改两个查询参与者的存储逻辑

分别修改FinancialTransactionQueryRemoteHost1和FinancialTransactionQueryRemoteHost2的prepare方法,把各自的响应存到专属键中,避免覆盖:

修改FinancialTransactionQueryRemoteHost1:

@Override 
public int prepare(long l, Serializable srlzbl) { 
    try{ 
        channelManager = ((ChannelManager) NameRegistrar.get("jpos-host1-adaptor")); 
        ISOMsg reqMsg = (ISOMsg) ((Context) srlzbl).get(Constants.REQUEST_KEY); 
        ISOMsg respMsg = channelManager.sendMsg(reqMsg); 
        // 用HOST1专属键存储响应
        ((Context) srlzbl).put(Constants.HOST1_RESPONSE_KEY, respMsg); 
        return PREPARED; 
    }catch(NameRegistrar.NotFoundException e){ 
        e.printStackTrace(); 
        return ABORTED; 
    }catch(Throwable t){ 
        t.printStackTrace(); 
        return ABORTED; 
    } 
}

修改FinancialTransactionQueryRemoteHost2:

@Override 
public int prepare(long l, Serializable srlzbl) { 
    try{ 
        channelManager = ((ChannelManager) NameRegistrar.get("jpos-host2-adaptor")); 
        ISOMsg reqMsg = (ISOMsg) ((Context) srlzbl).get(Constants.REQUEST_KEY); 
        ISOMsg respMsg = channelManager.sendMsg(reqMsg); 
        // 用HOST2专属键存储响应
        ((Context) srlzbl).put(Constants.HOST2_RESPONSE_KEY, respMsg); 
        return PREPARED; 
    }catch(NameRegistrar.NotFoundException e){ 
        e.printStackTrace(); 
        return ABORTED; 
    }catch(Throwable t){ 
        t.printStackTrace(); 
        return ABORTED; 
    } 
}

第三步:修改FinancialTransactionResponse的对比逻辑

现在可以在这个参与者里分别取出两个主机的响应,对比字段39,再生成最终的响应结果:

@Override 
public int prepare(long id, Serializable context) { 
    Context ctx = (Context)context; 
    
    // 取出两个主机的响应,注意做空指针判断
    ISOMsg host1Resp = (ISOMsg)ctx.get(Constants.HOST1_RESPONSE_KEY); 
    ISOMsg host2Resp = (ISOMsg)ctx.get(Constants.HOST2_RESPONSE_KEY); 
    
    // 基于请求消息初始化最终响应(确保MTI、跟踪号等关键字段正确)
    ISOMsg finalResp = null;
    ISOMsg reqMsg = (ISOMsg)ctx.get(Constants.REQUEST_KEY);
    try {
        finalResp = (ISOMsg) reqMsg.clone();
        finalResp.setResponseMTI(); // 切换为响应MTI
    } catch (CloneNotSupportedException e) {
        e.printStackTrace();
        return ABORTED;
    }
    
    // 判断两个主机的响应状态(字段39是否为"00")
    boolean host1Success = (host1Resp != null && "00".equals(host1Resp.getString(39)));
    boolean host2Success = (host2Resp != null && "00".equals(host2Resp.getString(39)));
    
    // 根据业务规则生成最终的字段39值
    if (host1Success && host2Success) {
        finalResp.set(39, "00"); // 两者都成功,返回成功码
    } else if (host1Success || host2Success) {
        finalResp.set(39, "00"); // 只要一个成功就返回成功(可根据实际业务调整)
    } else {
        finalResp.set(39, "06"); // 两者都失败,返回失败码
    }
    
    ctx.put(Constants.RESPONSE_KEY, finalResp); 
    return PREPARED; 
}

额外注意事项

  • 一定要处理响应为空的情况:如果某个主机调用失败(参与者返回ABORTED),对应的响应键可能不存在,必须加非空判断避免空指针异常。
  • 业务规则可灵活调整:比如你是要求两者都成功才算成功,还是只要一个成功即可,完全根据你的实际业务需求修改判断逻辑。
  • 如果ISOMsg克隆有问题,也可以手动创建新的响应消息,复制请求中的必要字段(如系统跟踪号、日期时间等)。

内容的提问来源于stack exchange,提问作者Dexter

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:10:57