2

I am trying to validate JSon using the json schema validator. But it returns a generic message. "Json content is not compliant with schema" . I have a HTTP POST REQUEST which sends a payload as follows:

{ "key1" : "value1", "key2" : "value2" ,"key3": "value3" }

if key1 and key2 is missing . I want it to give error messages as follows:

{{
  errorCode :1001,
  errorMessage : key1 is missing",
},
  errorCode :1002,
  errorMessage : key2 is missing"
}
}

I tried writing the errors to a file(json file containing all the warnings and messages} looks something like this:

{
  "level" : "error",
  "domain" : "validation",
  "keyword" : "required",
  "message" : "object has missing required properties ([\"key1\",\"key2\",\"key3\"])",
  "required" : [ "key1", "key2", "key3"],
  "missing" : [ "key1", "key2"]
}

This is just a small part of this file. I'll have to loop through the file to reach this information. Is there any other way , I can perform custom validations and return proper error messages to the user.

EDIT 1:

I have created the following RequestObj class:

public class RequestObj {

@Valid
@NotBlank
@NotNull
private String key1;

@Valid
@NotBlank
private String key2;

@Valid
@NotBlank
private String key3;

@Override
public String toString() {
    return "RequestObj [key1=" + key1 + ", key2=" + key2 + ", key3=" + key3 + "]";
}

enter image description here

It is not validating key1 as not null.

postman request :

POST /validate HTTP/1.1 Host: localhost:8081 Content-Type: application/json

{ "key2" :"gg", "key3" : "hh" }

EDIT 2: enter image description here

when I implement the validator interface. I dont get access to the mule Event. How will I access the json that I need to validate in this case ?

HMT
  • 2,093
  • 1
  • 19
  • 51
  • Can you provide more of the file you want to "look through"? Moreover, I see a couple of problems been mentioned in your post, be explicit if you need help in both – George Dec 20 '19 at 13:56
  • 1
    you need to go for a custom json payload verified. you can use jackson json libraries to write your java code and refer the same in the mule flow. – satish chennupati Dec 20 '19 at 14:11
  • 1
    @satishchennupati Can I validate the complete payload using the customValidator ?I tried implementing the Validator interface , But I didn't find the mule Event.Can you share any doc or code for reference ? – HMT Dec 23 '19 at 06:37
  • 1
    @satishchennupati I have created the Request Object Class. Can you help me proceed further ? – HMT Dec 23 '19 at 09:08
  • @HeenaMittal sure let me know If i can pass you on any links or some samples. – satish chennupati Dec 24 '19 at 15:03
  • @satishchennupati Can you share a sample working code. Also I am unable to use payload annotation in my code. which maven dependeny should I add for that ? The other annotations that I have added for validation doesn't seem to work. Thanks for the help. – HMT Dec 27 '19 at 04:24
  • 1
    can you send me your complete xml at satishchennupati at the rate gmail.com – satish chennupati Dec 27 '19 at 18:45
  • @satishchennupati https://github.com/Heena110297/validation-poc-3 Thanks for the help – HMT Dec 30 '19 at 04:58
  • @satishchennupati I have implemented custom error handling. How can I give business error codes to every custom validation ? – HMT Dec 31 '19 at 10:31
  • 1
    @HeenaMittal you can put your error codes in property files and assign them appropriately based on the scenario. Other way is you can implement custom logging. – satish chennupati Dec 31 '19 at 13:17
  • Should I access the error codes in property file by creating a bean of message source ? – HMT Jan 01 '20 at 10:52
  • @satishchennupati https://stackoverflow.com/questions/59821078/how-to-access-property-from-property-file-in-java-code-mule-esb need your advice on this question. – HMT Jan 20 '20 at 10:38

2 Answers2

3

enter image description here

This is how my result looks after performing custom validations on the json input. I used JSR-303 annotations for validating the data.

class Example{ 
   @NotBlank
        @Size(min = 3, max = 5)
        private String key1;

        @Pattern(regexp=".+@.+\\.[a-z]+") // email
        private String key2;

        private String key3;
}

then I wrote a custom validator and I invoked the static function validate by passing all the values:

public class ValidationServiceImpl {

    public static HashMap<String,String> validate(String key1 , String key2 , String key3)  {
        HashMap<String,String> result = new HashMap();
        Example req = new Example(key1 , key2, key3);
    Validator validator;
    ValidatorFactory validatorFactory = Validation.buildDefaultValidatorFactory();
    validator = validatorFactory.getValidator();
    Set<ConstraintViolation<Example>> violations = validator.validate(req);
    if(!CollectionUtils.isEmpty(violations)) {
        for (ConstraintViolation<Example> violation : violations) 
        {
            String propertyPath = violation.getPropertyPath().toString();
            String message = violation.getMessage();
            result.put(propertyPath, message);
        }
    }
    return result;
    }

}

The result is the hashmap which returns all the violations.Logging it will give you the result.

POM dependencies required are:

<!-- https://mvnrepository.com/artifact/org.hibernate.validator/hibernate-validator -->
<dependency>
    <groupId>org.hibernate.validator</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>6.1.0.Final</version>
</dependency>
   <!-- https://mvnrepository.com/artifact/org.hibernate.validator/hibernate-validator-annotation-processor -->
<dependency>
    <groupId>org.hibernate.validator</groupId>
    <artifactId>hibernate-validator-annotation-processor</artifactId>
    <version>6.1.0.Final</version>
</dependency>


    <!-- https://mvnrepository.com/artifact/javax.validation/validation-api -->
<dependency>
    <groupId>javax.validation</groupId>
    <artifactId>validation-api</artifactId>
    <version>2.0.1.Final</version>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.el/javax.el-api -->
<dependency>
    <groupId>javax.el</groupId>
    <artifactId>javax.el-api</artifactId>
    <version>3.0.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.glassfish/javax.el -->
<dependency>
    <groupId>org.glassfish</groupId>
    <artifactId>javax.el</artifactId>
    <version>3.0.0</version>
</dependency>
HMT
  • 2,093
  • 1
  • 19
  • 51
2

If the built-in JSON validator doesn't provide the validation or error reporting that you need, then you have to implement your own custom validator in Java. See the docs on how to implement a custom validator by extending the Validator interface and in your implementation class you can use any Java library to validate JSON, like for example Jackson or GSON. Then you can customize the error handling.

aled
  • 21,330
  • 3
  • 27
  • 34
  • 1
    @Override public ValidationResult validate() { return null; } – HMT Dec 23 '19 at 04:59
  • 1
    When I implement the Validator , This is the default implementation , How will I access the mule Event in this case ? – HMT Dec 23 '19 at 05:00
  • The MuleEvent is the parameter of the validate() method: ValidationResult validate(MuleEvent event); – aled Dec 23 '19 at 12:41
  • 1
    import org.mule.extension.validation.api.Validator , is this the correct validator ? – HMT Dec 24 '19 at 04:49
  • 1
    why are the annotation not working. I have added @NotBlank . But it doesn't work – HMT Dec 24 '19 at 06:31
  • 1
    Hi , can you please check the EDIT 2 in my question above ? I have tried the approach you suggested. Need some help – HMT Dec 30 '19 at 08:19
  • 1
    I see now that you are using Mule 4. My answer is for Mule 3 and it is not valid for Mule 4. Please see the comment by @afelisatti in your other question https://stackoverflow.com/questions/59529130/how-to-access-the-payload-when-implementing-the-validator-interface. I'll edit my answer to reflect this. – aled Dec 30 '19 at 15:34
  • Also , I am unable to use @Payload annotation in mule 4 . How do I pass the whole payload to java function ? Thanks for the help – HMT Dec 31 '19 at 06:14
  • That's a different question. Please post as a new question. – aled Dec 31 '19 at 17:53