gpt4 book ai didi

java - 特殊字符问题 : MQ message PUT error : java. nio.charset.UnmappableCharacterException

转载 作者:行者123 更新时间:2023-12-02 16:28:47 38 4
gpt4 key购买 nike

我有一个设置,其中有一个 JMS 生产者和 JMS 接收器。发件人应用程序发送如下消息:

source text ⟨е, ё, и, ю, я⟩  abcdefg

JMS 接收器在收到消息后,使用纯 IBM MQ API 类将其放入 IBM MQ 队列。

将此消息发送到 MQ 时出现以下异常:

INFO  | 2020-09-17 09:45:19 | [main] mimq.MQReceiver (MQReceiver.java:211) - IO Exception Occurred: Input length = 1
java.nio.charset.UnmappableCharacterException: Input length = 1
at java.nio.charset.CoderResult.throwException(CoderResult.java:282)
at java.nio.charset.CharsetEncoder.encode(CharsetEncoder.java:816)
at com.ibm.mq.jmqi.system.JmqiCodepage.stringToBytes(JmqiCodepage.java:923)
at com.ibm.mq.MQMessage.writeString(MQMessage.java:2848)
at com.ibm.mimq.MQReceiver.sendToAnotherQueue(MQReceiver.java:192)
at com.ibm.mimq.MQReceiver.main(MQReceiver.java:113)

下面是我的 MQ PUT 代码:

public static void sendToLocalQueue(String msg) {

int port = 1414;
String host = "some-host";
String channel = "some-channel";
String manager = "some-QM";
String user = "user";
String passwd = "passwd";
String qname = "TEST";
String qmname = "some-QM";

MQQueueManager qMgr;
MQQueue inputQ;

try {

Hashtable<String, String> h = new Hashtable<String, String>();
h.put(MQC.TRANSPORT_PROPERTY, MQC.TRANSPORT_MQSERIES_CLIENT);
MQEnvironment.properties = h;
MQEnvironment.hostname = host;
MQEnvironment.port = port;
MQEnvironment.channel = channel;

MQEnvironment.userID = user;
MQEnvironment.password = passwd;
MQEnvironment.disableTracing();
MQException.log = null;
qMgr = new MQQueueManager(manager);

MQMessage m = new MQMessage();
m.applicationOriginData = "AMPS";
m.messageType = MQC.MQMT_DATAGRAM;
m.format = MQC.MQFMT_STRING;
m.encoding = MQC.MQENC_NATIVE;
m.priority = 4;
m.persistence = MQC.MQPER_PERSISTENT;
m.characterSet = MQC.MQCCSI_Q_MGR;
//m.characterSet = 1208;
m.expiry = MQC.MQEI_UNLIMITED;
m.writeString(msg);

MQPutMessageOptions putOptions = new MQPutMessageOptions();
putOptions.options = MQC.MQPMO_SYNCPOINT | MQC.MQPMO_FAIL_IF_QUIESCING;

logger.info("Putting message to LAN MQ (TEST queue)....");
qMgr.put(qname, qmname, m, putOptions);
qMgr.commit();


} catch(MQException me) {
logger.info("Error Code : " +me.getErrorCode());
logger.info("LocalizedMessage : " +me.getLocalizedMessage());
logger.info("Message : " +me.getMessage());
logger.info("Reason : " +me.getReason());
me.printStackTrace();

} catch (IOException e) {
// TODO Auto-generated catch block
logger.info("IO Exception Occurred : " +e.getLocalizedMessage());
e.printStackTrace();
}
}

由于不可映射字符,无法将消息放入队列。编码在队列管理器级别设置为 UTF-8。

但是,当我替换以下行时:m.characterSet = MQC.MQCCSI_Q_MGR;

使用以下行:m.characterSet = 1208; 问题不再存在。

我的问题是为什么这种转换没有在 MQ 级别完成。我需要检查哪些设置以确保正确转换。我尝试了以下技术,但没有用:

Setting java parameter as : -Dfile.encoding=UTF-8 

我的环境:

Server : Linux
MQ : 9.0 or 7.5
Java : 1.8

还有一件事要提,同样的设置在 7.5 上工作,但在迁移后不能在 MQ 9.0 上工作。我知道通过我上面的一行代码更改我可以传递消息。但是我想在 MQ 级别上了解,如果我遗漏了一些配置。任何建议将不胜感激。

谢谢。

更新

我将消息发送到 MQ 的客户端计算机具有 CCSID:MQMD.CodedCharSetId = 1208

我正在连接和发送消息的 MQ 服务器有这个:

getDefaultProperty(Object) returns [819(0x333)] Integer
setCCSID(int) setter [819(0x333)]

因此,当我在我的代码中明确设置 1208 时,它可以正常工作。如果不是,则转换失败。

UPDATE-2

正如我在 jar 中看到的那样,MQC.MQCCSI_Q_MGR 的值是零。因此代码是这样设计的,如果值为零,它将从设置为 819 的 Jar 中获取默认值。我在打开 MQ 跟踪时了解到这一点。代码是这样的:

getDefaultProperty(Object) returns [819(0x333)] Integer
setCCSID(int) setter [819(0x333)]

此代码存在于 jar 中。所以我们需要在消息上显式设置字符集值。在我的例子中是 1208。

最佳答案

这在 MQ v7.5 而不是 MQ v9.0 中起作用的原因是因为在 IBM MQ v8.0 之前,IBM MQ 类使用 java.nio.charset.Charset.encode 对 Java 编码数据进行编码(CharBuffer) 这会导致默认替换格式错误或不可翻译的数据。由于默认的 characterSet 是 819 (ASCII),这将导致您发送的任何无法转换为 ASCII 的字符被透明地替换为默认的替换字符,在大多数情况下,这意味着数据是替换为 ? 字符。

在 v8.0 之后,默认行为更改为将这种情况报告为错误,默认情况下不再替换格式错误或不可翻译的数据。


将字符集设置为 UTF-8 的解决方案是最佳解决方案,因为这会导致发送您打算发送的确切数据。

另一种选择是告诉 MQ 使用先前的行为。


IBM MQ 9.0 知识中心页面 Developing applications>Developing JMS and Java applications>Using IBM MQ classes for Java>Character string conversions in IBM MQ classes for Java 中描述了新行为的描述以及如何为 Java 配置 IBM MQ 类以使用先前的行为。 :

From IBM® MQ Version 8.0, some of the default behavior regardingcharacter string conversion in the IBM MQ classes for Java™ haschanged.

Before IBM MQ Version 8.0, string conversions in IBM MQ classes forJava was done by calling thejava.nio.charset.Charset.decode(ByteBuffer) andCharset.encode(CharBuffer) methods.

Using either of these methods results in a default replacement (REPLACE) of malformed or untranslatable data.

This behavior can obscure errors in applications, and lead tounexpected characters, for example ?, in translated data. From IBM MQVersion 8.0, to detect such issues earlier and more effectively, theIBM MQ classes for Java use CharsetEncoders and CharsetDecodersdirectly and configure the handling of malformed and untranslatabledata explicitly.

From IBM MQ Version 8.0, the default behavior is to REPORT such issuesby throwing a suitable MQException.

...

Setting system defaults--

From IBM MQ Version 8.0, the following two Java system properties areavailable to configure default behavior regarding character stringconversion.

com.ibm.mq.cfg.jmqi.UnmappableCharacterAction Specifies the action to be taken for untranslatable data on encoding and decoding.The value can be REPORT, REPLACE, or IGNORE.

com.ibm.mq.cfg.jmqi.UnmappableCharacterReplacement Sets or gets the replacement bytes to apply when a character cannot be mappedin an encoding operation The default Java replacement string is usedin decoding operations.

To avoid confusion between Java character and native byterepresentations, you should specifycom.ibm.mq.cfg.jmqi.UnmappableCharacterReplacement as a decimal numberrepresenting the replacement byte in the native character set.

For example, the decimal value of ?, as a native byte, is 63 if thenative character set is ASCII-based, such as ISO-8859-1, while it is111 if the native character set is EBCDIC.


如果您想模仿之前的行为,您可以设置以下系统属性:

-Dcom.ibm.mq.cfg.jmqi.UnmappableCharacterAction=REPLACE
-Dcom.ibm.mq.cfg.jmqi.UnmappableCharacterReplacement=63

您也可以通过以下方式以编程方式设置它:

System.setProperty("com.ibm.mq.cfg.jmqi.UnmappableCharacterAction", "REPLACE");
System.setProperty("com.ibm.mq.cfg.jmqi.UnmappableCharacterReplacement", "63");

关于java - 特殊字符问题 : MQ message PUT error : java. nio.charset.UnmappableCharacterException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63935780/

38 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com