ฉันจะตรวจสอบสตริง JSON ใน Java ได้อย่างไร หรือฉันจะแยกมันโดยใช้การแสดงออกปกติ?
ฉันจะตรวจสอบสตริง JSON ใน Java ได้อย่างไร หรือฉันจะแยกมันโดยใช้การแสดงออกปกติ?
คำตอบ:
แนวคิดที่ดีเยี่ยมลองแยกวิเคราะห์แล้วดูข้อยกเว้น:
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;
}
นี้จะใช้รหัสorg.jsonการดำเนิน JSON API ที่มีอยู่บน GitHub , ในผู้เชี่ยวชาญและมีบางส่วนบน Android
ห้องสมุด JACKSON
ทางเลือกหนึ่งที่จะใช้ห้องสมุดแจ็คสัน ก่อนนำเข้าเวอร์ชันล่าสุด (ตอนนี้คือ):
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.7.0</version>
</dependency>
จากนั้นคุณสามารถใช้คำตอบที่ถูกต้องดังนี้
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;
}
}
}
ตัวเลือก Google GSON
อีกตัวเลือกหนึ่งคือการใช้Google Gson นำเข้าการพึ่งพา:
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.5</version>
</dependency>
อีกครั้งคุณสามารถใช้วิธีแก้ไขปัญหาที่เสนอเป็น:
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;
}
}
}
การทดสอบอย่างง่ายมีดังนี้:
//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
โปรดสังเกตว่าอาจมี "ผู้เยาว์" 3.0.0
ปัญหาเนื่องจากเครื่องหมายจุลภาคต่อท้ายว่าจะได้รับการแก้ไขในรุ่น
new ObjectMapper().readTree("28xjRBuOQqupRopHeSuhRQ")
แยกวิเคราะห์โดยไม่มีข้อยกเว้นเป็น IntNode (28) ไม่คาดหวังจริงๆ ...
ด้วยGoogle Gsonคุณสามารถใช้ JsonParser:
import com.google.gson.JsonParser;
JsonParser parser = new JsonParser();
parser.parse(json_string); // throws JsonSyntaxException
คุณสามารถใช้. mayBeJSON (String str) ที่มีอยู่ในไลบรารีJSONUtils
ขึ้นอยู่กับสิ่งที่คุณพยายามพิสูจน์ด้วยการตรวจสอบของคุณ แน่นอนแจง json ตามที่คนอื่น ๆ แนะนำดีกว่าการใช้ regexes เพราะไวยากรณ์ของ json มีความซับซ้อนมากกว่าที่จะแสดงด้วยเพียงแค่ regexes
หาก json จะถูกแยกวิเคราะห์โดยรหัส java ของคุณเท่านั้นให้ใช้ตัวแยกวิเคราะห์ตัวเดียวกันเพื่อตรวจสอบความถูกต้อง
แต่การแยกวิเคราะห์ไม่จำเป็นต้องบอกคุณว่าจะยอมรับได้ในสภาพแวดล้อมอื่นหรือไม่ เช่น
หากการตรวจสอบของคุณจะต้องละเอียดมากคุณสามารถ:
String jsonInput = "{\"mob no\":\"9846716175\"}";//Read input Here
JSONReader reader = new JSONValidatingReader();
Object result = reader.read(jsonInput);
System.out.println("Validation Success !!");
กรุณาดาวน์โหลดห้องสมุดstringtree-json
เล็กน้อยเกี่ยวกับการแยกวิเคราะห์:
Json และในความเป็นจริงทุกภาษาใช้ไวยากรณ์ซึ่งเป็นชุดของกฎที่สามารถใช้แทน ในการแยกวิเคราะห์ json คุณจำเป็นต้องใช้การแทนที่เหล่านั้นในทางกลับกัน
Json เป็นไวยากรณ์แบบไม่มีบริบทหมายความว่าคุณสามารถมีออบเจ็กต์ / อาร์เรย์ซ้อนกันอย่างไม่สิ้นสุดและ json จะยังคงใช้งานได้ regex จัดการเฉพาะไวยากรณ์ปกติ (ดังนั้น 'reg' ในชื่อ) ซึ่งเป็นส่วนหนึ่งของไวยากรณ์ฟรีบริบทที่ไม่อนุญาตให้มีการทำรังที่ไม่มีที่สิ้นสุดดังนั้นจึงเป็นไปไม่ได้ที่จะใช้เฉพาะ regex เพื่อแจง json ที่ถูกต้องทั้งหมด คุณสามารถใช้ชุด regex ที่ซับซ้อนและวนซ้ำกับข้อสันนิษฐานที่ไม่มีใครทำรังในอดีตพูดลึก 100 ระดับ แต่มันก็ยังคงเป็นเรื่องยากมาก
ถ้าคุณพร้อมที่จะเขียน parser ของคุณเอง
คุณสามารถสร้าง parser ที่สืบเชื้อสายมาจากคุณหลังจากที่คุณใช้ไวยากรณ์
ตรวจสอบไม่ว่าจะเป็นสตริงที่กำหนดเป็น JSON ที่ถูกต้องในKotlin ฉันแปลงคำตอบของMByD Java เป็น Kotlin
fun isJSONValid(test: String): Boolean {
try {
JSONObject(test);
} catch (ex: JSONException) {
try {
JSONArray(test);
} catch (ex1: JSONException) {
return false;
}
}
return true;
}
ที่นี่คุณสามารถค้นหาเครื่องมือที่สามารถตรวจสอบความถูกต้องของไฟล์ JSON หรือคุณสามารถทำการ deserialize ไฟล์ JSON ของคุณกับไลบรารี่ JSON ใดก็ได้และหากการดำเนินการประสบความสำเร็จก็ควรจะถูกต้อง ( google-jsonเป็นต้น) มันคือการแยกไม่ถูกต้อง JSON)
เมื่อใช้ Playframework 2.6 ไลบรารี Json ที่พบใน java api สามารถใช้เพื่อแยกสตริงได้อย่างง่ายดาย สตริงสามารถเป็นองค์ประกอบ json ของอาร์เรย์ json เนื่องจากค่าที่ส่งคืนไม่มีความสำคัญที่นี่เราเพิ่งจับข้อผิดพลาดในการแยกวิเคราะห์เพื่อตรวจสอบว่าสตริงเป็นสตริง json ที่ถูกต้องหรือไม่
import play.libs.Json;
public static Boolean isValidJson(String value) {
try{
Json.parse(value);
return true;
} catch(final Exception e){
return false;
}
}
IMHO วิธีที่สง่างามมากที่สุดคือการใช้ใน Java API สำหรับ JSON การประมวลผล (JSON-P) ซึ่งเป็นหนึ่งในมาตรฐาน JavaEE ที่สอดคล้องกับ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();
}
ใช้ Maven เพิ่มการพึ่งพา JSON-P:
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.json</artifactId>
<version>1.1.4</version>
</dependency>
เยี่ยมชมหน้าอย่างเป็นทางการของ JSON-Pสำหรับข้อมูลเพิ่มเติม
นี่คือตัวอย่างการทำงานสำหรับการแยกวิเคราะห์ json ที่เข้มงวดกับไลบรารีgson :
public static JsonElement parseStrict(String json) {
// throws on almost any non-valid json
return new Gson().getAdapter(JsonElement.class).fromJson(json);
}
ดูคำตอบโดยละเอียดอื่น ๆ ของฉันในวิธีตรวจสอบว่า JSON นั้นถูกต้องใน Java โดยใช้ GSONด้วยข้อมูลเพิ่มเติมและกรณีทดสอบเพิ่มเติมพร้อมตัวอย่างที่ไม่ถูกต้องมากมาย
อย่างที่คุณเห็นมีโซลูชั่นมากมายพวกเขาส่วนใหญ่วิเคราะห์ JSON เพื่อตรวจสอบและในตอนท้ายคุณจะต้องแยกวิเคราะห์เพื่อให้แน่ใจ
แต่ขึ้นอยู่กับบริบทคุณอาจปรับปรุงการแสดงด้วยการตรวจสอบล่วงหน้า
สิ่งที่ฉันทำเมื่อฉันเรียก API คือตรวจสอบว่าอักขระตัวแรกคือ '{' และตัวสุดท้ายคือ '}' ถ้าไม่ใช่ในกรณีนี้ฉันจะไม่สร้าง parser
ฉันได้พบวิธีแก้ปัญหาที่ง่ายมากสำหรับมันแล้ว
กรุณาติดตั้งไลบรารีนี้net.sf.json-lib
ก่อน
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
}
เสร็จสิ้น สนุก
คำตอบนั้นถูกต้องเพียงบางส่วน ฉันยังประสบปัญหาเดียวกัน การแยกวิเคราะห์ json และตรวจสอบข้อยกเว้นดูเหมือนเป็นวิธีปกติ แต่วิธีแก้ปัญหาล้มเหลวสำหรับอินพุต json บางอย่างเช่น
{"outputValueSchemaFormat": "", "sortByIndexInRecord": 0, "sortOrder": 847874874387209 "จากมากไปน้อย"} kajhfsadkjh
อย่างที่คุณเห็น json นั้นไม่ถูกต้องเนื่องจากมีอักขระขยะต่อท้าย แต่ถ้าคุณพยายามที่จะแยกวิเคราะห์ json ข้างต้นโดยใช้ jackson หรือ gson คุณจะได้รับแผนที่ที่แยกวิเคราะห์ของ json ที่ถูกต้องและตัวอักษรต่อท้ายขยะจะถูกละเว้น ซึ่งไม่ใช่โซลูชันที่จำเป็นเมื่อคุณใช้ parser สำหรับตรวจสอบความถูกต้องของ json
PS: คำถามนี้ถูกถามและตอบโดยฉัน
import static net.minidev.json.JSONValue.isValidJson;
และเรียกใช้ฟังก์ชันนี้ผ่านใน JSON String ของคุณ :)
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.");
}
}
}
วิธีการแก้ปัญหาข้างต้นครอบคลุมทั้งสองสถานการณ์:
วิธีแก้ปัญหาโดยใช้javax.json
ไลบรารี:
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;
}
คุณสามารถใช้WellFormedJson
คลาสได้จากไลบรารีการตรวจสอบความถูกต้องของValidol
การประกาศตัวเองอาจมีลักษณะดังต่อไปนี้:
new WellFormedJson(
new Unnamed<>(Either.right(new Present<>(jsonRequestString)))
)
ขั้นตอนการตรวจสอบมีลักษณะดังนี้:
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()
);
อาจดูเหมือน overkill สำหรับงานง่าย ๆ แต่มันจะส่องแสงเมื่อคุณต้องตรวจสอบคำขอที่ซับซ้อน ตรวจสอบ validol ของส่วนเริ่มต้นอย่างรวดเร็ว