Azure Service Bus接收JSON时尾部出现重复字段问题求助
解决Azure Service Bus接收JSON时尾部字段重复的问题
兄弟,你的问题根源在于读取消息体时的字节数组处理不当!
问题原因分析
你用了固定大小(200字节)的byte[] b来循环读取输入流,每次读取后直接把整个数组转成字符串:
s = new String(b);
当最后一次读取的字节数小于200时,数组里还残留着上一次读取的剩余字节,这些残留内容会被一起转成字符串,就导致了你看到的JSON末尾重复字段的问题。举个例子:假设最后一次只读到50字节,那数组里剩下的150字节是上一次读取的旧数据,直接转字符串就会把这些旧数据也带出来。
解决方案
方案1:正确处理每次读取的有效字节长度
用StringBuilder拼接每次读取的有效字节块,只转换实际读到的字节数,而不是整个数组:
import java.nio.charset.StandardCharsets; // ... if (message != null && message.getMessageId() != null) { System.out.println("MessageID: " + message.getMessageId()); System.out.print("From queue: "); byte[] b = new byte[200]; StringBuilder messageBuilder = new StringBuilder(); int numRead = message.getBody().read(b); System.out.println("numread--"+numRead); while (-1 != numRead) { // 仅转换本次读取的numRead个字节,避免残留旧数据 String chunk = new String(b, 0, numRead, StandardCharsets.UTF_8); messageBuilder.append(chunk); numRead = message.getBody().read(b); } String fullJson = messageBuilder.toString().trim(); System.out.println(fullJson); }
这里额外指定了StandardCharsets.UTF_8编码,避免不同环境下默认编码不一致导致的乱码问题,更稳妥。
方案2:用工具类一次性读取整个流(更简洁)
如果你的项目是Java 9及以上,可以直接用InputStream.readAllBytes()一次性读取所有字节,省掉循环处理:
import java.nio.charset.StandardCharsets; // ... if (message != null && message.getMessageId() != null) { System.out.println("MessageID: " + message.getMessageId()); System.out.print("From queue: "); byte[] allBytes = message.getBody().readAllBytes(); String fullJson = new String(allBytes, StandardCharsets.UTF_8).trim(); System.out.println(fullJson); }
如果项目里依赖了Apache Commons IO库,也可以用IOUtils.toString()来简化:
import org.apache.commons.io.IOUtils; import java.nio.charset.StandardCharsets; // ... if (message != null && message.getMessageId() != null) { System.out.println("MessageID: " + message.getMessageId()); System.out.print("From queue: "); String fullJson = IOUtils.toString(message.getBody(), StandardCharsets.UTF_8).trim(); System.out.println(fullJson); }
这种方式完全不用手动处理流的循环读取,代码更简洁,出错概率更低。
额外优化建议
发送消息时其实可以直接传入对象而非JSON字符串,让BrokeredMessage自动序列化,接收时也可以直接反序列化为对象,这样能避免手动处理JSON字符串的麻烦:
// 发送端 YourObject obj = new YourObject(); BrokeredMessage message = new BrokeredMessage(obj); // 接收端 YourObject receivedObj = message.getBody(YourObject.class);
如果必须用JSON字符串,也建议用Jackson/Gson等库来序列化/反序列化,比手动处理字符串更可靠。
内容的提问来源于stack exchange,提问作者nikita kakraniya




