I am trying to receive Azure Queue Message from Java. I am able to receive message using BrokeredMessage in java. (I am novice to java).

My problem is message.getBody() is returning some header information as well (Not just the message as I need).

I get     string3http://schemas.mi@string3http://schemas.microsoft.com/2003/10/Serialization/?? message appended with my body in front of it. How can I get rid of this header information.

And I also I noticed i get message in two batches. (Not the whole lot at once)

My first batch of message.getBody()returns below message
'@string3http://schemas.mi'
My Second batch of message.getBody()returns below message
@crosoft.com/2003/10/Serialization/?? + My actual message.

MY total message size is less than 500B, But I have set byte size to 4096. So is is not splinting because of size issue.

This is my receiver code I use.

ReceiveMessageOptions opts = ReceiveMessageOptions.DEFAULT;
opts.setReceiveMode(ReceiveMode.PEEK_LOCK);

while (true)
{
ReceiveQueueMessageResult resultQM =
service.receiveQueueMessage("MyqueueName", opts);
BrokeredMessage message = resultQM.getValue();
if (message != null && message.getMessageId() != null)
{

byte[] b = new byte[4096];
String s = null;
int numRead = message.getBody().read(b);
while (-1 != numRead)
{
s = new String(b);
s = s.trim();
System.out.print(s);
numRead = message.getBody().read(b);
}
}

}

This is the total output of System.out.print(s);. (But in two batches as I mentioned before)

total output
string3http://schemas.microsoft.com/2003/10/Serialization/??+ My actual message.

Any Help is much appreciated!

2

There are 2 best solutions below

0
On

I think you are getting the above sample from here. Before proceeding with the Code, we need to understand about Receive Mode Lock types which are PeekLock and ReceiveAndDelete

ReceiveAndDelete:

When using the ReceiveAndDelete mode, receive is a single-shot operation - that is, when Service Bus receives a read request for a message in a queue, it marks the message as being consumed and returns it to the application. ReceiveAndDelete mode (which is the default mode) is the simplest model and works best for scenarios in which an application can tolerate not processing a message in the event of a failure. To understand this, consider a scenario in which the consumer issues the receive request and then crashes before processing it. Because Service Bus will have marked the message as being consumed, then when the application restarts and begins consuming messages again, it will have missed the message that was consumed prior to the crash.

PeekLook:

In PeekLock mode, receive becomes a two-stage operation, which makes it possible to support applications that cannot tolerate missing messages. When Service Bus receives a request, it finds the next message to be consumed, locks it to prevent other consumers receiving it, and then returns it to the application. After the application finishes processing the message (or stores it reliably for future processing), it completes the second stage of the receive process by calling Delete on the received message. When Service Bus sees the Delete call, it will mark the message as being consumed and remove it from the queue.

You are trying with the PeekLock Mode, in which you need to explicitly call the deleteMessage(message) in order to mark the message as being consumed unless you didn't call this method, even though it looks like consumed, but it not actually consumed. It still in the Queue.

I think the header which you are mentioning is not the actual header, it was the initial message in the queue, which is actually not consumed at all

You can check this like change your code like the below and try

if (message != null && message.getMessageId() != null)
{

byte[] b = new byte[4096];
String s = null;
int numRead = message.getBody().read(b);
while (-1 != numRead)
{
s = new String(b);
s = s.trim();
System.out.print(s);
numRead = message.getBody().read(b);
}
//Add the below to ack that you are consumed the message
service.deleteMessage(message);
}    
}
0
On

Thanks, Jayendaran for your response. Chaing the mode type from PeekLock to ReceiveAndDelete did not solve the issue.

However, I found the solution Steaming the message before sending solves the problem.

Instead of this

BrokeredMessage message = new BrokeredMessage(encryptData);
message.ContentType = "application/json";
testQueueSender.Send(message);

Do this to sovle the problem

byte[] bytes = Encoding.UTF8.GetBytes(encryptData);
MemoryStream stream = new MemoryStream(bytes, writable: false);
BrokeredMessage message = new BrokeredMessage(stream);
message.ContentType = "application/json";
testQueueSender.Send(message);

But I still receive the message in two parts for some reason. the first part is 27 bytes fixed all the time. But I don't have this problem in.NET.

Regards