Java equivalent of perl unpack function - java

I have a perl code (say client) which sends packed data as HTTP POST to another perl code running on apache mod_perl module (say server).
In client side, I have the pack function like this,
$postData = pack("N a*", length($metaData), $metaData);
From perl pack document, it seems,
N -> An unsigned long (32-bit) in "network" (big-endian) order.
a -> A string with arbitrary binary data, will be null padded.
Now the $postData will be sent to server using perl LWP User Agent.
In the server side perl, we used to unpack like this,
# first reading the metaData Length
my $buf;
$request->read($buf, 4); #$request is apache request handler
my $metaDataLength = unpack("N", $buf);
# now read the metaData itself
$request->read($buf, $metaDataLength);
Now I have to do this server side data parsing in java (moving away from perl for some reasons). I have searched google for this and it seems to be not a single line solution as in perl. Some suggested to write our own unpack function. I am using java 1.7 version.
Is there any simple solution available in java for the above server side data parsing ?
Edit: Thanks Elliot for 'ByteBuffer' idea. The following code works fine for me,
InputStream is = request.getInputStream(); //request is HTTPServletRequest
byte[] bArr = new byte[4]; //reading first 4 bytes to get metaDataLength
int bytesRead = is.read(bArr);
ByteBuffer buf = ByteBuffer.wrap(bArr);
int metaDataLength = buf.getInt(); //shows value matches with clientside perl code.

potentially JBBP can be such one
final int value = JBBPParser.prepare("int;").parse(theInputStream).findFieldForType(JBBPFieldInt.class).getAsInt();

Related

Java > PHP Socket - trash at start of message

I have a java server communicating with a PHP script called from apache. I am aiming to send a JSON from the java server to the php client when requested, however there is some stuff getting prefixed when its received on the client.
JAVA
in = new BufferedReader(new InputStreamReader (socket.getInputStream()));
out= new DataOutputStream(socket.getOutputStream());
//The server receives a JSON from the PHP script and replies. It recives and converts to a Gson JSON no problem.
String reply = "{\"status\":\"reg\",\"token\":\""+client.getToken()+"\"}\r\n";
//reply = "HELLO\r";
out.writeUTF(reply);
PHP
$rec = socket_read($socket, 2048,PHP_NORMAL_READ);
echo "Receiving... ";
echo $rec;
The issue is that the message received is pre-fixed with some crap.
Output From PHP
Receiving... 1{"status":"reg","token":"QOPIPCNDI4K97QP0NAQF"}
If I send "HELLO\r"
Receiving... >HELLO
You shouldn't use DataOutputStream.writeUTF() unless you are using DataOutputStream.readUTF() to read the message.
Here is a snippet of the javadoc of writeUTF():
Writes a string to the underlying output stream using modified UTF-8
encoding in a machine-independent manner.
First, two bytes are written to the output stream as if by the
writeShort method giving the number of bytes to follow. This value is
the number of bytes actually written out, not the length of the
string. Following the length, each character of the string is output,
in sequence, using the modified UTF-8 encoding for the character. If
no exception is thrown, the counter written is incremented by the
total number of bytes written to the output stream. This will be at
least two plus the length of str, and at most two plus thrice the
length of str.
The bolded part above may tell you why you are getting weird characters at the beginning of your message.
Here is a workaround I believe will work in your case
BufferedOutputStream out = new BufferedOutputStream(socket.getOutputStream());
out.write(os.getBytes("UTF-8"));
Reference: Why does DataOutputStream.writeUTF() add additional 2 bytes at the beginning?

Using PHP to supply an in memory pdf from a Java generator

I am creating a web front end for clients to download their reports. The program that the company uses is written in Java and consists of 31 mysql tables with the 4 reports needed having over 140 points of data each. I am making the website in PHP and report generator in Java but I am having an issue finding the information on how to get the in memory PDF to load directly in the clients browser. I figured on using a TCP client/server going from Java to PHP but how do I code it so that it doesn't have to be written to the server drive and be supplied as a link. I also have no wish to rewrite 17,000 lines of Java to PHP as I am new to PHP. Is there anyway to get this done?
Thank you in advance.
Depending on how long the java app would take to run, you could consider using proc_open to create a pipe to the java programme:
<?php
$desc = array(array('pipe','r'),array('pipe','w'));
$resource= proc_open('bash',$desc,$pipes);
if (!is_resource($resource))
{
throw new Exception('PDF stream creation failed');
}
usleep(5);//for safety
fwrite($pipes[0],'java mkPDF paras'."\n");//double quoted \n is crucial
fclose($pipes[0]);
usleep(100);//while java app is running;
$pdf = stream_get_contents($pipes[1]);
fclose($pipes[1]);
proc_close($resource);
?>
This is just a basic example, that gets the streamed pdf in one big lump, so it's far from perfect. What you -IMO- should look into is getting the stream in chunks using a while loop. The php man page contains a couple of examples of this, basically, repleace
usleep(100);//while java app is running;
$pdf = stream_get_contents($pipes[1]);
with:
usleep(10);//while java app is running;
$pdf = '';
while (($pdfBuff = fgets($pipes[1],1024)) !== null)
{
$pdf.=$pdfBuff;//or echo, or whatever
}
fclose($pipes[1]);
The latter is untested, so I'm not sure if that will work in your case... but you get the idea
As said by #Elias directly send web request to java application and stream the pdf to php.
Using web services,
I. Develop some web services on java side that will send only data in any of the format like XML, jSon etc.
II. Write a code to consume these web services and develop your code to generate the pdf and stream these pdf's.
There is one pdf generating lib. Please find the link here

Client-side string encoding java

My team and I have this nasty problem with parsing a string received from our server. The server is pretty simple socket stuff done in qt here is the sendData function:
void sendData(QTcpSocket *client,QString response){
QString text = response.toUtf8();
QByteArray block;
QDataStream out(&block, QIODevice::WriteOnly);
out << (quint32)0;
out << text;
out.device()->seek(0);
out << (quint32)(block.size() - sizeof(quint32));
try{
client->write(block);
}
catch(...){...
The client is in Java and is also pretty standard socket stuff, here is where we are at now after trying many many different ways of decoding the response from the server:
Socket s;
try {
s = new Socket(URL, 1987);
PrintWriter output = new PrintWriter(s.getOutputStream(), true);
InputStreamReader inp = new InputStreamReader(s.getInputStream(), Charset.forName("UTF-8"));
BufferedReader rd = new BufferedReader( inp );
String st;
while ((st = rd.readLine()) != null){
System.out.println(st);
}...
If a connection is made with the server it sends a string "Send Handshake" with the size of the string in bytes sent before it as seen in the first block of code. This notifies the client that it should send authentication to the server. As of now the string we get from the server looks like this:
������ ��������S��e��n��d�� ��H��a��n��d��s��h��a��k��e
We have used tools such as string encode/decode tool to try and assess how the string is encoded but it fails on every configuration.
We are out of ideas as to what encoding this is, if any, or how to fix it.
Any help would be much appreciated.
At a glance, the line where you convert the QString parameter to a Utf8 QByteArray and then back to a QString seems odd:
QString text = response.toUtf8();
When the QByteArray returned by toUtf8() is assigned to text, I think it is assumed that the QByteArray contains an Ascii (char*) buffer.
I'm pretty sure that QDataStream is intended to be used only within Qt. It provides a platform-independent way of serializing data that is then intended to be deserialized with another QDataStream somewhere else. As you noticed, it's including a lot of extra stuff besides your raw data, and that extra stuff is subject to change at the next Qt version. (This is why the documentation suggests including in your stream the version of QDataStream being used ... so it can use the correct deserialization logic.)
In other words, the extra stuff you are seeing is probably meta-data included by Qt and it is not guaranteed to be the same with the next Qt version. From the docs:
QDataStream's binary format has evolved since Qt 1.0, and is likely to
continue evolving to reflect changes done in Qt. When inputting or
outputting complex types, it's very important to make sure that the
same version of the stream (version()) is used for reading and
writing.
If you are going to another language, this isn't practical to use. If it is just text you are passing, use a well-known transport mechanism (JSON, XML, ASCII text, UTF-8, etc.) and bypass the QDataStream altogether.

Java's new Base64(-1) in PHP?

I m trying to match java base64 code in php. But getting inconsistent result.
Java base64 encode
encMessage = URLEncoder.encode(new Base64(-1).encodeToString(encrypted),"UTF8");
Java decode
message = URLDecoder.decode(message,"utf8");
Above code java encode code return the string which i have to decode and decrypt in php
PHP base64 decode
$message = utf8_decode(urldecode($encrypted));
$message = base64_decode($message);
PHP encode
$encMessage = base64_encode($encrypted);
$encMessage = utf8_encode(urlencode($encMessage));
Results:
java:
KO%2F%2B%2Bzbp5z8oCdvZn62jb72kseT%2Bem8hYUZY0IuB9zo%3D
php:
KO%2F%2B%2Bzbp5z8oCdvZn62jb3CVVVXsV%2Bws2kDOmKK%2BPEc%3D
src : https://gist.github.com/944269
I had this problem between CSharp and Java, and found that URL encoding things was the culprit. What I did in my work around was basically re-encrypt the data with a newly generated public key until I got one that didn't need URL encoding. Not a great solution, but it works, it averages 2 tries to get it right, but I've seen it taking up to 15 tries to do it, either way we're still talking milliseconds, and it works reliably.
YMMV

Implementing zLib compression in Flex and Java

I am sending some JSON data from my Flex application to the Java side for business processing. Now on top of that, I have added some code to compress(zLib) the data at Flex side and then pass it through Request and uncompress the same at java side.
But at the java layer, the uncompressed data is still not in readable/usable format.
Putting the code in here for reference.
Flex code for encoding
var bytes:ByteArray = new ByteArray();
bytes.writeObject(JSON.encode(someObj));
bytes.position = 0;
bytes.compress();
variables.encodeJSONStr = bytes;
requester.data = variables;
loader.load(requester);
Java code for decoding
String json = req.getParameter("encodeJSONStr");
byte[] input = json.getBytes();
Inflater decompresser = new Inflater();
decompresser.setInput(input);
byte[] result = new byte[1000];
int resultLength=0;
resultLength = decompresser.inflate(result);
decompresser.end();
String outputString = new String(result, 0, resultLength, "UTF-8");
System.out.println("\n\n resultLength>>>"+resultLength); // O/P comes as Zero
Can someone point put the issue in here or some better approach for compression of data when sending from Flex to Java ?
Some time ago I wrote a short post about sending compressed data between flex/java, maybe it helps: http://cornelcreanga.com/2008/07/actionscript-compressing-strings/
First you should try if Flex does the zLib compression properly (by uncompressing the data sent with another tool).
On the Java side you can try to use the InflaterInputStream which is easier to handle than the more low level Inflater. I had some issues with the Java native implementation and ended up using the jZlib which offers a zlib compression uncompression in pure Java.

Categories