Check if JSON is valid in JAVA using Jackson - java

I have a JSON string which I am storing it in DB as a string. In front-end, I am rendering this JSON as object.
I am using:
JSON.parse(string);
Uncaught Syntax error: Unexpected Token
String :
{
"id": "295cd59f-4033-438c-9bf4-c571829f134e",
"from": "Shrisha S.<shrisha#s.com>",
"to": [
"Katie Porter <katie.porter#ss.com>"
],
"cc": [
"Jack d<jack.d#dd.com>, Keerthi<keerthi.s#dd.com>"
],
"bcc": [
]
}
Is there any way I can check If JSON is valid or not in JAVA?
One thing to be noted here is that, I don't have a schema defined for JSON which I can map to, i.e. JSON can hold anything.
I am currently trying out with JACKSON but for that I need a pre-defined schema which I don't have. Is there anyway this can be fixed?

You can read it as a JsonNode, no need to map it to a specific Class, its generic:
try{
ObjectMapper objectMapper = ...;
JsonNode jsonNode = objectMapper.readTree(yourJsonString);
} catch(JsonProcessingException e){........}

There are two different parts to the question. First is whether it is valid JSON, and second whether it contains specific set of information.
#pdem already answered first part (you can also read JSON as java.lang.Object to get the same effect).
But for second part, JSON Schema is not usually a good way, as it focuses on JSON aspects but not on more meaningful part of actual data, possible sub-typing and so on, which matter at Java level where all actual data processing occurs.
So usually you would define a POJO (or ideally just use one you use for actual data processing), bind to it (with ObjectMapper.readValue()), and then check whether data is not only technically valid wrt low-level data types, but also that it conforms to additional business constraints.
For latter part you can either write Java code, or use an annotation based framework such as Bean Validation API (JSR-303); see for example:
http://beanvalidation.org/
plus there are many #bean-validation tagged questions here as well related to usage. Some frameworks add explicit support for it; for example the best Java service framework, DropWizard does this. Others like Spring Boot have support as well.

JSON specification forbids it from using newline characters, make sure you are replacing newline characters see
Regex replace all newline characters with comma
make sure you do this before storing it in DB.

public boolean isValidJson(final String json) {
try {
final ObjectMapper objectMapper = new ObjectMapper();
final JsonNode jsonNode = objectMapper.readTree(json);
return jsonNode instanceof ContainerNode;
} catch (JsonProcessingException jpe) {
return false;
}
}

Related

Modeling JSON in Java

The few times I've worked with Java/Rest/JSon, JSON elements have always been built in camelCase format.
For example:
"someField": {
"someSonField1": "20191106",
"someSonField2": "20201119",
...
}
However, in a functional document they have passed me to build a Rest JSon client, they use this notation:
"some_field": {
"some_son_field_1": "20191106",
"some_son_field_2": "20201119",
...
}
Is it expressed somewhere that Java has to use the notation 1?.
It seems to me that if it is done this way, everything goes much more smoothly when modeling the objects:
#XmlRootElement(name = "someField")
#XmlType(propOrder = {"someSonField1", "someSonField2"})
public class someField {
private String someSonField1;
private String someSonField2;
//...
}
Thanks!
Q: Is it expressed somewhere that Java has to use the notation?
A: No: it's 100% "convention", not mandatory.
As it happens, the standard convention for both JSON (a creature of Javascript) and Java is camelcase. For example: Java Naming Conventions.
some_son_field_1 is an example of snake case. It's associated with classic "C" programs. It's also common (but NOT universal) with XML. It, too, is a "convention" - not a requirement.
I'm curious why you're choosing XML bindings for JSON data. Have you considered using Jackson?
Finally, this article might be of interest to you:
5 Basic REST API Design Guidelines
I see you're using javax.xml.bind package? Have you tried #XmlElement?
#XmlRootElement(name = "someField")
#XmlType(propOrder = {"some_son_field_1", "some_son_field_2"})
public class someField {
#XmlElement(name="some_son_field_1")
private String someSonField1;
#XmlElement(name="some_son_field_2")
private String someSonField2;
//...
}
Not sure, probably you should try putting them on getters, as your fields are private.
Or you could use unify-jdocs, a library which I created to read and write JSON documents without using any POJO objects. Rather than defining POJO objects, which we know can be difficult to manage in case of complex documents and changes to the JSON document, just don't use them at all. Directly read and write paths in the JSON document. For example, in your snippet, you could read and write the fields as:
Document d = new JDocument(s); // where s is a JSON string
String s1 = d.getString("$.some_field.some_son_field_1");
String s2 = d.getString("$.some_field.some_son_field_2");
You could use a similar way to write to these paths as so:
d.setString("$.some_field.some_son_field_1", "val1");
d.setString("$.some_field.some_son_field_2", "val2");
This library offers a whole lot of other features which can be used to manipulate JSON documents. Features like model documents which lock the structure of documents to a template, field level validations, comparisons, merging documents etc.
Obviously, you would consider it only if you wanted to work without POJO objects. Alternatively, you could use it to read and write a POJO object using your own method.
Check it out on https://github.com/americanexpress/unify-jdocs.

Remove Elements from JSON String

I have a JSON string as follows:
{
"account": "1234",
"type": "ar-type",
"eventTypes": "Update",
"objectClassName": "com.triype",
"objectJson": "{\"Name\":\"pdpot\",\"traptype\":\"adpot",\"displayName\":\"pdpot",\"experimentName\":\"pdpotpie\",\"creationTime\":\"Mar 18, 2020 5:58:58 PM\",\"createdBy\":{\"userProfileOne\":\"s:pdx\",\"userProfileTwo\":\"sid\",\"domainId\":\"did:pdx-tod-64003\"},\"lastModifiedBy\":{\"userProfileArn\":\"s:pdx-tod-64003\"},\"createdBy\":{\"userProfileOne\":\"s:p\",\"userProfileTwo\":\"si\",\"domainId\":\"did:ppot\"}}}
}
I get this input as a string and before passing it as a string to a parser I need to perform some string filtering and remove all "userProfileOne", "userProfileTwo","domainId" and their keys, without compromising the JSON structure. I am currently writing this code in Java using gson and json.
Note: There are multiple occurences of UserProfileOne, UserProfileTwo and DomainID.
The required Output is as follows:
{
"account": "1234",
"type": "ar-type",
"eventTypes": "Update",
"objectClassName": "com.triype",
"objectJson": "{\"Name\":\"pdpot\",\"traptype\":\"adpot",\"displayName\":\"pdpot",\"experimentName\":\"pdpotpie\",\"creationTime\":\"Mar 18, 2020 5:58:58 PM\"}}
}
Currently I am using substringBetween. But the operation does not work as intended.
A potential approach is to deserialize the json into a java structure then filter this structure by set to null fields you don't want to be serialize.
By using framework like Jackson you can set this before serialization on the ObjectMapper
mapper.setSerializationInclusion(Include.NON_NULL). So all null values won't be serialized in the final json/result.
I think the best maintainable way would be to create a class structure corresponding to that json and map it to the class.
Use #JsonIgnore on the fields to be ignored and then map it back to JSON from the class structure.
Another approach, a bit complex to implement, is to go through each node in the json and remove that node if it's not required
You can also do it by string matching but I don't think that is a good approach.

Use of JsonIgnoreProperties specific property deserialize properties exists only in JSON

I stumbled upon some code that adds JsonIgnoreProperties to a property that doesn't exists in class, but exists in JSON, e.g.:
#JsonIgnoreProperties({"ignoreprop"})
public class VO {
public String prop;
}
When JSON is
{ "prop":"1", "ignoreprop":"9999"}
I wonder if ignoring properties has any advantage(s) performance-wise or is it just redundant code?
Annotation that can be used to either suppress serialization of properties (during serialization), or ignore processing of JSON properties read (during deserialization).
EDIT
Is there an advantage(s) ignoring specific property over all (with
#JsonIgnoreProperties(ignoreUnknown=true))?
I wonder if ignoring properties has any advantage
Yes, it is used a lot for forward-compatibility in services. Let's say you have Services A and B. Currently A sends requests to B with some JSON objects.
Now you want to support a new property in the JSON. If you have this feature you are able to let A start sending the new property before B knows how to handle it. Decoupling the development processes of those two services.
ignoring specific property over all
This case does have some minor performance advantages. First, it doesn't try to parse this property which can be a simple string or complex object/array. Second, it helps you avoid handling an exception. Think that all the following can be valid calls and you only care about prop:
{ "prop":"1", "ignoreprop":"9999"}
{ "prop":"1", "ignoreprop":{ "a": { "key": "value", "foo": false }}}
{ "prop":"1", "ignoreprop":[1,2,3,4,5,6..... 1000000]}
From the documentation, mainly the purpose of use this is To ignore any unknown properties in JSON input without exception: which is better not to popup exception when properties are not found either in class or JSON, and this might helps serializing faster docs
Example:
// to prevent specified fields from being serialized or deserialized
// (i.e. not include in JSON output; or being set even if they were included)
#JsonIgnoreProperties({ "internalId", "secretKey" })
// To ignore any unknown properties in JSON input without exception:
#JsonIgnoreProperties(ignoreUnknown=true)
Starting with 2.0, this annotation can be applied both to classes and to properties. If used for both, actual set will be union of all ignorals: that is, you can only add properties to ignore, not remove or override. So you can not remove properties to ignore using per-property annotation.

Good practices in REST / Java

I'm currently trying to acquire skills in REST, and specifically in "good" Rest, hypermedia and all the good practices that comes with it.
In order to do so, I was asked to develop a prototype REST server containing data of my choice and implementing everything I'll have to use in a real project coming after that.
So I made a server using Spring boot and Jackson for json handling.
My data architecture is close to this : I have a collection of LaunchVehicle (I like space =D) like Ariane V, Falcon 9, etc. I can retrieve the JSON object flawlessly
{ "name":"Ariane V","country":"Europe","firstFlight":null,"GTO_Payload":1.0,"LEO_Payload":2.3,"weight":136.0 }
The thing is, I'd like to add a "space agency" field which would be an object containing some Strings and Floats, inside my LaunchVehicle. However, when the client retrieve a LaunchVehicle, I don't want it to retrieve the full SpaceAgency object, just the name for exemple. From here, he would be able to follow the link to the space agency via an hypermedia link included in the response it would have received.
How can I do this ? Right now I'm only able to send to the client my full LaunchVehicle object with the SpaceAgency object and all his fields. Is there any annotations doing what I want ? Thanks ;)
public class LaunchVehicle {
private String name;
private String country;
private Date firstFlight;
private Map<String, Float> characteristics;
private SpaceAgency spaceAgency;
#JsonCreator
constructor...
#JsonProperty(required=false)
getters and setters...
}
Thanks a lot, don't hesitate if I'm not precise or understandable enough.
Try #JsonIgnoreProperties annotation at the class level. That should provide you the feature that you want.
Otherwise, you could always use some kind of DTO object to create your response model, and there just have the fields that are going to be used at the API layer.
I would rather prefer to use an appropiate DTO/ApiModel for your API layer than having a full domain object with JSON annotations in it.
If your SpaceAgency class only defines the properties that you need to deserialize, Jackson will only deserialize those. It will forget the unmapped properties.
Try jax-ws-rs!
It's a standart REST implementation in Java.
Oracle docs
Very good tutorial by Mkyong
You can use the Gson API for this
JsonParser parser = new JsonParser();
JsonObject obj = parser.parse(spaceAgency).getAsJsonObject();
String agencyName = obj.get("agencyName").getAsString();
I think you should reference the space agency as a hyperlink.
So the JSON will look like:
{ "name":"Ariane V",
"country":"Europe",
< other fields omitted >
"_links": {
"agency": { "href": "agencies/ESA" },
< other links omitted >
}
}
To achieve this you need to specify the link in your data transfer object. Don't make this a reference to an actual object of that type -- to do so would mean populating that object, even when the client doesn't ask for it.
How you achieve this depends on what technology you're using. In Jersey it's
public class LaunchVehicle {
...
#InjectLink(resource=AgencyResource.class)
URI agencyLink;
...
}
https://jersey.java.net/documentation/latest/declarative-linking.html
Linking like this is what "real" REST is all about. However note that plenty of real-world solutions claim to be doing REST without actually using hyperlinks. A more hacky solution would be to have a String agencyId field in your JSON, which could be put into a URL template to get agency details.

Using json Schema to filter json instances in Java

I'm searching for a library which enables me to filter out a json instance in accordance with a json schema. If the json instance contains elements not defined in the schema they should be filtered out. I have found this for JavaScript: https://www.npmjs.org/package/json-schema-filter, but have been unable to find something that does this in Java.
Does anyone have suggestion as to how this can be achieved in Java? Or where to find a library that does the job?
Regards
Morten
An example
File schemaname.json:
{
"type": "object",
"properties": {
"aid": {
"type": "string"
}
}
}
final String json =
{
"aid" : "123954",
"newfield" : "itsValue"
}
What I'm asking is if the filterInstance(instance,schema) method shown below exists.
JsonNode schema = JsonLoader.fromResource("path/schemaname.json");
JsonNode instance = (new ObjectMapper()).readTree(json);
JsonNode fInstance = filterInstance(instance,schema);
fInstance =
{
"aid" : "123954"
}
You can use https://github.com/chathurabuddi/json-schema-filter.
This is the Java version of the above-mentioned json-schema-filter
You can just ignore new fields in JSON, when you are mapping to POJO.
Ignoring new fields on JSON objects using Jackson
In this case your POJO is your Jackson scheme, and use Jackson for serialization in this case :)
This questions was posted long ago and specification may have changed but as of JSON Schema 2020-12 the JSON in the example above is valid and no fields should be removed according to the schema.
The JSON schema of schemaname.json in the example above implies that the JSON String is valid because keyword "additionalProperties" has default value of empty schema {}.
I have not found any JSON Schema filter that filters based on the full schema so I am about to create my own implementation for this but would be happy if anyone knows any JSON Schema filter implementation written in Java (or other JVM-based language).

Categories

Resources