IBMMQ Chinease ISSUE

本文探讨了通过IBMMQ传输中文消息时出现乱码的原因,并提出了使用BytesMessage结合UTF-8编码来有效避免乱码问题的方法。
最近遇到一个问题,我们从一个IBM MQ 中收到的中文消息出现了乱码。

这是发送的消息 :
    <message>繁体中文</message>
当然,我们希望收到的消息跟发送消息一模一样。 不过实际收到的消息 却是:
    <message>?????</message>

问题出在哪里?要知道,一条消息从发送到接收经历了 发送端 --> MQ Server,MQ Server --> 接收端 的过程。任何一个环节的字符编码出了问题都有可能出现乱码。

凡涉及中文乱码的问题,解起来都是蛮头痛的。头痛的这里就不提了,记一下查到的资料还有一些心得,或许以后还有用:)

CCSID在Client端的设定
从这里(http: //middleware.its.state.nc.us/middleware/Documentation/en_US/htm/amqaac04/amqaac0418.htm) 可以看到MQ Server上面可以支援的编码方式及对应的CCSID
以下是一些常用的CCSID
819        ISO8859-1(Default)
1208       UTF-8
950          BIG5
1386          GBK

MQ Client在跟MQ Server连接的时候需要提供CCSID作为连接参数,推荐这个参数跟Server上的设定一致,不过并非要一致才可连接。如果不一致,则会增加MQ Server转码的额外负担。另外特定的字符集间也有可能无法互相转换,传送消息时便会报错。


Message Type 的选择策略
IBM MQ Online Help( http://publib.boulder.ibm.com/infocenter/wmqv6/v6r0/index.jsp)  上面有列出提供支援的消息形态(其实也就是JMS定义的几种消息形态)。其中比较常用的可能也就是TextMessage 跟BytesMessage。以下就是资料中对这两种Message Type的经典说明。
TextMessage
is an encoded string. For an outgoing message, the string is encoded in the character set given by the destination object. This defaults to UTF8 encoding (the UTF8 encoding starts with the first character of the message; there is no length field at the start). It is, however, possible to specify any other character set supported by WebSphere MQ Java. Such character sets are used mainly when you send a message to a non-JMS application.

If the character set is a double-byte set (including UTF16), the destination object's integer encoding specification determines the order of the bytes.

An incoming message is interpreted using the character set and encoding that are specified in the message itself. These specifications are in the last WebSphere® MQ header (or MQMD if there are no headers). For JMS messages, the last header is usually the MQRFH2.

BytesMessage
is, by default, a sequence of bytes as defined by the JMS 1.0.2 specification and associated Java documentation.

For an outgoing message that was assembled by the application itself, the destination object's encoding property can be used to override the encodings of integer and floating point fields contained in the message. For example, you can request that floating point values are stored in S/390® rather than IEEE format).

An incoming message is interpreted using the numeric encoding specified in the message itself. This specification is in the rightmost WebSphere MQ header (or MQMD if there are no headers). For JMS messages, the rightmost header is usually the MQRFH2.

If a BytesMessage is received, and is re-sent without modification, its body is transmitted byte for byte, as it was received. The destination object's encoding property has no effect on the body. The only string-like entity that can be sent explicitly in a BytesMessage is a UTF8 string. This is encoded in Java UTF8 format, and starts with a 2-byte length field. The destination object's character set property has no effect on the encoding of an outgoing BytesMessage. The character set value in an incoming WebSphere MQ message has no effect on the interpretation of that message as a JMS BytesMessage.

Non-Java applications are unlikely to recognize the Java UTF8 encoding. Therefore, for a JMS application to send a BytesMessage that contains text data, the application itself must convert its strings to byte arrays, and write these byte arrays into the BytesMessage.

    其实要用MQ来传递中文消息,不管这个MQ是哪方提供的,那么使用BytesMessage可以比较容易的避免乱码的问题。作法上 推荐在发送端先用UTF-8对消息编码,再放入BytesMessage。因为是字节形态,所以在传送过程中不会对其重新编码,就避免了可能出现的乱码。 在接收方收到消息后只要以UTF-8解码,就能得到正确的消息内容了。
    使用TextMessage来传递中文消息要比使用BytesMessage的方式更容易出现乱码。如果一定要用,则需注意对于消息对象发送时的处理,除 了要使字符串的编码方式跟MQ Server上的设定一致以外,可能还需要特别在消息头中设定该消息的字符集信息。前者是为了让MQ Server在处理消息的时候正确辨识消息的内容,后者则是为了让消息的接收方在收到消息后可以依照消息头中设定的字符集信息对其内容正确的解码。

--END
 
<think> 首先,用户的问题是关于理解一个特定的正则表达式:/^(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9]).{8,}$。我需要解释这个正则表达式的含义。 回顾系统级指令: - 所有行内数学表达式必须使用$...$格式。 - 独立公式必须使用$$...$$格式并单独成段。 - LaTeX语法正确。 - 使用中文回答。 - 生成相关问题。 - 回答中引用的段落末尾自然地添加引用标识。 - 回答结构清晰,帮助用户逐步解决问题。 - 最后,生成相关问题。 用户提供了三个引用: - 引用[1]:关于常见正则表达式,如正浮点数。 - 引用[2]:包含各种正则表达式的例子,如字母数字下划线字符串、整数、浮点数、中文字符、身份证号等。 - 引用[3]:关于正则表达式的简化建议。 但用户说这些引用仅供参考,我应该基于用户的问题来回答。用户的问题是解释正则表达式/^(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9]).{8,}$的含义。 所以,我需要解析这个正则表达式。 分解正则表达式- /^:表示字符串的开始。 - (?=.*[A-Z]):这是一个正向先行断言(positive lookahead)。意思是:字符串中必须包含至少一个大写字母(A-Z)。 - (?=.*[a-z]):另一个正向先行断言,表示字符串中必须包含至少一个小写字母(a-z)。 - (?=.*[0-9]):另一个正向先行断言,表示字符串中必须包含至少一个数字(0-9)。 - .{8,}:表示任意字符(除换行符外)至少8次。意思是字符串长度至少为8个字符。 - $:表示字符串的结束。 所以,整体来看,这个正则表达式匹配的字符串必须: 1. 包含至少一个大写字母。 2. 包含至少一个小写字母。 3. 包含至少一个数字。 4. 长度至少为8个字符。 这通常用于密码强度验证,要求密码有大小写字母、数字,并且长度至少8位。 现在,构建回答: - 使用中文。 - 结构清晰:逐步解释。 - 引用相关部分:用户提供了引用,但它们是关于其他正则表达式的。我可以提到引用[2]中有类似的正则表达式例子,比如强密码的表达式,但用户的具体表达式不同。引用[2]中有类似的东西:/^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{6,15}$/,这很相似,但长度不同。 在引用[2]中:强密码:必须包含数字、字母,字符长度为6~15位 /^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{6,15}$/ 或 /^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])[0-9a-zA-Z]{6,15}$/。 用户的正则是/^(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9]).{8,}$,长度至少8,没有上限,并且使用.*允许任何字符。 所以,在回答中,我可以引用这个。 引用[3]是关于简化正则表达式的建议,但可能不直接相关。 回答结构: 1. 介绍正则表达式的整体目的:用于验证密码强度。 2. 分解表达式部分: - ^$:表示整个字符串。 - (?=.*[A-Z]):解释先行断言的含义。 - 类似地解释其他部分。 - .{8,}:长度要求。 3. 总结匹配的条件。 4. 自然地添加引用:例如,在解释先行断言时,可以提到引用中的类似例子。 引用标识:在引用的段落末尾添加[^n]。 最后,生成相关问题。 相关问题应该基于这个主题,比如: 1. 如何使用这个正则表达式在代码中? 2. 这个正则表达式的局限性是什么? 3. 如何修改它来添加特殊字符要求? 4. 相关的正则表达式例子。 确保LaTeX:在回答中,如果有数学表达式,比如.*[A-Z],这不算数学表达式,所以不需要用$...$。但如果有像范围或计数,可能不需要。指令是针对数学表达式的,所以这里可能不适用。 在引用中,用户有像^[1-9]\d*\.\d*|0\.\d*[1-9]\d*$这样的表达式,但没有要求用LaTeX格式。指令说“所有行内数学表达式(包括变量、不等式、方程等)必须使用$...$格式”,但正则表达式不是数学表达式,所以我应该直接写正则表达式。 在回答中,我会直接写正则表达式代码,用反引号表示代码块或内联代码。 指令有示例:在“快速排序”例子中,有代码块用```python```。 所以,我可以将正则表达式放入代码块。 回答步骤: 1. 解释整体含义。 2. 分解每个部分。 3. 给出示例匹配的字符串。 4. 引用相关资源。 5. 生成相关问题。 用中文。 </think> ### 正则表达式 `/^(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9]).{8,}$` 的含义解析 这个正则表达式主要用于验证密码强度,要求字符串满足特定的复杂度条件。以下我将逐步分解其结构,帮助您理解每个部分的含义。整个表达式的核心是使用**正向先行断言(positive lookahead)** 来确保字符串中包含大写字母、小写字母和数字,同时要求最小长度。正则表达式语法可参考站内引用中的常见模式[^2]。 #### 1. **整体结构** - `/^ ... $/`:这表示正则表达式匹配整个字符串,从开头 (`^`) 到结尾 (`$`)。例如,字符串 `"Abc12345"` 会被匹配,但 `" Abc12345"`(开头有空格)则不会,因为空格导致开头不匹配。 - 表达式由多个部分组成: - 三个正向先行断言 `(?=...)`:用于检查字符串是否满足某些条件,但不消耗字符(即不移动匹配位置)。 - `.`:匹配任意单个字符(除换行符外)。 - `{8,}`:表示前面的模式(这里是 `.`)至少重复 8 次,即字符串长度至少为 8 个字符。 - **简言之**:这个正则表达式要求字符串**必须同时包含至少一个大写字母、至少一个小写字母、至少一个数字,且总长度不少于 8 个字符**。它常用于密码策略中,确保密码强度。 #### 2. **分解每个部分** - `(?=.*[A-Z])`: - `(?= ... )` 是正向先行断言,表示“字符串必须满足括号内的条件”,但不计入匹配位置。 - `.*`:匹配零个或多个任意字符(`.` 表示任意字符,`*` 表示重复零次或多次)。 - `[A-Z]`:匹配一个大写字母(A 到 Z)。 - **含义**:字符串中必须包含至少一个大写字母。例如,在 `"abc123"` 中不满足(没有大写字母),而 `"Abc123"` 满足。 - 类似用法在引用[2]中的“强密码”例子中出现过(如 `/^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{6,15}$/`)[^2]。 - `(?=.*[a-z])`: - 结构同上,但 `[a-z]` 匹配一个小写字母(a 到 z)。 - **含义**:字符串中必须包含至少一个小写字母。例如,`"ABC123"` 不满足(没有小写字母),而 `"Abc123"` 满足。 - `(?=.*[0-9])`: - `[0-9]` 匹配一个数字(09)。 - **含义**:字符串中必须包含至少一个数字。例如,`"Abcdefg"` 不满足(没有数字),而 `"Abc123"` 满足。 - `.{8,}`: - `.` 匹配任意字符。 - `{8,}` 表示前面的 `.` 至少重复 8 次,即字符串长度至少为 8 个字符。 - **含义**:整个字符串的最小长度为 8。例如,`"Abc123"`(长度 6)不满足,而 `"Abc12345"`(长度 8)满足。 #### 3. **组合效果和示例** - **匹配条件总结**: - 至少一个大写字母(A-Z)。 - 至少一个小写字母(a-z)。 - 至少一个数字(0-9)。 - 长度至少 8 个字符(允许更长)。 - 字符类型不限(因为 `.` 匹配任意字符,包括符号如 `!@#$`)。 - **有效匹配示例**: - `"Password123"`:包含大写 P、小写 assword、数字 123,长度 11。 - `"Abc!12345"`:包含大写 A、小写 bc、数字 12345,以及符号 `!`,长度 9- **无效匹配示例**: - `"password"`:缺少大写字母和数字。 - `"PASSWORD123"`:缺少小写字母。 - `"Abc123"`:长度不足 8。 - `"!@#$%^&*"`:缺少字母和数字。 这个表达式确保了密码的基础强度,但未要求特殊字符(如符号),您可以根据需求扩展。类似的正则表达式设计原则在引用[3]中提到,强调“宁简勿繁”,即拆解复杂条件为多个简单断言以提升可读性和效率[^3]。 #### 4. **实际应用** - 在编程中,这个正则表达式可用于表单验证(如密码输入框)。例如,在 JavaScript 中: ```javascript const regex = /^(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9]).{8,}$/; console.log(regex.test("Abc12345")); // 输出 true console.log(regex.test("abc1234")); // 输出 false(缺少大写字母) ``` - 优点:使用先行断言能高效检查多个条件,无需嵌套或复杂逻辑。 - 局限性:它不检查字符类型重复(如多个数字),或特殊字符要求。如果需更严格规则(如包含符号),可追加断言,例如添加 `(?=.*[!@#$%^&*])`。 如果您有更多上下文(如具体代码实现),我可以提供更针对性的帮助。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值