Làm cách nào để xác thực chuỗi JSON trong Java? Hoặc tôi có thể phân tích nó bằng cách sử dụng các biểu thức thông thường?
Làm cách nào để xác thực chuỗi JSON trong Java? Hoặc tôi có thể phân tích nó bằng cách sử dụng các biểu thức thông thường?
Câu trả lời:
Một ý tưởng hoang dã, hãy thử phân tích cú pháp và bắt ngoại lệ:
import org.json.*;
public boolean isJSONValid(String test) {
try {
new JSONObject(test);
} catch (JSONException ex) {
// edited, to include @Arthur's comment
// e.g. in case JSONArray is valid as well...
try {
new JSONArray(test);
} catch (JSONException ex1) {
return false;
}
}
return true;
}
Mã này sử dụng triển khai API org.json có sẵn trên github , trong maven và một phần trên Android .
Thư viện JACKSON
Một lựa chọn sẽ là sử dụng thư viện Jackson . Lần đầu tiên nhập phiên bản mới nhất (bây giờ là):
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.7.0</version>
</dependency>
Sau đó, bạn có thể thực hiện câu trả lời đúng như sau:
import com.fasterxml.jackson.databind.ObjectMapper;
public final class JSONUtils {
private JSONUtils(){}
public static boolean isJSONValid(String jsonInString ) {
try {
final ObjectMapper mapper = new ObjectMapper();
mapper.readTree(jsonInString);
return true;
} catch (IOException e) {
return false;
}
}
}
Tùy chọn Google GSON
Một tùy chọn khác là sử dụng Google Gson . Nhập phụ thuộc:
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.5</version>
</dependency>
Một lần nữa, bạn có thể thực hiện giải pháp đề xuất như:
import com.google.gson.Gson;
public final class JSONUtils {
private static final Gson gson = new Gson();
private JSONUtils(){}
public static boolean isJSONValid(String jsonInString) {
try {
gson.fromJson(jsonInString, Object.class);
return true;
} catch(com.google.gson.JsonSyntaxException ex) {
return false;
}
}
}
Một bài kiểm tra đơn giản sau đây:
//A valid JSON String to parse.
String validJsonString = "{ \"developers\": [{ \"firstName\":\"Linus\" , \"lastName\":\"Torvalds\" }, " +
"{ \"firstName\":\"John\" , \"lastName\":\"von Neumann\" } ]}";
// Invalid String with a missing parenthesis at the beginning.
String invalidJsonString = "\"developers\": [ \"firstName\":\"Linus\" , \"lastName\":\"Torvalds\" }, " +
"{ \"firstName\":\"John\" , \"lastName\":\"von Neumann\" } ]}";
boolean firstStringValid = JSONUtils.isJSONValid(validJsonString); //true
boolean secondStringValid = JSONUtils.isJSONValid(invalidJsonString); //false
Xin vui lòng, quan sát rằng có thể có một vấn đề "nhỏ" do dấu phẩy sẽ được khắc phục trong bản phát hành 3.0.0
.
new ObjectMapper().readTree("28xjRBuOQqupRopHeSuhRQ")
phân tích cú pháp mà không có Ngoại lệ là IntNode (28). Không thực sự mong đợi ...
Với Google Gson, bạn có thể sử dụng JsonParser:
import com.google.gson.JsonParser;
JsonParser parser = new JsonParser();
parser.parse(json_string); // throws JsonSyntaxException
Bạn có thể sử dụng .mayBeJSON (Chuỗi str) có sẵn trong thư viện JSONUtils .
Nó phụ thuộc vào những gì bạn đang cố gắng chứng minh với xác nhận của bạn. Chắc chắn phân tích cú pháp json như những người khác đã đề xuất là tốt hơn so với sử dụng regexes, bởi vì ngữ pháp của json phức tạp hơn có thể được biểu diễn chỉ bằng regexes.
Nếu json sẽ chỉ được phân tích cú pháp bởi mã java của bạn, thì hãy sử dụng cùng một trình phân tích cú pháp để xác thực nó.
Nhưng chỉ cần phân tích cú pháp sẽ không nhất thiết cho bạn biết nếu nó sẽ được chấp nhận trong các môi trường khác. ví dụ
Nếu xác nhận của bạn cần phải rất kỹ lưỡng, bạn có thể:
String jsonInput = "{\"mob no\":\"9846716175\"}";//Read input Here
JSONReader reader = new JSONValidatingReader();
Object result = reader.read(jsonInput);
System.out.println("Validation Success !!");
Vui lòng tải xuống thư viện stringtree-json
Một chút về phân tích cú pháp:
Json, và trên thực tế tất cả các ngôn ngữ, sử dụng một ngữ pháp là một bộ quy tắc có thể được sử dụng thay thế. để phân tích json, về cơ bản, bạn cần phải tìm ra những sự thay thế đó
Json là một ngữ pháp không có ngữ cảnh , nghĩa là bạn có thể có các đối tượng / mảng được lồng vô hạn và json vẫn sẽ hợp lệ. regex chỉ xử lý các ngữ pháp thông thường (do đó là 'reg' trong tên), là một tập hợp con của các ngữ pháp tự do ngữ cảnh không cho phép lồng nhau vô hạn, vì vậy không thể chỉ sử dụng regex để phân tích tất cả json hợp lệ. bạn có thể sử dụng một tập hợp các regex và vòng lặp phức tạp với giả định rằng không ai sẽ nói quá khứ, sâu 100 cấp độ, nhưng nó vẫn sẽ rất khó khăn.
nếu bạn sẵn sàng viết trình phân tích cú pháp của riêng mình,
bạn có thể tạo một trình phân tích cú pháp gốc đệ quy sau khi bạn thực hiện ngữ pháp
Kiểm tra xem một chuỗi đã cho có phải là JSON hợp lệ trong Kotlin không . Tôi đã chuyển đổi câu trả lời của MByD Java sang Kotlin
fun isJSONValid(test: String): Boolean {
try {
JSONObject(test);
} catch (ex: JSONException) {
try {
JSONArray(test);
} catch (ex1: JSONException) {
return false;
}
}
return true;
}
Tại đây, bạn có thể tìm thấy một công cụ có thể xác thực tệp JSON hoặc bạn chỉ có thể giải tuần tự hóa tệp JSON của mình với bất kỳ thư viện JSON nào và nếu thao tác thành công thì nó phải hợp lệ ( ví dụ google-json sẽ ném ngoại lệ nếu đầu vào nó đang phân tích cú pháp không hợp lệ JSON).
Sử dụng Playframework 2.6, thư viện Json được tìm thấy trong java api cũng có thể được sử dụng để phân tích chuỗi đơn giản. Chuỗi có thể là một phần tử json của mảng json. Vì giá trị trả về không quan trọng ở đây, chúng tôi chỉ cần bắt lỗi phân tích cú pháp để xác định rằng chuỗi có phải là chuỗi json chính xác hay không.
import play.libs.Json;
public static Boolean isValidJson(String value) {
try{
Json.parse(value);
return true;
} catch(final Exception e){
return false;
}
}
IMHO, cách thanh lịch nhất là sử dụng API Java để xử lý JSON (JSON-P), một trong những tiêu chuẩn JavaEE phù hợp với JSR 374 .
try(StringReader sr = new StringReader(jsonStrn)) {
Json.createReader(sr).readObject();
} catch(JsonParsingException e) {
System.out.println("The given string is not a valid json");
e.printStackTrace();
}
Sử dụng Maven, thêm phụ thuộc vào JSON-P:
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.json</artifactId>
<version>1.1.4</version>
</dependency>
Truy cập trang chính thức JSON-P để biết thêm thông tin.
Dưới đây là một ví dụ hoạt động để phân tích cú pháp json nghiêm ngặt với thư viện gson :
public static JsonElement parseStrict(String json) {
// throws on almost any non-valid json
return new Gson().getAdapter(JsonElement.class).fromJson(json);
}
Xem thêm câu trả lời chi tiết khác của tôi trong Cách kiểm tra xem JSON có hợp lệ trong Java hay không bằng cách sử dụng GSON với nhiều thông tin hơn và trường hợp thử nghiệm mở rộng với các ví dụ không hợp lệ khác nhau.
Như bạn có thể thấy, có rất nhiều giải pháp, họ chủ yếu phân tích cú pháp JSON để kiểm tra và cuối cùng bạn sẽ phải phân tích cú pháp để chắc chắn.
Nhưng, tùy thuộc vào ngữ cảnh, bạn có thể cải thiện màn trình diễn bằng cách kiểm tra trước.
Những gì tôi làm khi tôi gọi API, chỉ là kiểm tra xem ký tự đầu tiên là '{' và cuối cùng là '}'. Nếu không phải như vậy, tôi không bận tâm đến việc tạo một trình phân tích cú pháp.
Tôi đã tìm thấy một giải pháp rất đơn giản cho nó.
Trước tiên hãy cài đặt thư viện này net.sf.json-lib
cho nó.
import net.sf.json.JSONException;
import net.sf.json.JSONSerializer;
private static boolean isValidJson(String jsonStr) {
boolean isValid = false;
try {
JSONSerializer.toJSON(jsonStr);
isValid = true;
} catch (JSONException je) {
isValid = false;
}
return isValid;
}
public static void testJson() {
String vjson = "{\"employees\": [{ \"firstName\":\"John\" , \"lastName\":\"Doe\" },{ \"firstName\":\"Anna\" , \"lastName\":\"Smith\" },{ \"firstName\":\"Peter\" , \"lastName\":\"Jones\" }]}";
String ivjson = "{\"employees\": [{ \"firstName\":\"John\" ,, \"lastName\":\"Doe\" },{ \"firstName\":\"Anna\" , \"lastName\":\"Smith\" },{ \"firstName\":\"Peter\" , \"lastName\":\"Jones\" }]}";
System.out.println(""+isValidJson(vjson)); // true
System.out.println(""+isValidJson(ivjson)); // false
}
Làm xong. Thưởng thức
Các câu trả lời là một phần chính xác. Tôi cũng phải đối mặt với vấn đề tương tự. Phân tích cú pháp json và kiểm tra ngoại lệ có vẻ như cách thông thường nhưng giải pháp không thành công cho json đầu vào giống như
{"outputValueSchemaFormat": "", "sortByIndexInRecord": 0, "sortOrder": 847874874387209 "giảm dần"} kajhfsadkjh
Như bạn có thể thấy json không hợp lệ vì có các ký tự rác. Nhưng nếu bạn cố phân tích json ở trên bằng cách sử dụng jackson hoặc gson thì bạn sẽ nhận được bản đồ được phân tích cú pháp của json hợp lệ và các ký tự theo dõi rác được bỏ qua. Đó không phải là giải pháp cần thiết khi bạn đang sử dụng trình phân tích cú pháp để kiểm tra tính hợp lệ của json.
Để biết giải pháp cho vấn đề này xem tại đây .
PS: Câu hỏi này đã được tôi hỏi và trả lời.
public static boolean isJSONValid(String test) {
try {
isValidJSON(test);
JsonFactory factory = new JsonFactory();
JsonParser parser = factory.createParser(test);
while (!parser.isClosed()) {
parser.nextToken();
}
} catch (Exception e) {
LOGGER.error("exception: ", e);
return false;
}
return true;
}
private static void isValidJSON(String test) {
try {
new JSONObject(test);
} catch (JSONException ex) {
try {
LOGGER.error("exception: ", ex);
new JSONArray(test);
} catch (JSONException ex1) {
LOGGER.error("exception: ", ex1);
throw new Exception("Invalid JSON.");
}
}
}
Giải pháp trên bao gồm cả hai kịch bản:
Một giải pháp sử dụng javax.json
thư viện:
import javax.json.*;
public boolean isTextJson(String text) {
try {
Json.createReader(new StringReader(text)).readObject();
} catch (JsonException ex) {
try {
Json.createReader(new StringReader(text)).readArray();
} catch (JsonException ex2) {
return false;
}
}
return true;
}
Bạn có thể sử dụng WellFormedJson
lớp từ Validol thư viện xác nhận khai báo.
Bản khai có thể trông giống như sau:
new WellFormedJson(
new Unnamed<>(Either.right(new Present<>(jsonRequestString)))
)
Giai đoạn kiểm tra trông như thế:
Result<JsonElement> result =
(new WellFormedJson(
new Named<>(
"vasya",
Either.right(
new Present<>(
"{\"guest\":{\"name\":\"Vadim Samokhin\",\"email\":\"samokhinvadim@gmail.com\"},\"source\":1,\"items\":[{\"id\":1900},{\"id\":777}]}"
)
)
)
))
.result();
assertTrue(result.isSuccessful());
assertEquals(
"{\"guest\":{\"name\":\"Vadim Samokhin\",\"email\":\"samokhinvadim@gmail.com\"},\"source\":1,\"items\":[{\"id\":1900},{\"id\":777}]}",
result.value().raw().toString()
);
assertEquals(
"{\"name\":\"Vadim Samokhin\",\"email\":\"samokhinvadim@gmail.com\"}",
result.value().raw().getAsJsonObject().get("guest").toString()
);
Nó có vẻ như quá mức cho một nhiệm vụ đơn giản như vậy, nhưng nó tỏa sáng khi bạn phải xác nhận một yêu cầu phức tạp. Kiểm tra phần bắt đầu nhanh chóng của validol .