Parse JSON packet input in java - java

I have a TCP socket connected to a server communicating via JSON. Since it's a stream the packets often merge into one larger through the inputstream, and I've been trying to parse it correctly but haven't found a successful way to read the input.
The input looks something like this
+#$3{"data1":"datahere","moredata":25}2*${"data1":"differentdata","otherdata":001}
This I have parsed to be
{"data1":"datahere","moredata":25}{"data1":"differentdata","otherdata":001}
Using a reader only returns the first json object when it is set to lenient, otherwise it throws an exception. The JSON comes from a socket, and is a result of packet merging. What can be done in a JSON library to parse these separately?

Related

HL7V2 HAPI parser exception while receiving data via TCP/IP

I'm using the HAPI hapi-structures-v25 library with version 2.3 to parse HL7v2 message & convert that into FHIR resources. I'm facing a strange issue while receiving and parsing the HL7V2 message using HAPI via TCP listener.
Determine encoding for message. The following is the first 50 chars of the message for reference, although this may not be where the issue is: MSH|^~\&|test|DrJhonDoe|TEST|UNKNOWN|20210216190432||ADT^A01^ADT_A01|60b647d4-b5a5-4fae-a928-d4a3849de3c8|T|2.5
Strange that I'm not getting this error when I'm trying to send this message as a string in main function. I'm getting this error only when I receive the data over TCP/IP to my Java function. I tried sending the HL7 message to my receiving TCP port using Mirth as well external tool & my result is same.
Here is the sample of my HL7v2 message Im trying to process
MSH|^~\\&|test|Dr.JhonDoe|TEST|UNKNOWN|20210216190432.7||ADT^A01^ADT_A01|60b647d4b5a54faea928d4a3849de3c8|T|2.5
EVN||20210216|20210216|
While receiving the data from tcp/ip im converting the byte to string using the UTF-8 charset.
InputStream in = connection.getInputStream();
OutputStream out = connection.getOutputStream();
receivedMessageSize = in.read(receivedByeBuffer);
String incomingHl7Message = new String(receivedByeBuffer, StandardCharsets.UTF_8);
Im getting the message properly. But not sure why the error comes.
As mentioned in the answer by Amit, it needs to be escaped in JAVA. The HL7v2 when transmitted via MLLP it adds <VT>, <CR> Unicode data to the text. The understanding needed here is that these are not junk characters. By the protocol of MLLP the starting and ending of the messages are marked by these unicode characters to describe the starting and ending of a frame.
The HAPI HL7 parse cannot parse these special (non-printable) characters. Happy that I've found a solution on the same forum to handle it in java wisely. How to remove control characters from java string?
A simple regex will do the trick as shown below:
.replaceAll("[\\p{Cntrl}&&[^\r\n\t]]", "");
Also make sure that you're encoding characters are also handled properly with JAVA. Usually JAVA is not good in handling backslash. So, escape the backslash .replace("\\", "\\\\")
This will do the trick.

Sending JSON from Python to Java

I'm trying to send JSON from a Python client to a Java server
The JSON data type is bytes (in Python) and when I deserialize it (in Python) and print it, it looks perfect. The server works fine when a Java client connects and when I deserialize the JSON and print it in Java it looks exactly the same as in Python and the actual JSON files. The JSON all looks good, but the data isn't accepted by the Java server.
data = open(file_path, 'r').read() # reading JSON object as string
serialized_data = pickle.dumps(data)
s.send(serialized_data)
When I send a JSON file the Java server acknowledges the connection but the JSON data for whatever reason isn't accepted.
Java Client
String sentence = new String(readFile());
if(!sentence.equals("fileNotFound")) {
ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
oos.writeObject(sentence);
}
Java Server
ObjectInputStream inFromClient = new ObjectInputStream(socket.getInputStream());
String clientString = null;
try {
clientString = (String) inFromClient.readObject();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
inFromClient.close();
You appear to be doing this:
Read JSON from file as a String
Pickle the string
Send the pickle to Java.
That won't work. A pickle is a Python-specific serialization format. Java doesn't understand it.
The data you are reading from the file is already serialized .... as JSON.
Solution: send the string containing the JSON without pickling it.
On the other hand, if the Java server expects to receive something that has been serialized using ObjectOutputStream, then you have a bigger problem. The Java Object Serialization protocol is Java specific. Python doesn't support it. But if you are actually sending JSON to the server you should need to do that. Change the server to accept JSON, and get rid of the ObjectInputStream / ObjectOutputStream code on both sides.
On the third hand, if you can't get rid of the ObjectInputStream / ObjectOutputStream stuff, then maybe you need to modify the server side to either provide a separate API for python to call, or get the server to check the request's "content-type" header and handle either form of data serialization (JSON and Object Serialization protocol)

Java socket Input stream read is getting hangs intermittently

We have client - server application developed using java socket programming.
My problem is sometime(intermittently) client is getting hang / blocked while reading data from socket input stream which making connection between client and server unresponsive. I have to restart either server or client to temporary fix this issue
The message which server sends to client is composed of two part a.header
b.body
Header : my header data is plain and i retrieve header data by reading a character at a time from input stream.
Body : body data can be in plain or zip format. I retrieve body data by either reading Inputstream or GZIPInputStream.

sending JSON data to client using writeandflush() from netty showing Invalid JSON type

I'm using java code for sending JSON data to flash for that I'm using netty server 4.0.23.
By that I'm using two different data to send to the same client frequently. I used channel.writeAndFlush(). So far everything happens good, while receiving data in client both the data are merged together and gives Invalid Json.
I traced the sending data in java there it is in correct format. It is getting invalid while receiving in client side. The two different JSON data are merged into a single JSON Data, so that the Invalid Json type error is occuring. If I put timer delay in between the two data, then the data are correctly received in client side. How can I receive proper data without applying the delay inbetween the data while sending.....
I used the following pipelines
pipeline.addLast(new DelimiterBasedFrameDecoder(8192, Delimiters.lineDelimiter()));
pipeline.addLast(new StringDecoder());
pipeline.addLast(new StringEncoder());
pipeline.addLast("handler", new ServerHandler());
It sounds like your client (the receiving part) does not handle the received JSON messages properly. TCP is streaming protocol, which means two writes on one side can be seen as one read on the other side. For example, when a server sends "A" and "B", a client will not always see "A" and "B" but will sometimes see "AB", and it's fully fine.
To deal with this sort of situation, you need to 'frame' a message. It is usually done in Netty by inserting a framing decoder.
In your case, the client is written in Flash, so you'd better simply use XMLSocket and let your server delimit each JSON message with NUL (0) byte.
If you are interested in framing, please read the Netty user guide.

Problem in converting InputStream to String

I have created a java program which acts as Rest Web Server. It gets the http request and send response. I am getting the http request as Input Stream inside my server. I want to convert this Input stream to String and then want to parse string according to some predefined pattern. The problem is when I get the input Stream and tries to convert it to String, it will not finish the operation until new request comes or the original request is terminated. If any of these two events happen only then the Input stream is successfully converted to string otherwise itjust gets hanged there. Am I missing any thing ? Any Suggestions will be very helpful.
ServerSocket service = new ServerSocket(Integer.parseInt(argv[0]));
Socket connection = service.accept();
InputStream is = connection.getInputStream();
String ss = IOUtils.toString(is);
System.out.println("PRINT : "+ss);
Now the ss is only printed when the old request is terminated or the new request is accepted at socket. I want to convert it to string within the same request.
Please Suggest me what i am doing wrong?
Thanks,
Tara Singh
You should read the request in steps. First read the headers, line for line. Then, if it's a POST request, there will be a request body. If that's the case, you should have read a Content-Length header before, which says how long the body is in bytes. You should read that number of bytes from the input stream.
Most of that is already handled for you if you make this app as a servlet, or if that's not possible, using an HTTP server library.
What you are doing wrong is that you want to convert a stream to a string a operation that is only possible when the stream is finished. That is why you get your string when the connection is terminated. How else is the method toString supposed to know when there is no more data comming and it should begin the conversion? What if it spits a string and in the meantime more data arrive in the stream? I guess you won't be happy then too :)
In short: you must somehow know when you are finished receiving before converting to string. Redesign your app.

Categories