Showing posts with label Groovy JSON validator. Show all posts
Showing posts with label Groovy JSON validator. Show all posts

Thursday 11 December 2014

Groovy JSON Validator

Aim of this blog is to validate a JSON document using XML based IScreen validation API by converting a JSON document into a Groovy map.

So, we have an Invoice in JSON format:

 {  
  "id": 1,  
  "invoiceNumber": 100,  
  "orderDetail": {  
   "companyName": "ABC Corp",  
   "products": {  
    "product": [   
     {  
      "name":"Benetton T-Shirt",  
      "description": {  
       "order": {  
        "quantity": "1000000000",  
        "amountPerPiece": "100"  
       }  
      }  
     }  
     ]  
   }  
  }  
 }  


We will be using Groovy JsonSlurper class parseText method to convert JSON document into a Groovy Map.

We will be using IScreen validation framework to validate the Map against a validation XML file:

 <?xml version="1.0" encoding="UTF-8"?>  
 <validation-root namespace="com.blogspot.javasampleprogram.validators"  
      default-resource="messages">  
      <include file="org/iscreen/validators.xml" />  
      <!-- This will validate the entire object graph, with the order being the   
           root object. -->  
      <validation-set id="invoice">  
           <!-- NumberRange Validator -->  
           <use-validator ref="org.iscreen.NumberRangeValidator"  
                name="id">  
                <mapping from="id" to="value" />  
                <label>Invoice Id</label>  
                <constraint property="minimumValue">10</constraint>  
                <constraint property="maximumValue">100</constraint>  
           </use-validator>  
           <!-- Custom messages -->  
           <use-validator ref="org.iscreen.NumberRangeValidator"  
                name="invoiceNumber">  
                <mapping from="invoiceNumber" to="value" />  
                <label>Invoice Number</label>  
                <constraint property="minimumValue">1000</constraint>  
                <constraint property="maximumValue">99999999</constraint>  
                <failure property="rangeFailure">  
                     ${label} can be between ${validator.minimumValue} and ${validator.maximumValue} and is mandatory  
                </failure>  
           </use-validator>  
           <use-validation-set ref="orderDetail" map="orderDetail" />  
      </validation-set>  
      <!-- Validates a OrderDetail. -->  
      <validation-set id="orderDetail">  
           <!-- String Validator -->  
           <use-validator ref="org.iscreen.StringValidator" name="companyName">  
                <mapping from="companyName" to="value" />  
                <label>Company Name</label>  
                <constraint property="minLength">10</constraint>  
                <constraint property="maxLength">65</constraint>  
           </use-validator>  
           <!-- Null Validator -->  
           <use-validator name="NullValidator" ref="org.iscreen.NullValidator">  
                <mapping from="invoiceAddress" to="value" />  
                <label>Invoice Address</label>  
                <failure property="defaultFailure">  
                     ${label} is a mandatory field.  
                </failure>  
           </use-validator>  
           <use-validation-set ref="products" map="products"/>  
      </validation-set>  
      <!-- Validates a Products -->  
      <validation-set id="products">  
           <!-- List validator -->  
           <use-validation-set ref="product" map="product" iterate="true" />  
      </validation-set>  
      <!-- Validates a Product -->  
      <validation-set id="product">  
           <use-validation-set ref="description" map="description" />  
      </validation-set>  
      <!-- Validates a Description -->  
      <validation-set id="description">  
           <use-validation-set ref="order" map="order" />  
      </validation-set>  
      <!-- Validates a Order -->  
      <validation-set id="order">  
           <!-- Custom messages -->  
           <use-validator ref="org.iscreen.NumberRangeValidator"  
                name="quantity">  
                <mapping from="quantity" to="value" />  
                <label>Quantity</label>  
                <constraint property="minimumValue">1</constraint>  
                <constraint property="maximumValue">999999999</constraint>  
                <failure property="rangeFailure">  
                     ${label} can be between ${validator.minimumValue} and ${validator.maximumValue} and is mandatory  
                </failure>  
           </use-validator>  
      </validation-set>  
 </validation-root>  

Before we proceed let me explain the validation xml above:

For each class we will be creating a validation-set inside which we can either use IScreen built-in validators or we can also use custom validators to validate the fields (For more info on how to create custom validator please see).

Here we are validating the 'Id' using built-in 'NumberRangeValidator' to make sure 'Id' field has a minimum value of 10 and  maximum value of 100.

Similarly, we are validating 'CompanyName' field inside the OrderDetail to validate its max and min length. Same goes for 'InvoiceAddress' field which is checked for Not Null validation.


 package com.blogspot.javasampleprogram  
 import java.util.List  
 import java.util.Locale  
 import org.iscreen.DocumentationIterator  
 import org.iscreen.ValidationException  
 import org.iscreen.ValidationFactory  
 import org.iscreen.ValidationFactoryConfig  
 import org.iscreen.ValidationFailure  
 import org.iscreen.ValidationServiceWrapper  
 import groovy.json.JsonSlurper  

 class JSONValidator {  

   private static final String VALIDATION_CONFIG = "com/blogspot/javasampleprogram/my_validations.xml"  

   static main(args) {  
     // Step 1: Load json  
     File f = new File("/home/devbox/workspace/JSONGroovyValidator/src/com/blogspot/javasampleprogram/test.json")  
     FileReader fr = new FileReader(f)  
     StringBuffer sbuf = new StringBuffer(500)  
     String s = null  
     while((s = fr.readLine())!= null) {  
       sbuf.append(s)  
     }  
     println sbuf.toString()  
    
    // Step 2: generate Invoice Map  
     def invoice = new JsonSlurper().parseText(escapeJson(sbuf.toString()))  
     ValidationFactoryConfig factory  
     ValidationServiceWrapper service  
     DocumentationIterator it  
     
     //Step 3: Load validation configurations  
     factory = new ValidationFactoryConfig(ValidationFactory.FACTORY_OGNL_XML,  
         VALIDATION_CONFIG,  
         Locale.getDefault(),  
         null)  
     service = new ValidationServiceWrapper(factory, "com.blogspot.javasampleprogram.validators.invoice")  
     try {  
      
       // Step 4: validate Invoice Map  
       service.validate(invoice)  
       System.out.println("Validation successful!")  
     } catch (ValidationException e) {  
       List failures  
       failures = e.getFailures(ValidationFailure.FAILURE)  
       System.out.println("Validation Failures found!\n")  
       for (int i = 0; i < failures.size(); i++) {  
         System.out.println(((ValidationFailure) failures.get(i)).getMessage())  
       }  
     }  
   }  
   static final String escapeJson(final String json) {  
     return json.replaceAll('&', '&amp;').replaceAll('>', '&gt;').replaceAll('>', '&lt;')  
   }  
 }  
Above code is validating the json in 4 steps:

  1. Load json data
  2. Generate Groovy Map from json string
  3. Load validation IScreen configurations
  4. Validate Map against Iscreen configuration
so if you run the code above you will get the following output:

 Validation Failures found!  

 Invoice Id must be at least 10 and no greater than 100.  
 Invoice Number can be between 1000 and 99999999 and is mandatory  
 Company Name must be at least 10 characters long.  
 Invoice Address is a mandatory field.  
 Quantity can be between 1 and 999999999 and is mandatory  


Please add the following jars to your project:

  1. javassist-3.7.ga.jar
  2. iScreen-ognl-2-0-1.jar
  3. ognl-3.0.jar
Add Groovy Capabilities to your eclipse project (Make sure you have groovy eclipse plugin installed):


Now you should see Groovy libs in your project:





Project Structure: