如何在 Java 中验证 JSON 对象?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/32038543/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 11:57:54  来源:igfitidea点击:

How to validate a JSON object in java?

javajsonvalidationrules

提问by N3WOS

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

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

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

假设传入请求是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"
}

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 JSONstructure, then the entire code needs to be modified.

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

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

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

采纳答案by Amit Bhati

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

您可以使用 Json 验证器: - 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 :-

或者您可以简单地尝试使用 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());
}

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/#/

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

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

您可以参考这篇文章,以快速了解 json 模式:- 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.

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

回答by Vivek Choudhary

Print the JSON object using:

使用以下命令打印 JSON 对象:

Log.e("JSON OBJECT CREATED:", jsonobject.toString());

And then use a json validator online to validate the json.

然后在线使用json验证器对json进行验证。

回答by vaquar khan

import com.fasterxml.Hymanson.core.JsonFactory;
import com.fasterxml.Hymanson.core.JsonParseException;
import com.fasterxml.Hymanson.core.JsonParser;
import com.fasterxml.Hymanson.core.JsonProcessingException;
import com.fasterxml.Hymanson.databind.DeserializationFeature;
import com.fasterxml.Hymanson.databind.JsonNode;
import com.fasterxml.Hymanson.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;
        }

回答by Vadim Samokhin

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

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

I think a way simpler, but still declarative approach taken in validollibrary 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.

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

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.

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

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.

可惜的是,stackoverflow 不支持行号,但是,无论如何,这是逐行进行的。

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 whereblock.
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 wherejson 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 Whereobject is created. It's first argument is street, which must be a String; the second one is building, which must be an integer.

Line 1:整个验证是一个快速失败的事情,如果第一个参数导致错误,则返回错误。
Line 4: 第一个参数是where块的声明。
Line 3: 必须是格式良好的json。
Line 2: 此外,它应该是一个json对象。
Line 7: 第二个参数是闭包。它的第一个参数是一个wherejson 对象。
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,它必须是一个整数。

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

查看快速入门部分以获取更多示例和逐行代码分析。