如何验证 java 中的 JSON 对象?
How to validate a JSON object in java?
我使用 sf.json 库为 java 中的 Web 应用程序中的传入请求映射表单数据。
假设传入请求是 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我可以配置验证所需的规则?
您可以使用 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/#/
您可以参考此 post,以快速了解 json 架构:- http://json-schema.org/example1.html
示例:-
"price": {
"type": "number",
"minimum": 0,
"exclusiveMinimum": true
}
上面的代码定义了Json模式中的价格,当Json对象根据这个模式进行验证时,它将确保价格不应该为零,它应该大于零并且它应该是一个数字。如果在 price 中传递字符串或零或一些负值,验证将失败。
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;
}
通常 json 架构可能看起来有点矫枉过正。按照我的口味,它非常复杂和笨拙,添加更多规则会使事情变得更糟。
我认为 validol library 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.
中采用了一种更简单但仍然是声明式的方法
这是它的外观示例。
考虑要验证的架构:
{
"where":{
"building":1,
"street":"Red Square"
}
}
验证逻辑反映了json模式的结构。所有约束都在结构本身中进行了描述。
所有像 json 密钥存在这样的普通检查都已经处理好了。
开始了:
/*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();
很遗憾,Whosebug 不支持行号,但是,无论如何,这是逐行进行的。
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 以获得更多示例和逐行代码分析。
我使用 sf.json 库为 java 中的 Web 应用程序中的传入请求映射表单数据。
假设传入请求是 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我可以配置验证所需的规则?
您可以使用 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/#/
您可以参考此 post,以快速了解 json 架构:- http://json-schema.org/example1.html
示例:-
"price": {
"type": "number",
"minimum": 0,
"exclusiveMinimum": true
}
上面的代码定义了Json模式中的价格,当Json对象根据这个模式进行验证时,它将确保价格不应该为零,它应该大于零并且它应该是一个数字。如果在 price 中传递字符串或零或一些负值,验证将失败。
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;
}
通常 json 架构可能看起来有点矫枉过正。按照我的口味,它非常复杂和笨拙,添加更多规则会使事情变得更糟。
我认为 validol library 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.
中采用了一种更简单但仍然是声明式的方法这是它的外观示例。 考虑要验证的架构:
{
"where":{
"building":1,
"street":"Red Square"
}
}
验证逻辑反映了json模式的结构。所有约束都在结构本身中进行了描述。 所有像 json 密钥存在这样的普通检查都已经处理好了。
开始了:
/*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();
很遗憾,Whosebug 不支持行号,但是,无论如何,这是逐行进行的。
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 以获得更多示例和逐行代码分析。