Compress object to a string or a hash and and viceversa? - java

I am trying to do this...
I have a big object that I need to send from the backend to the view and from that view to other backend as parameter in a GET post. So, since I cannot send all the object, I thought about make it a very small string or a number, and for this I tried doing this.
First I converted the object to JSON, using JSONObject,but due the special characters I cannot take it as a normal string (it has many ", /, {},....) so, I thought make it a byte, but I am not sure if is a correct approach, any idea how to do this?
Or something similar to have my object in an acceptable GET parameter for the URL.
So far I only have this code.
byte[] foo = new JSONObject(myObject).toString().getBytes();
String bar = foo.toString();
But dont know who to parse it back to byte and have not even tried to parse it back to JSON, any idea?
I am using spring and I dont have gson or jackson for convert to json an object.

Related

Is it possible to return an image and strings in one Json object to a client

I'm doing a project of mine and I'm trying to return an Json object with an image and some other data to the client, is this possible? And if its not, if I return the image as a byte array or base64 would a frontender be able to convert it back to an actual image or the conversion should be done on my end?
{
"author": "Uponn",
"title": "Some title",
"likes": 10000000,
"file": *image here*,
"uploadTime": null
}
Answer is: depends.
I'm doing a project of mine and I'm trying to return an Json object with an image and some other data to the client, is this possible?
You are the one defining the API/interface of your application. If you want that this service returns a JSON object that contains that data, then yes: that is possible.
if I return the image as a byte array or base64 would a frontender be able to convert it
Sure. If you clearly specify what exactly the service is doing. So: when your backend reads the raw bytes of some image from disk, and puts these bytes (somehow encoded, maybe using base64) into a string. Sure, then any client should be able re-build the raw bytes, to then do with that information whatever the user wants to use them for.
In other words: nothing you ask for is technically impossible. The key thing for you to understand: we can't tell you your requirements. You have to identify why and how people will want to use your service(s). And then you design them in ways that support the agreed on use cases.

Parseing JSON Array with unnamed fields with GSON

So I want to parse flightradar24.com data into a Java program. The data seems to be JSON-ish and thus I am trying to read it using GSONs JSonParser.
Here is a short excerpt of what I try to parse (you can see it in full e.g. in http://arn.data.fr24.com/zones/italy_all.js?callback=pd_callback):
pd_callback({"45da286":["4CAAB6",43.5609,12.6837,211,34975,420,"7311","F-LIBP2","B772","EI-ISA",1411143824,"NRT","FCO","AZ785",0,0,"AZA785",0],
"45dae4b":["7809B9",47.5892,15.8256,204,36000,442,"7303","F-LKTB2","A332","B-5921",1411143824,"PVG","FCO","MU787",0,0,"CES787",0],
"45dae73":["76CEF7",47.6238,17.2440,291,36000,428,"0342","F-LKTB1","B77W","9V-SWW",1411143826,"SIN","LHR","SQ318",0,0,"SIA318",0],
"45db3e2":["71BC61",46.0211,10.0549,242,22800,344,"7313","F-LIPE1","B744","HL7461",1411143824,"ICN","MXP","KE927",0,-2176,"KAL927",0],
"full_count":10394,"version":4});
Each line in the example above resembles the data of a certain flight at that moment, with id, lat, lon, and so on. I have removed pd_callback(...); and just to try it I removed ""full_count":10394,"version":4" as well. When I try to parse this string to an iterable JSON Object Array, e.g. like this:
com.google.gson.JsonParser jsonParser = new JsonParser();
com.google.gson.JsonArray jsa = jsonParser.parse(line).getAsJsonArray();
I always get parsing errors. I think one of the problems is that the field names are not given and the syntax might be wrong, but thats actually how flightradar reads the data. In the end, I just want to be able to iterate through each flight and to read each attribute as a primitive to then feed it into my own objects.
Anyone with an idea where the problem is or how I can parse this kind of data conveniently? Any comments appreciated.

Jackson JSON Streaming API: Read an entire object directly to String

I'm trying to stream in an array of JSON, object by object, but I need to import it as a raw JSON String.
Given an array of input like so:
[
{"object":1},
{"object":2},
...
{"object":n}
]
I am trying to iterate through the Strings:
{"object":1}
{"object":2}
...
{"object":n}
I can navigate the structure using the streaming API to validate that I have encountered an object, and all that, but I think the way I'm getting my String back is ideal.
Currently:
//[...]
//we have read a START_OBJECT token
JsonNode node = parser.readValueAsTree();
String jsonString = anObjectMapper.writeValueAsString(node);
//as opposed to String jsonString = node.toString() ;
//[...]
I imagine the building of the whole JsonNode structure involves a bunch of overhead, which is pointless if I'm just reserializing, so I'm looking for a better solution. Something along the lines of this would be ideal:
//[...]
//we have read a START_OBJECT token
String jsonString = parser.readValueAsString()
//or parser.skipChildrenAsString()
//[...]
The objects are obviously not as simple as
{"object":1}
which is why I'm looking to not waste time doing pointless node building. There may be some ideal way, involving mapping the content to objects and working with that, but I am not in a position where I am able to do that. I need the raw JSON string, one object at a time, to work with existing code.
Any suggestions or comments are appreciated. Thanks!
EDIT : parser.getText() returns the current token as text (e.g. START_OBJECT -> "{"), but not the rest of the object.
Edit2 : The motivation for using the Streaming API is to buffer objects in one by one. The actual json files can be quite large, and each object can be discarded after use, so I simply need to iterate through.
There is no way to avoid JSON tokenization (otherwise parser wouldn't know where objects start and end etc), so it will always involve some level of parsing and generation.
But you can reduce overhead slightly by reading values as TokenBuffer -- it is Jackson's internal type with lowest memory/performance overhead (and used internally whenever things need to be buffered):
TokenBuffer buf = parser.readValueAs(TokenBuffer.class);
// write straight from buffer if you have JsonGenerator
jgen.writeObject(buf);
// or, if you must, convert to byte[] or String
byte[] stuff = mapper.writeValueAsBytes();
We can do bit better however: if you can create JsonGenerator for output, just use JsonGenerator.copyCurrentStructure(JsonParser);:
jgen.copyCurrentStructure(jp); // points to END_OBJECT after copy
This will avoid all object allocation; and although it will need to decode JSON, encode back as JSON, it will be rather efficient.
And you can in fact use this even for transcoding -- read JSON, write XML/Smile/CSV/YAML/Avro -- between any formats Jackson supports.

Is it possible to serialize an object into a plain text string and send it as a string then convert it back?

As the title says. I'm sending a message, from my server, into a proxy which is outside of my control which then sends it onto my application. All I can do is send and receive strings. Is it possible to serialize to a plain string and send in this way without an input/output stream as you would normally have?
TIA
A little more info:
public class myClass implements java.io.Serializable {
int h = "ccc";
int i = "bbbb";
String myString = "aaaa";
}
I have this class, for example. Now I want to serialize it and send it as a string inside my HTTPpost and send to the proxy, can't do anything about this stage:
HttpPost post = new HttpPost("http://www.myURL.com/send.php?msg="+msg);
Then receive the msg as a string on the other side and convert it back.
Is that easily done without to many other library?
Yes.
This is done every day using JSON and XML, just to name a few formats of strings that are easily formatted and parsed. (Read about JAXRS to know about a way to use JSON formatted strings to do this and do the transfers. Or, read about JAXB which will format as XML but doesn't halp with the communication of the strings.)
You can do it in CSV format.
You can do it in fixed with fields of characters.
Morse code isn't much of a different concept only it starts with strings and converts to short and long beeps.
The way it works is this:
There is some code to which you pass an object and it returns a string in a known format.
You send the string to the other server somehow. Some ways to send strings have limits on the length.
The other server receives the string.
Using its knowledge of the format, that other server parses out the string contents and uses it.
Some notes:
If both servers use Java (or C# or Python or PHP or whatever) the formatting and parsing become symetrical. You start with a Java object of some type and end up with a Java object in the other JVM of the same type. But that is not a given. You can store values in a custom POJO in one server and a Map in the other.
If you write code to format and parse, it seems really easy as long as the contents are simple and you don't run afoul of transmission rules. For example, if you send in the query part of an HTTP get, you can't have any ampersand characters in the string.
If you use an existing library, you take advantage of everyone else's acquired knowlege of how to do this without error.
If you use a standard format for the string, it is easy to explain what's going on to someone else. If your project works, a third server might want to be in the communication loop and if it's controlled by someone else ...
Formatting is easier than parsing. There are lots of pitfalls that other people have already solved. If you are doing this to learn ways not to do things and improve your own knowledge base, by all means, do it yourself. If you want rock solid performance, use an existing and standard library and format.
Take a look at XStream. It serializes into XML, and is very simple to use.
Take a look at there Two Minute Tutorial
Yes it is possible. You can use ajax to to serialize the string to a json object and have it back to the server using an ajax.post event (javascript event).

Why can I only convert a Representation to a string once in RESTlet?

So,
I'm trying to convert a Representation to a String or a StringWriter either using the getText() or write() method. It seems I can only call this method once successfully on a Representation... If I call the method again, it returns null or empty string on the second call. Why is this? I'd expect it to return the same thing every time:
public void SomeMethod(Representation rep)
{
String repAsString = rep.getText(); // returns valid text for example: <someXml>Hello WOrld</someXml>
String repAsString2 = rep.getText(); // returns null... wtf?
}
If I'm "doing it wrong" then I'd be open to any suggestions as to how I can get to that data.
The javadocs explain this:
The content of a representation can be
retrieved several times if there is a
stable and accessible source, like a
local file or a string. When the
representation is obtained via a
temporary source like a network
socket, its content can only be
retrieved once.
So presumably it's being read directly from the network or something similar.
You can check this by calling isTransient(). If you need to be able to read it multiple times, presumably you should convert it to a string and then create a new Representation from that string.
It's because in general the Representation doesn't actually get read in from the InputStream until you ask for it with getText(), and once you've asked for it, all the bytes have been read and converted into the String.
This is the natural implementation for efficiency: rather than creating a potentially very large String and then converting that String into something useful (a JSON object, a DOM tree, or whatever), you write your converter to operate on the InputStream instead, avoiding the costs of making and reading that huge String.
So for example if you have a large XML file being PUT into a web service, you can feed the InputStream right into a SAX parser.
(As #John notes, a StringRepresentation wraps a String, and so can be read multiple times. But you must be reading a Request's representation, which is most likely an InputRepresentation.)

Categories