4

I would like to validate incoming json object for correctness at the server side. Is there a standard / optimal way to do that? What is your approach of validation?

mattmc3
  • 16,761
  • 6
  • 81
  • 99
Harsha Hulageri
  • 2,760
  • 1
  • 21
  • 23

3 Answers3

5

My advice - deserialize the JSON and see if it breaks. For example, if you're using C# on the server side, you can use the newfangled DataContractJsonSerializer, or do it the old way with the JavaScriptSerializer which is arguably much simpler.

var serializer = new JavaScriptSerializer();
var result = serializer.Deserialize<Dictionary<string, object>>(jsonString);

EDIT: And now that it's come out that you're using Java, of course my C# example is not going to work for you, but the concept is the same. Stackoverflow already has some answers here: Convert a JSON string to object in Java ME?

Community
  • 1
  • 1
mattmc3
  • 16,761
  • 6
  • 81
  • 99
  • Thanks for the response. I know the way to convert json to java object. I would want to do quick generic validation on it ( to check whether its valid ) before converting it into java object. – Harsha Hulageri Feb 24 '11 at 04:29
  • @Harsha Validating the JSON text would mean parsing it to some extent. Therefor, for correct json text (which should outnumber invalid json by a large factor in any decent application) you will end up doing double parsing. Is that really worth it? – rahulmohan Feb 24 '11 at 05:40
  • Many times you may want the validation to occur before the request hits the backend. In that case some sort of schema validation is in order. – TechTrip May 11 '12 at 09:37
3

Decode it with a JSON library. If it successfully decodes using a library that follows the specifications then it's valid.

Ignacio Vazquez-Abrams
  • 740,318
  • 145
  • 1,296
  • 1,325
  • 1
    Yeah one of quickest way is to decode it into java object and see if it throws error while decoding. I want to do a generic validation on given json object without converting it into java object. I dont want to create java object just for validation. Any of your favorite json library / utility that would help me? – Harsha Hulageri Feb 24 '11 at 04:35
0

I can conclude from your comments that you first want to make sure that json object is valid, and if it is, you're ok with creating a java object. Whatever your argumentation is, validol library allows you to state however complex validation rules declaratively, which if successful, result in a java object.

Suppose you have an order registration request, which consists of several blocks, including payment. For brevity sake, I omit all the block except that one. Here is how this request looks like in this case:

{
    "payment":{
        "expires_at":"12/29",
        "card_number":12345612341234
    }
}

Here is a validation code:

/*1 */    public class ValidatedRegistrationRequest implements Validatable<RegistrationRequest>
          {
              private String jsonRequestString;
              private Connection dbConnection;

/*6 */        public ValidatedRegistrationRequest(String jsonRequestString, Connection dbConnection)
              {
                  this.jsonRequestString = jsonRequestString;
                  this.dbConnection = dbConnection;
              }

              @Override
/*13*/        public Result<RegistrationRequest> result() throws Exception
              {
                  return
/*16*/                new FastFail<>(
/*17*/                    new WellFormedJson(
/*18*/                        new Unnamed<>(Either.right(new Present<>(this.jsonRequestString)))
                          ),
/*20*/                    requestJsonObject ->
/*21*/                        new UnnamedBlocOfNameds<>(
/*22*/                            List.of(
/*23*/                                new FastFail<>(
/*24*/                                    new IsJsonObject(
/*25*/                                        new Required(
/*26*/                                            new IndexedValue("payment", requestJsonObject)
                                              )
                                          ),
/*29*/                                    paymentJsonObject ->
/*30*/                                        new NamedBlocOfNameds<>(
/*31*/                                            "payment",
/*32*/                                            List.of(
/*33*/                                                new CardIsNotExpired(
/*34*/                                                    new AsString(
/*35*/                                                        new Required(
/*36*/                                                            new IndexedValue("expires_at", paymentJsonObject)
                                                              )
                                                          )
                                                      ),
/*40*/                                                new CardNumberIsNotBlacklisted(
/*41*/                                                    new CardNumberSatisfiesLuhnAlgorithm(
/*42*/                                                        new Required(
/*43*/                                                            new IndexedValue("card_number", paymentJsonObject)
                                                              )
                                                          ),
/*46*/                                                    this.dbConnection
                                                      )
                                                  ),
/*49*/                                            Payment.class
                                              )
                                      )
                                  ),
/*53*/                            RegistrationRequest.class
                              )
                      )
                          .result();
              }
          }

Let’s see what’s going on here, line by line:

Line 1 Declaration of ValidatedRegistrationRequest.
Line 6 Its constructor accepts not yet parsed json string. It might come from an incoming request, from received response, or from pretty much anywhere else.
Line 13: Validation starts when this method is invoked.
Line 16: The higher-level validation object is FastFail block. If the first argument is invalid, an error is returned right away.
Lines 17-19: json is checked whether it’s well-formed or not. If the latter, validation fails fast and returns a corresponding error.
Line 20: if json is well-formed, a closure is invoked, and json data is passed as its single argument.
Line 21: json data is validated. Its structure is an unnamed block of named blocks. It corresponds to a JSON Object.
Line 26: The first (and the only) block is called payment.
Line 25: It’s required.
Line 24: It must be a json object.
Line 23: If not, an error will be returned right away because it’s a FailFast object.
Line 29: Otherwise, a closure is invoked.
Line 30: Payment block is a named block consisting of other named entries – objects or scalars.
Line 36: The first one is called expires_at
Line 35: It’s required.
Line 34: And represented as a string, if possible. If not, an error will be returned.
Line 33: Finally, check that it’s not expired.
Line 43: Second parameter is called card_number.
Line 42: It’s required as well.
Line 41: It must satisfy Luhn algorithm.
Line 40: And it should not be blacklisted in our database, hence …
Line 46: … this.dbConnection parameter.
Line 49: If all previous validation checks are successful, an object of class Payment is created.
Line 53: Finally, RegistrationRequest is created and returned.

Here is how a calling code looks when validation is successful:

Result<RegistrationRequest> result = new ValidatedRegistrationRequest(jsonRequestString).result();
result.isSuccessful();
result.value().raw().payment().cardNumber(); // 12345612341234

You can find out more about the declarative validation approach, or proceed right away to quick start entry for more examples.

Vadim Samokhin
  • 3,274
  • 4
  • 39
  • 66