首页 > 解决方案 > JAVA 到 EBCIDIC 的转换没有发生

问题描述

我正在尝试从一个应用程序获取数据并在处理数据后将其发送到另一个(大型机)。

假设我正在获取“这是来自另一个应用程序”的数据,处理与“此数据已处理”相同的处理状态。最终消息应结合使用编码(Cp1047)到大型机应用程序来读取与

0024这是来自另一个应用程序001A此数据已处理


0024 的十进制值为 36(消息长度 + 4 是十六进制值长度)
001A 的十进制值为 26(处理的消息长度 + 4)

我的应用程序在 Java8 上运行并使用 websphere MQ。我需要将数据发送到从 Mainframe MQ 接收数据的应用程序。WebSphere MQ 中的远程队列将消息放入大型机 MQ 的本地队列。我的代码如下,使用 Cp1047 转换数据和编码,

String incomingData = "This is from another application";
String processingData = "This data is processed" 
public String outGoingData(String incomingData, String processingData) {  
  StringBuilder strBuilder = new StringBuilder();
  return stringbuilder.append(new String(convertToEbcidie(incomingData, "Cp1047")))
  .append(incomingData)
  .append(new String(convertToEbcidie(processingData, "Cp1047")))
  .append(processing data).toString(); //playing this string to queue
}
private byte[] convertToEbcidic(String s) {
  String hexStr = StringUtils.leftPad(s.length+4, 8, "0");
  byte[] byteAry = new byte[hexStr.length()/2];
  for (int i = 0; i < hexStr.length(); i+=2) {
    byteAry[i/2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
                   + Character.digit(s.charAt(i+1), 16)); 
  }  return byteAry;
}

接收方应用程序(大型机)决定哪个是原始消息和基于处理状态的 4 个字符的十六进制值。他们能够阅读大部分信息,但不是全部。例如,长度 805 的十六进制值为 325,但在大型机 mq 条目中为 315。由于长度不匹配,它们无法处理。

另一个样本数据:- OO25这是来自源001A的原始数据,已成功处理


0025 是 org msg length(33) + 4 的十六进制值,001A 是处理后的 msg 长度 (22) + 4 的十六进制值。这里 4 是十六进制值的长度。
我是否缺少任何转换为​​ ebcidic 的逻辑?

标签: javaibm-mqencodemainframecharacter-set

解决方案


您发布的代码有很多错误,我不知道从哪里开始。

首先,StackOverflow 规则/策略是您应该将工作代码从编辑器或 IDE 复制并粘贴到 StackOverflow。显然,您没有这样做,而只是在 StackOverflow 编辑窗口中创建了新代码——这是错误的!!!

return stringbuilder.append(new String(convertToEbcidie(incomingData, "Cp1047")))
  .append(incomingData)
  .append(new String(convertToEbcidie(processingData, "Cp1047")))
  .append(processing data).toString();

(1) convertToEbcidic 方法采用 ONE 参数,而不是 2。您的括号错误。

(2) 方法名是convertToEbcidic而不是convertToEbcidie(最后一个字母是'c'而不是'e')

private byte[] convertToEbcidic(String s) {
  String hexStr = StringUtils.leftPad(s.length+4, 8, "0");
  byte[] byteAry = new byte[hexStr.length()/2];
  for (int i = 0; i < hexStr.length(); i+=2) {
    byteAry[i/2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
                   + Character.digit(s.charAt(i+1), 16)); 
  }  return byteAry;
}

(3) 我不知道您要做什么,但显然它没有做您认为的任何事情。您是否使用调试器单步执行代码?

(3A) s 变量的长度是一个方法而不是一个字段。它应该是“s.length()”而不是“s.length”。

(3B) StringUtils.leftPad 方法的第一个参数必须是 String 而不是 int。

(3C) hexStr 将为“00000036”(32 + 4)。hexStr 的长度为 8。

(3D) byteAry 的大小为 4!!!您如何将 36 个字符放入 4 个字节中?即 4 + 26 个字符“这是来自另一个应用程序”。

(3E) 你的循环在做什么?它运行了 4 次,我完全不知道你在想什么。

好的。现在到你的问题。

ANOTHER SAMPLE DATA :- OO25THIS IS ORIGINAL DATA FROM SOURCE001APROCESSED SUCCESSFULLY

好的。因此,基于该示例,在我看来布局如下:

{“字符数据1”长度的字符串表示,十六进制}{字符数据1}{“字符数据2”长度的字符串表示,十六进制}{字符数据2}

由于整个消息负载将是字符串,因此将字符串作为消息放在本地代码页(ASCII)中要好得多,将 MQMD 格式标记为字符串并让 MQ 进行转换。当大型机应用程序发出“MQGET with Convert”调用时,转换将完成。

这是您的问题的正确代码:

String incomingData = "This is from another application";
String processingData = "This data is processed";
StringBuilder sb = new StringBuilder();
MQQueueManager qMgr = null;
MQQueue outQ = null;

String inHexLen = Integer.toHexString(incomingData.length()+4).toUpperCase();
inHexLen = StringUtils.leftPad(inHexLen, 4, '0');
sb.append(inHexLen);
sb.append(incomingData);

String outHexLen = Integer.toHexString(processingData.length()+4).toUpperCase();
outHexLen = StringUtils.leftPad(outHexLen, 4, '0');
sb.append(outHexLen);
sb.append(processingData);

System.out.println("sb="+sb.toString());

try
{
   qMgr = new MQQueueManager("MQA1");

   outQ = qMgr.accessQueue("TEST.Q1",
                           CMQC.MQOO_OUTPUT + CMQC.MQOO_FAIL_IF_QUIESCING);

   MQMessage sendmsg = new MQMessage();
   sendmsg.format = CMQC.MQFMT_STRING;
   sendmsg.writeString(sb.toString());
   outQ.put(sendmsg, new MQPutMessageOptions());
}
catch (MQException e)
{
   e.printStackTrace();
}
catch (IOException e)
{
   e.printStackTrace();
}
finally
{
   try
   {
      if (outQ != null)
         outQ.close();
   }
   catch (MQException e)
   {
      e.printStackTrace();
   }
   try
   {
      if (qMgr != null)
         qMgr.disconnect();
   }
   catch (MQException e)
   {
      e.printStackTrace();
   }
}

推荐阅读