How to encode BSON Int64 as JSON String using Mongo Java client - java

When calling org.bson.Document.toJson() for a document containing an Int64 (Java long) value, it is encoded using Mongo's "$numberLong" encoding. For example this code:
Document parse = Document.parse("{}");
parse.put("version", 1L);
String json = parse.toJson();
Produces this JSON:
{ "version" : { "$numberLong" : "1" } }
In order to make it more interopable I'd like to encode it as String instead, i.e. like this:
{ "version" : "1" }
I've read the wiki on codecs and extended JSON as well as most of the Javadoc but I cannot for the life of me figure out how to register a custom JSON serializer for longs. Even the default org.bson.codecs.LongCodec doesn't seem to be the one that introduces the $numberLong syntax.
Obviously a simple setting (e.g. an equvalent to Gson's setLongSerializationPolicy(LongSerializationPolicy.STRING)) would be ideal but any way to make this work would be appreciated.

For get strict JSON you can use com.mongodb.util.JSON
and method serialize()
JSON.serialize(parse)
Or you can use some JSON libraries. For example GSON.
Gson gson = new Gson();
String gsonString = gson.toJson(parse);

use json.simple
JSONObject.toJSONString(parse)

Related

How to extract JSON fields from an api

I have an api which returns data in the below format when i use the clientbuilder get():
final Response response = ClientBuilder.newClient().target("url").queryParam("CustomerQuery", jsonarr).request(MediaType.APPLICATION_JSON).get();
String actual = response.readEntity(String.class);
System.out.println(actual);
Result:
{"_id":{"timestamp":1649320244,"date":"2022-04-07T08:30:44.000+00:00"},"ScheduleTime":"2022-04-07T09:50:00.000+00:00","History":[{"Status":"Pending","Time":"2022-04-07T08:30:44.011+00:00"}],"MyDetails":{"Query":"query1^^","name":"NEH","address":"XXX","Format":"xml","Version":"2"}}
{"_id":{"timestamp":1649320255,"date":"2022-04-07T08:30:55.000+00:00"},"ScheduleTime":"2022-04-07T09:50:00.000+00:00","History":[{"Status":"Pending","Time":"2022-04-07T08:30:55.011+00:00"}],"MyDetails":{"Query":"query2^^^","name":"ABC","address":"YYY","Format":"xml","Version":"1"}}
I need to extract fields under MyDetails in the above string and i tried using :
final Response response = ClientBuilder.newClient().target("url").request(MediaType.APPLICATION_JSON).get();
JsonReader jsonReader = Json.createReader(new StringReader(response.readEntity(String.class)));
System.out.println(jsonReader.readObject());
Please let me know how can i extract the fields.
If you have questions about how to use a JsonObject, read the Javadoc https://docs.oracle.com/javaee/7/api/javax/json/JsonObject.html
JsonReader jsonReader = Json.createReader(new StringReader(response.readEntity(String.class)));
JsonObject o = jsonReader.readObject();
JsonObject details = o.getJsonObject("MyDetails");
// details.get...
Alternatively, use a different http client like Retrofit that encourages direct object mapping
There are many ways to do what you want to do. I will just describe some of them. You can use several Json parsing libraries. The most popular ones are Json-Jackson also known as faster XML (See link here). You can use method readValue of ObjectMapper class. For class parameter you can use Map.class or your custom written class that will reflect the structure of your Json.
Than there is Gson library, with its user guide
But also if you want a simplistic solution, I wrote my own open-source library that includes JsonUtils class that is a thin wrapper over Json-Jackson library that gives you a very simple solution. In your case it may look like this (assuming variable json is a String that contains your Json string):
try {
Map<String, Object>map = JsonUtils.readObjectFromJsonString(json, Map.class);
Map details = map.get("MyDetails");
} catch(IOException ioe) {
...
}
Map details will contain a map with all your keys and values from section "MyDetails". If you want to use this library here is where to get it: Its called MgntUtils and you can get it on Github with Javadoc and source code. It is available as maven artifacts as well. Here is a Javadoc for JsonUtils class

Interpolate JSON values into a string

I am writing an application/class that will take in a template text file and a JSON value and return interpolated text back to the caller.
The format of the input template text file needs to be determined. For example: my name is ${fullName}
Example of the JSON:
{"fullName": "Elon Musk"}
Expected output:
"my name is Elon Musk"
I am looking for a widely used library/formats that can accomplish this.
What format should the template text file be?
What library would support the template text file format defined above and accept JSON values?
Its easy to build my own parser but there are many edge cases that needs to be taken care of and I do not want to reinvent the wheel.
For example, if we have a slightly complex JSON object with lists, nested values etc. then I will have to think about those as well and implement it.
I have always used org.json library. Found at http://www.json.org/.
It makes it really easy to go through JSON Objects.
For example if you want to make a new object:
JSONObject person = new JSONObject();
person.put("fullName", "Elon Musk");
person.put("phoneNumber", 3811111111);
The JSON Object would look like:
{
"fullName": "Elon Musk",
"phoneNumber": 3811111111
}
It's similar to retrieving from the Object
String name = person.getString("fullName");
You can read out the file with BufferedReader and parse it as you wish.
Hopefully I helped out. :)
This is how we do it.
Map inputMap = ["fullName": "Elon Musk"]
String finalText = StrSubstitutor.replace("my name is \${fullName}", inputMap)
You can try this:
https://github.com/alibaba/fastjson
Fastjson is a Java library that can be used to convert Java Objects into their JSON representation. It can also be used to convert a JSON string to an equivalent Java object. Fastjson can work with arbitrary Java objects including pre-existing objects that you do not have source-code of.

How to get values from Json Object in Java?

I have stored an Json object in an String variable called output.
Assume,
String output;
This output variable is holding an json object.
below is the json object which output variable is holding.
How can access the price_currency which is in the prices?
"prices": [
{
"price_label": "",
"price_currency": "USD",
"price_wholesale": 32.00,
"price_retail": 70.00,
"price_currency_retail": "USD"
}
],
"deliveries": [{
"delivery_name": "Zappos Holiday",
"delivery_code": "",
"style_display_order": 2,
"season_name": "Holiday",
"season_year" : "2017",
"season_code": "",
"date_cancel": "",
"date_delivery_start": "",
"date_delivery_end": "",
"public": "0",
"style_comments": ""
},
There are many possibilities:
Converting the json in a bean (using libraries like Gson or Faster Jackson)
Converting the json in a Map (always using libraries like Gson or Faster Jackson)
Accessing directly the field you need using a regular expression (very complex)
Writing a parser
Using a library to access directly the field using Json path
Each of the previous possibilities has pro and cons.
For example if you need a particular field but you don't know the structure of the whole document you can use json path.
If you need to manage the whole json as an object to save it locally convert it to a bean.
And so on.
It is super simple, if you use the new javax.json package that was introduced in Java 7:
https://docs.oracle.com/javaee/7/api/javax/json/package-summary.html
Example:
JsonReader jsonReader = Json.createReader(new StringReader(yourString));
JsonArray prices = jsonReader.readArray();
for (JsonValue price : prices){
// ...
}
jsonReader.close();
Firstly you said your response value is a string output, here is the steps of parsing a JSON object in JAVA.
Parse your string value to JSONObject, let me name it jsonRet.
Then parse this
jsonRet.getJSONArray("prices")
This step you also get a JSON array of prices let me call it prices
Foreach the prices array as JSONObject
Then do
price.getString("price_currency")
This step you get a string value, this would be what you want.
For more info, I suggest you search key word Java JSON with Google that would be benefit for your understanding.
in java You have JSONObjet class which You can use in this case.
Some link to java doc --> click

How to use Apache Avro to serialize the JSON document and then write it into Cassandra?

I have been reading a lot about Apache Avro these days and I am more inclined towards using it instead of using JSON. Currently, what we are doing is, we are serializing the JSON document using Jackson and then writing that serialize JSON document into Cassandra for each row key/user id. Then we have a REST service that reads the whole JSON document using the row key and then deserialize it and use it further.
We will write into Cassandra like this-
user-id column-name serialize-json-document-value
Below is an example which shows the JSON document that we are writing into Cassandra. This JSON document is for particular row key/user id.
{
"lv" : [ {
"v" : {
"site-id" : 0,
"categories" : {
"321" : {
"price_score" : "0.2",
"confidence_score" : "0.5"
},
"123" : {
"price_score" : "0.4",
"confidence_score" : "0.2"
}
},
"price-score" : 0.5,
"confidence-score" : 0.2
}
} ],
"lmd" : 1379214255197
}
Now we are thinking to use Apache Avro so that we can compact this JSON document by serializing with Apache Avro and then store it in Cassandra. I have couple of questions on this-
Is it possible to serialize the above JSON document using Apache Avro first of all and then write it into Cassandra? If yes, how can I do that? Can anyone provide a simple example?
And also we need to deserialize it as well while reading back from Cassandra from our REST service. Is this also possible to do?
Below is my simple code which is serializing the JSON document and printing it out on the console.
public static void main(String[] args) {
final long lmd = System.currentTimeMillis();
Map<String, Object> props = new HashMap<String, Object>();
props.put("site-id", 0);
props.put("price-score", 0.5);
props.put("confidence-score", 0.2);
Map<String, Category> categories = new HashMap<String, Category>();
categories.put("123", new Category("0.4", "0.2"));
categories.put("321", new Category("0.2", "0.5"));
props.put("categories", categories);
AttributeValue av = new AttributeValue();
av.setProperties(props);
Attribute attr = new Attribute();
attr.instantiateNewListValue();
attr.getListValue().add(av);
attr.setLastModifiedDate(lmd);
// serialize it
try {
String jsonStr = JsonMapperFactory.get().writeValueAsString(attr);
// then write into Cassandra
System.out.println(jsonStr);
} catch (JsonGenerationException e) {
e.printStackTrace();
} catch (JsonMappingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
Serialzie JSON document will look something like this -
{"lv":[{"v":{"site-id":0,"categories":{"321":{"price_score":"0.2","confidence_score":"0.5"},"123":{"price_score":"0.4","confidence_score":"0.2"}},"price-score":0.5,"confidence-score":0.2}}],"lmd":1379214255197}
AttributeValue and Attribute class are using Jackson Annotations.
And also one important note, properties inside the above json document will get changed depending on the column names. We have different properties for different column names. Some column names will have two properties, some will have 5 properties. So the above JSON document will have its correct properties and its value according to our metadata that we are having.
I hope the question is clear enough. Can anyone provide a simple example for this how can I achieve that using Apache Avro. I am just starting with Apache Avro so I am having lot of problems..
Since you already use jackson, you could try the Jackson dataformat module to support Avro-encoded data.
Avro requires a schema, so you MUST design it before using it; and usage differs a lot from free-formed JSON.
But instead of Avro, you might want to consider Smile -- a one-to-one binary serialization of JSON, designed for use cases where you may want to go back and forth between JSON and binary data; for example, to use JSON for debugging, or when serving Javascript clients.
Jackson has Smile backend (see https://github.com/FasterXML/jackson-dataformat-smile) and it is literally a one-line change to use Smile instead of (or in addition to) JSON.
Many projects use it (for example, Elastic Search), and it is mature and stable format; and tooling support via Jackson is extensive for different datatypes.

Formatting JSON before writing to File

Currently I'm using the Jackson JSON Processor to write preference data and whatnot to files mainly because I want advanced users to be able to modify/backup this data. Jackson is awesome for this because its incredibly easy to use and, apparently performs decently (see here), however the only problem I seem to be having with it is when I run myObjectMapper.writeValue(myFile, myJsonObjectNode) it writes all of the data in the ObjectNode to one line. What I would like to do is to format the JSON into a more user friendly format.
For example, if I pass a simple json tree to it, it will write the following:
{"testArray":[1,2,3,{"testObject":true}], "anotherObject":{"A":"b","C":"d"}, "string1":"i'm a string", "int1": 5092348315}
I would want it to show up in the file as:
{
"testArray": [
1,
2,
3,
{
"testObject": true
}
],
"anotherObject": {
"A": "b",
"C": "d"
},
"string1": "i'm a string",
"int1": 5092348315
}
Is anyone aware of a way I could do this with Jackson, or do I have to get the String of JSON from Jackson and use another third party lib to format it?
Thanks in advance!
try creating Object Writer like this
ObjectWriter writer = mapper.defaultPrettyPrintingWriter();
You need to configure the mapper beforehand as follows:
ObjectMapper mapper = new ObjectMapper();
mapper.configure(SerializationConfig.Feature.INDENT_OUTPUT, true);
mapper.writeValue(myFile, myJsonObjectNode);
As per above mentioned comments this worked for me very well,
Object json = mapper.readValue(content, Object.class);
mapper.writerWithDefaultPrettyPrinter().writeValueAsString(json);
Where content is your JSON string response
Jackson version:2.12
To enable standard indentation in Jackson 2.0.2 and above use the following:
ObjectMapper myObjectMapper = new ObjectMapper();
myObjectMapper.enable(SerializationFeature.INDENT_OUTPUT);
myObjectMapper.writeValue(myFile, myJsonObjectNode)
source:https://github.com/FasterXML/jackson-databind

Categories

Resources