parsing json & mapping xml with java com.fasterxml.jackson.databind.JsonNode; - java

New to java here coming from .NET and having some issue with parsing json. I need to be able to verify that a node exists and that the value is also not null before attempting to try and retrieve the value. I tried the following but not sure if this is the best approach.
ObjectMapper mapper = new ObjectMapper();
JsonNode messageNode = mapper.readTree(post);
id = messageNode.path("id").asText();
author = messageNode.path("actor").get("displayName").asText();
authorId = messageNode.path("actor").get("id").asText();
authorLink = messageNode.path("actor").get("link").asText();
if (! messageNode.path("actor").get("link").isMissingNode()) {
imageLink = messageNode.path("actor").get("link").asText();
}
pauthor = messageNode.path("actor").get("preferredUsername").asText();
Do I just use this for each field but how do I also check for null value?

Sounds like you should benefit from using JsonNode.has(...) and JsonNode.hasNotNull(...) methods.

Related

Get Json Value from text

I have a REST response, which contains text and JSON value. I need to get uniqueId from JSON value, what will be the best way?
My JSON is very big, but looks like this:
paymentResponse = Published your custom Transaction json to topic env_txn_endtoend_01 Final json: {"txnId":null, "envelope":{"uniqueId":234234_2344432_23442","rootID":"34534554534" etc...}}
How can I get this uniqueId value = 234234_2344432_23442?
There are many libraries to help with Json Serialization and Deserialization. Jackson Object Mapper is one of the most popular ones.
The code would be something like this. To begin with you would need Java Pojo which represents your json Object e.g. let's consider this example from this tutorial, where you can create a Car Java Object from a Car json string.
ObjectMapper objectMapper = new ObjectMapper();
String json = "{ \"color\" : \"Black\", \"type\" : \"BMW\" }";
Car car = objectMapper.readValue(json, Car.class); // you should have a Car Class(Pojo) with color, and type attributes
Final json: {"txnId":null,
"envelope":{"uniqueId":234234_2344432_23442","rootID":"34534554534"
etc...}}
How can i get this uniqueId value = 234234_2344432_23442
You could do something like this:
import groovy.json.JsonSlurper
...
String jsonString = '{"txnId":null, "envelope":{"uniqueId":"234234_2344432_23442","rootID":"34534554534"}}'
def slurper = new JsonSlurper()
def json = slurper.parseText(jsonString)
def envelope = json.envelope
String rootId = envelope.rootID
assert rootId == '34534554534'
String uniqueId = envelope.uniqueId
assert uniqueId == '234234_2344432_23442'

How to convert from Json to Protobuf?

I'm new to using protobuf, and was wondering if there is a simple way to convert a json stream/string to a protobuf stream/string in Java?
For example,
protoString = convertToProto(jsonString)
I have a json string that I want to parse into a protobuf message. So, I want to first convert the json string to protobuf, and then call Message.parseFrom() on it.
With proto3 you can do this using JsonFormat. It parses directly from the JSON representation, so there is no need for separately calling MyMessage.parseFrom(...). Something like this should work:
JsonFormat.parser().merge(json_string, builder);
//You can use this for converting your input json to a Struct / any other Protobuf Class
import com.google.protobuf.Struct.Builder;
import com.google.protobuf.Struct;
import com.google.protobuf.util.JsonFormat;
import org.json.JSONObject;
JSONObject parameters = new JSONObject();
Builder structBuilder = Struct.newBuilder();
JsonFormat.parser().merge(parameters.toString(), structBuilder);
// Now use the structBuilder to pass below (I used it for Dialog Flow V2 Context Management)
Since someone asked about getting the exception "com.google.protobuf.InvalidProtocolBufferException: JsonObject" when following Adam's advice--I ran into the same issue. Turns out it was due to the google protobuf timestamps. They are being serialized as an object containing two fields "seconds" and "nanos", since this isn't production code, I just got around this by parsing the JSON using jackson, going through the JSON object recursively and changing every timestamp from an object to a string formatted as per RFC 3339, I then serialized it back out and used the protobuf JSON parser as Adam has shown. This fixed the issue. This is some throwaway code I wrote (in my case all timestamp fields contain the word "timestamp", this could be more robust, but I don't care):
public Map<String, Object> fixJsonTimestamps(Map<String, Object> inMap) {
Map<String, Object> outMap = new HashMap<>();
for(String key : inMap.keySet()) {
Object val = inMap.get(key);
if(val instanceof Map) {
Map<String, Object> valMap = (Map<String, Object>)val;
if(key.toLowerCase().contains("timestamp") &&
valMap.containsKey("seconds") && valMap.containsKey("nanos")) {
if(valMap.get("seconds") != null) {
ZonedDateTime d = ZonedDateTime.ofInstant(Instant.ofEpochSecond((int)valMap.get("seconds")).plusNanos((int)valMap.get("nanos")),
ZoneId.of("UTC"));
val = d.format(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"));
}
} else {
val = fixJsonTimestamps(valMap);
}
} else if(val instanceof List && ((List) val).size() > 0 &&
((List) val).get(0) instanceof Map) {
List<Map<String, Object>> outputList = new ArrayList<>();
for(Map item : (List<Map>)val) {
outputList.add(fixJsonTimestamps(item));
}
val = outputList;
}
outMap.put(key, val);
}
return outMap;
}
Not the most ideal solution but it works for what I am doing, I think I saw someone recommend using a different timestamp class.
You can convert json string to Proto using builder and json String
Example :
YourProto.Builder protoBuilder = YourProto.newBuilder();
JsonFormat.parser().merge(JsonString, protoBuilder);
If you want to ignore unknown json field then
YourProto.Builder protoBuilder = YourProto.newBuilder();
JsonFormat.parser()..ignoringUnknownFields().merge(JsonString, protoBuilder);
Another way is, to use mergeFrom method from ProtocolBuffer
Example :
YourProto.Builder protoBuilder = YourProto.newBuilder();
protoBuilder.mergeFrom(JsonString.getBytes());
Once it execute, you will get all the data in protoBuilder from json String
online service:
https://json-to-proto.github.io/
This tool instantly converts JSON into a Protobuf. Paste a JSON structure on the left and the equivalent Protobuf will be generated to the right, which you can paste into your program. The script has to make some assumptions, so double-check the output!

how to parse json with ObjectMapper

i got problems when i try to parse json with ObjectMapper and in the json there is an number that look like mate
json
{ "_id" : 290365351583, "my_number" : 1.5638694276102368E8 }
my code
ObjectMapper objectMapper= new ObjectMapper();
DBobject obj = ;\\the json when i select it from mongo db
String data = JSONSerializers.getStrict().serialize(obj);
JsonNode = objectMapper.readTree(data);
when i run this code i got ERROR "Non-standart token 'Infinity': enable JsonParser.Feature.ALLOW_NON_NUMERIC_NUMBERS to allow"
You can use this maven dependency : http://mvnrepository.com/artifact/org.json/json/20160212
It's very simple to understated and use.
ex:
JSONObject obj = "YOUR_JSON_STRING";
String result = obj.getString("YOUR_STRING_KEY");
There you can use alot of methods like: getInt(), getDouble(), getBoolean() etc.
Useful examples are there : http://crunchify.com/java-how-to-parse-jsonobject-and-jsonarrays/

Neo4j Cypher results as JSON: Getting JsonMappingException when using JsonHelper.createJsonFrom() but only with certain queries

I'm working on neo4vertx, a module that makes it possible to talk to a Neo4j database using Vert.x. Specifically, I'm working on feature called "query" which allows a Vert.x user
to send a Cypher query as an eventbus message and get a JSON resultset back.
However, I seem to run into an unexpected problem when serializing to JSON using JsonHelper.createJsonFrom() with certain queries.
A quick example (database has stuff in it of course):
// This Fails with JsonMappingException (see below):
String query="MATCH (n) RETURN n";
// This Succeeds:
String query="MATCH (n) RETURN n.something";
//Rest of code:
engine = new ExecutionEngine(graphDatabaseService);
ExecutionResult result;
result = engine.execute(query);
Object object = result.iterator();
String foo = JsonHelper.createJsonFrom(object);
System.out.println("DEBUG (foo): " + foo);
Does this look familiar to anyone? We essentially want to be able to
send any kind of query and either return an empty json string or a json
representation not unlike the result.json that you can retrieve from the
web interface of neo4j!
The Exception:
testQuery(org.openpcf.neo4vertx.neo4j.Neo4jGraphTest) Time elapsed: 2.362 sec <<< ERROR!
org.neo4j.server.rest.domain.JsonBuildRuntimeException: org.codehaus.jackson.map.JsonMappingException: No serializer found for class org.neo4j.kernel.InternalAbstractGraphDatabase$DependencyResolverImpl and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationConfig.Feature.FAIL_ON_EMPTY_BEANS) ) (through reference chain: scala.collection.convert.MapWrapper["content"]->org.neo4j.kernel.impl.core.NodeProxy["graphDatabase"]->org.neo4j.test.["dependencyResolver"])
...
Although the ExecutionResult is an implementation of Iterator<Map<String,Object>> it is currently just a java wrapper around scala classes, as well as Neo4j classes (like Node, Relationship, Path).
So you have probably to do 2 things:
recursively replace neo4j classes with appropriate maps and lists
probably: recursively replace scala lists and maps with java lists and maps, e.g. new LinkedHashMap(row)
I did some of that some time ago here in my cypher-websocket-experiments
You can serialize the ExecutionResult of Neo4J to JSON this way:
ExecutionResult result ...
CypherResultRepresentation repr = new CypherResultRepresentation(result, false, false);
OutputFormat format = new OutputFormat(new JsonFormat(), null, null);
String json = format.assemble(repr);
The next thing you have to do is to create the appropriate vert.x JsonObject objects.
#Rubin: I'm currently adding this to neo4vertx ;)
By using RESTAPI:
String query = "MATCH (a)-[r]-(b) RETURN a,r,b";
RestAPI restAPI = new RestAPIFacade(URI);
CypherResult result = restAPI.query(query, Collections.<String, Object>emptyMap());
Gson gson = new GsonBuilder().disableHtmlEscaping().create();
String stringResult = gson.toJson(result.asMap());
JSONObject jsonResult = new JSONObject(stringResult);
By using Bolt
String query = "MATCH (a)-[r]-(b) RETURN a,r,b";
String stringConnection = "bolt://" + HOST + ":7687";
Driver driver = GraphDatabase.driver(stringConnection, AuthTokens.basic(USER, PASS));
Session session = driver.session();
StatementResult result = session.run(query);
session.close();
driver.close();
Gson gson = new GsonBuilder().disableHtmlEscaping().create();
while (result.hasNext()) {
Record record = result.next();
stringResult = gson.toJson(record.asMap());
}
JSONObject jsonResult = new JSONObject(stringResult);

JSON serialize gives null in the java POJO

I have a java POJO with values set. i set values like the following :
CreateRequisitionRO[] request = new CreateRequisitionRO[1];
request[0].setPortfolio("HEXGENFUND");
request[0].setTransSrlNo(new BigDecimal(1));
request[0].setTransCode("BUY");
request[0].setInvestReason("009");
request[0].setInflowOutflow(InflowOutflow.I);
request[0].setTradeDate(new LocalDate());
request[0].setTradeDate(new LocalDate());
and this is my json serialize method :
public String serialiseRequisionRO(CreateRequisitionRO[] requestObj) {
//CreateRequisitionRO requestObj = new CreateRequisitionRO();
JSONSerializer serializer = new JSONSerializer();
System.out.println("JSON : "+serializer.serialize(requestObj));
return serializer.serialize(requestObj);
}
but when i excute the program i get Null Pointer exception at this line request[0].setPortfolio("HEXGENFUND");
how to resolve it. and what could be the solution.
Please help me to resolve this.
Best Regards
Anto
You need to initialize array element/s.
request[0] = new CreateRequisitionRO();

Categories

Resources