发送至MQ的JMS消息含转义字符致JSON转换异常 如何去除消息内反斜杠
问题根因
出现接收端看到多余反斜杠、JSON解析异常的情况,核心是两个可复现的代码/配置问题:
- 手动拼接JSON字符串的写法本身存在转义逻辑缺陷。你在
toString()里手动拼的JSON结构,不会对字段值里的双引号、反斜杠等JSON特殊字符做正确的转义处理,传输过程中很容易出现字符串结构混乱,进而导致解析端识别到多余的转义符号。 - 你执行
replaceAll("\\\\", "")找不到匹配内容,本质上是因为你看到的反斜杠并不是实际存在于消息文本中的字符,而是Spring JMS消息转换器二次序列化时产生的编码层转义效果。直接对原始消息文本做替换,根本触碰不到编码层的转义逻辑,自然匹配不到目标内容。
可落地的解决方案
立刻替换手动拼接JSON的消息生成逻辑
放弃用toString()方法生成MQ发送内容,改用成熟的JSON序列化工具(Jackson、Fastjson等)将DTO直接序列化为标准JSON字符串,从根源上避免手动拼转义的bug。示例代码如下:// 定义全局复用的Jackson序列化实例 private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); /** * 生成符合JSON规范的消息内容,替代原有手动拼接的toString逻辑 */ public String buildJsonMessage() { try { // 自动处理所有字段的特殊字符转义,输出标准JSON格式字符串 return OBJECT_MAPPER.writeValueAsString(this); } catch (JsonProcessingException e) { throw new IllegalStateException("DTO序列化JSON消息失败", e); } }原有的
toString()方法可以保留,专门用来打印调试日志,不要承担业务消息序列化的职责。统一发送端和接收端的JMS消息转换器配置
你目前使用TextMessage传输纯文本本身不存在自动加反斜杠的逻辑,接收端看到多余转义符,大概率是Spring Boot默认装配的MappingJackson2MessageConverter开启了二次序列化:
这个转换器会自动把拿到的纯文本消息当成普通字符串,再次做一次JSON编码——也就是你本来传的是{"A":"test"},经过二次编码后会变成"{\"A\":\"test\"}",这就是多余反斜杠的来源。
调整时保持两边规则一致即可:- 如果启用了JSON消息转换器,就不要手动把对象转成字符串再发送,直接把DTO对象传给
jmsTemplate.send(),让转换器统一完成序列化、反序列化流程; - 如果需要手动发送
TextMessage,就关闭对应消息转换器的自动类型编码、二次序列化逻辑,避免对纯文本消息做额外编码。
- 如果启用了JSON消息转换器,就不要手动把对象转成字符串再发送,直接把DTO对象传给
基于实际消息内容排查,不要依赖日志显示判断
很多时候你在日志里看到的反斜杠,只是日志框架打印对象时对字符串做的转义显示,不是消息里的实际内容。排查时直接调用TextMessage的getText()方法拿到原始文本,逐字符核对实际内容,不要直接打印整个Message对象(Message的toString()方法会对内部存储的字符串做转义展示,很容易误导排查方向)。
避坑提醒
- 不要用字符串替换的方式处理JSON转义问题。
replaceAll的第一个参数是正则表达式,\\是正则的转义标识,你写的replaceAll("\\\\", "")实际匹配的是文本里的单个反斜杠。但如果反斜杠是编码层自动生成的,强行删除反而会破坏JSON的合法结构——比如把JSON里本来合法的\"(表示字符串内部的双引号)删掉,导致解析逻辑更混乱。 - 不要把日志打印用的
toString()逻辑当成业务序列化逻辑。toString()的设计目的是输出便于人读的调试信息,本身不需要满足结构化传输的规范,把业务序列化和日志逻辑混在一起,很容易出现日志显示正常、实际传输内容异常的问题。
内容的提问来源于stack exchange,提问作者xcoder
相关产品推荐
相关产品推荐

