How to validate a JSON object in java?

96,893

Solution 1

You can use the Json validator: - https://github.com/fge/json-schema-validator

Or you can simply try to parse the Json using Google Gson and catch syntax exception to validate it like below :-

try{
JsonParser parser = new JsonParser();
parser.parse(passed_json_string);
} 
catch(JsonSyntaxException jse){
System.out.println("Not a valid Json String:"+jse.getMessage());
}

For generic data validation, define the rules in your Json schema and then just validate the incoming Json against this schema.
In schema you can define the type of values it can contain, range etc.
For schema generation, you can use online tool like :- http://jsonschema.net/#/

You can refer this post, to have quick understanding of json schema:- http://json-schema.org/example1.html

Example:-

"price": {
            "type": "number",
            "minimum": 0,
            "exclusiveMinimum": true
        }

Above code defines the price in Json schema, when Json object is validated against this schema, it will ensure that price shouldn't be zero, it should be more than zero and it should be a number. If a string or zero or some negative value is passed in price, the validation will fail.

Solution 2

import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;    
/**
         * 
         * @param inputJosn
         * @return
         * @throws IOException 
         * @throws JsonParseException 
         * @throws JsonProcessingException
         */
        private static boolean isJsonValid(String inputJosn) throws JsonParseException, IOException  {
            ObjectMapper mapper = new ObjectMapper();
            mapper.enable(DeserializationFeature.FAIL_ON_READING_DUP_TREE_KEY);
            JsonFactory factory = mapper.getFactory();
            JsonParser parser = factory.createParser(inputJosn);
            JsonNode jsonObj = mapper.readTree(parser);
            System.out.println(jsonObj.toString());


            return true;
        }

Solution 3

Often times json schema might seem like overkill. It's quite complicated and clumsy to my taste, and adding more rules makes things worse.

I think a way simpler, but still declarative approach taken in validol library could be a good alternative. The main point is binding business rules to data they apply to. Complex rules decorate more basic ones. And an entire validation tree represents a single functional declarative expression. Besides, this approach encourages you to put validation logic where it belongs to: in a specific user scenario.

Here is an example of what it could look like. Consider a schema to be validated:

{
   "where":{
      "building":1,
      "street":"Red Square"
   }
}

Validation logic reflects the structure of json schema. All the constraints are described right in the structure itself. All the mundane checks like json key existence are already taken care of.

Here it goes:

/*1 */        new FastFail<>(
/*2 */            new IsJsonObject(
/*3 */                new WellFormedJson(
/*4 */                    new IndexedValue("where", jsonString)
                      )
                  ),
/*7 */            whereJsonElement ->
/*8 */                new NamedBlocOfNameds<>(
/*9 */                    "where",
/*10*/                    List.of(
/*11*/                        new AsString(
/*12*/                            new Required(
/*13*/                                new IndexedValue("street", whereJsonElement)
                                  )
                              ),
/*16*/                        new AsInteger(
/*17*/                            new Required(
/*18*/                                new IndexedValue("building", whereJsonElement)
                                  )
                              )
                          ),
/*22*/                    Where.class
                )
        )
            .result();

It's a pity that stackoverflow doesn't support line numbers, but, anyways, here's what's going on line by line.

Line 1: The whole validation is a fast fail thing, the one returning an error if the first argument results in an error.
Line 4: The first argument is a declaration of a where block.
Line 3: It must be a well-formed json.
Line 2: Besides, it should be a json object.
Line 7: The second argument is a closure. It's first argument is a where json object.
Line 8: Here goes the named block of named elements.
Line 9: Its name is where.
Line 10: The second argument is a list of all elements.
Line 13: The first element is street.
Line 12: It's required.
Line 11: And should be represented as string.
Line 18: The second one is building.
Line 17: It's required as well.
Line 16: And should be represented as an integer.
Line 22: If all previous checks are successful, an Where object is created. It's first argument is street, which must be a String; the second one is building, which must be an integer.

Take a look at quick-start section for more examples and line-by-line code analysis.

Share:
96,893

Related videos on Youtube

N3WOS
Author by

N3WOS

Java Developer

Updated on July 09, 2022

Comments

  • N3WOS
    N3WOS almost 2 years

    I use sf.json library to map form data for incoming request in my web application in java.

    Lets say the incoming request is http://localhost:8080/app/addProfile with form data as:

    formData: {  
       "name":"applicant Name",
       "Age":"26",
       "academics":{  
          "college":"80",
          "inter":"67",
          "matriculation":"89"
       },
       "skill":{  
          "computer":"c,c++,java",
          "maths":"limit,permutation,statistics"
       },
       "dateOfBirth":"09-07-1988"
    }
    

    Server Side :

    String requestFormData=request.getParameter("formData");
    JSONObject formData = JSONObject.fromObject(requestFormData);
    String name= formData.getString("name");
    
    if(name.length>70){
    //error message for length validation
    }
    
    if(!name.matches("regex for name"){
    //error message for name validation
    }
    ...
    ...
    ...
    

    The main problem with this approach is if there is minor modification in the JSON structure, then the entire code needs to be modified.

    Is there is any api where i can configure the rules which are required for validation?

    • itwasntme
      itwasntme almost 9 years
      I cant think of situation where you will need kind of validation provided by you. There are plenty of people with names (first and surname) longer than 70 even 100 chars.
    • itwasntme
      itwasntme almost 9 years
      I'd rather look up for some unique validation rules like: age is positive number, date contains day-month-year, user provided at least 2 skills in every category.
  • N3WOS
    N3WOS almost 9 years
    Hi Amit thanks, does it validate net.sf.json object?
  • Amit Bhati
    Amit Bhati almost 9 years
    Json is just a data format, you define a schema for Json and then just validate the incoming json against that schema.
  • itwasntme
    itwasntme almost 9 years
    @N3WOS what do you mean by "validation"? Do you want to check if incoming json data is valid (correct in terms of its specification) or do you want to check user input (age over 18, etc.)??
  • N3WOS
    N3WOS almost 9 years
    mastah I want to check the user input. A kind of data validation.
  • itwasntme
    itwasntme almost 9 years
    @AmitBhati could you provide a little bit more about validation JSON using schemas?
  • Karishma Gulati
    Karishma Gulati over 3 years
    Gson's JsonParser has now been deprecated, so use the static function instead: JsonParser.parseString(passed_json_string);
  • suhas0sn07
    suhas0sn07 about 3 years
    The problem with many of the stackoverflow answers is the link which results in 4o4. Better to explain with code and then provide a link. json schema link.