【问题标题】:How to validate a JSON object in java?如何在 java 中验证 JSON 对象?
【发布时间】:2015-11-09 09:22:57
【问题描述】:

我使用 sf.json 库在我的 Java 网络应用程序中为传入请求映射表单数据。

假设传入的请求是http://localhost:8080/app/addProfile,表单数据为:

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"
}

服务器端:

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
}
...
...
...

这种方法的主要问题是,如果JSON结构有微小的修改,那么整个代码都需要修改。

是否有任何 api 可以配置验证所需的规则?

【问题讨论】:

  • 我想不出您需要您提供的某种验证的情况。有很多人的名字(名字和姓氏)超过 70 甚至 100 个字符。
  • 我宁愿查找一些独特的验证规则,例如:年龄为正数,日期包含日-月-年,用户在每个类别中至少提供 2 个技能。

标签: java json validation rules


【解决方案1】:

很多时候 json 模式看起来有点矫枉过正。这对我来说相当复杂和笨拙,添加更多规则会使事情变得更糟。

我认为validol 库中采用的一种更简单但仍然是声明性的方法可能是一个不错的选择。要点是将业务规则绑定到它们适用的数据。复杂的规则装饰更基本的规则。整个验证树代表一个单一的功能性声明性表达式。此外,这种方法鼓励您将验证逻辑放在它所属的位置:在特定的user scenario 中。

这是它的外观示例。 考虑要验证的架构:

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

验证逻辑反映了 json schema 的结构。所有约束都在结构本身中进行了描述。 所有像 json key 存在这样的普通检查都已经处理好了。

这里是:

/*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();

很遗憾stackoverflow不支持行号,但是,不管怎样,这里是一行一行的。

Line 1:整个验证是一个快速失败的事情,如果第一个参数导致错误,则返回错误。
Line 4:第一个参数是where 块的声明。
Line 3:必须是格式良好的json。
Line 2:另外,应该是json对象。
Line 7:第二个参数是闭包。它的第一个参数是where json 对象。
Line 8:这里是命名元素的命名块。
Line 9:它的名字是where
Line 10:第二个参数是所有元素的列表。
Line 13:第一个元素是street
Line 12:这是必需的。
Line 11:应该表示为字符串。
Line 18:第二个是building
Line 17:也是必需的。
Line 16:并且应该表示为整数。
Line 22:如果之前的所有检查成功后,将创建一个 Where 对象。 它的第一个参数是street,它必须是一个字符串;第二个是building,必须是整数。

查看quick-start section 了解更多示例和逐行代码分析。

【讨论】:

    【解决方案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;
            }
    

    【讨论】:

      【解决方案3】:

      您可以使用 Json 验证器:- https://github.com/fge/json-schema-validator

      或者您可以简单地尝试使用 Google Gson 解析 Json 并捕获语法异常以验证它,如下所示:-

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

      对于通用数据验证,请在您的 Json 架构中定义规则,然后根据该架构验证传入的 Json。
      在架构中,您可以定义它可以包含的值的类型、范围等。
      对于模式生成,您可以使用在线工具,例如:- http://jsonschema.net/#/

      您可以参考这篇文章,快速了解 json 架构:- http://json-schema.org/example1.html

      例子:-

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

      上面的代码定义了 Json 模式中的价格,当 Json 对象针对这个模式进行验证时,它将确保价格不应该为零,它应该大于零并且应该是一个数字。如果在 price 中传递字符串或零或某个负值,则验证将失败。

      【讨论】:

      • 嗨,阿米特,谢谢,它是否验证 net.sf.json 对象?
      • Json 只是一种数据格式,您为 Json 定义一个模式,然后根据该模式验证传入的 json。
      • @N3WOS “验证”是什么意思?您要检查传入的json 数据是否有效(根据其规范正确)还是要检查用户输入(18 岁以上等)??
      • mastah 我想检查用户输入。一种数据验证。
      • @AmitBhati 你能提供更多关于使用模式验证JSON 的信息吗?
      猜你喜欢
      • 2017-10-20
      • 2011-07-03
      • 2021-05-18
      • 1970-01-01
      • 2017-10-15
      • 1970-01-01
      • 2015-10-24
      • 2012-01-15
      • 2019-12-04
      相关资源
      最近更新 更多