JavaでJSON文字列を検証するにはどうすればよいですか?または、正規表現を使用して解析できますか?
JavaでJSON文字列を検証するにはどうすればよいですか?または、正規表現を使用して解析できますか?
回答:
ワイルドアイデア、それを解析して、例外をキャッチしてみてください。
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;
}
このコードは、github、maven、および部分的にAndroid で利用可能なorg.json JSON API実装を使用します。
ジャクソン図書館
1つのオプションは、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(文字列strが)で利用可能JSONUtilsのライブラリ。
これは、検証で何を証明しようとしているのかによって異なります。確かに、他の人が示唆しているようにjsonを解析する方が、正規表現を使用するよりも優れています。なぜなら、jsonの文法は、正規表現だけで表現できるよりも複雑だからです。
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は引き続き有効です。正規表現は通常の文法のみを処理します(したがって、名前の「reg」)。これは、無限のネストを許可しないコンテキストフリーの文法のサブセットであるため、正規表現のみを使用してすべての有効なjsonを解析することはできません。100レベルの深さで誰も入れ子にならないという前提で、複雑な正規表現とループのセットを使用できますが、それでも非常に困難です。
独自のパーサーを作成する準備
ができている場合は、文法を学習した後に再帰降下パーサーを作成できます
ここでは、JSONファイルを検証できるツールを見つけることができます。または、JSONライブラリを使用してJSONファイルを逆シリアル化することもできます。操作が成功した場合、それは有効であるはずです(たとえば、入力時に例外をスローするgoogle-json解析は有効なJSONではありません)。
Playframework 2.6を使用すると、Java APIにあるJsonライブラリを使用して、文字列を単純に解析することもできます。文字列は、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、最もエレガントな方法は、JSON 374に準拠するJavaEE標準の1つである、JSON処理用のJava API(JSON-P)を使用することです。
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公式ページをご覧ください。
私はそれに対する非常に簡単な解決策を見つけました。
まず、このライブラリ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 "descending"} kajhfsadkjh
ご覧のように、末尾のガベージ文字があるため、jsonは無効です。しかし、上記のjsonをjacksonまたはgsonを使用して解析しようとすると、有効なjsonの解析済みマップが取得され、文字化けした文字は無視されます。jsonの妥当性をチェックするためにパーサーを使用している場合、これは必要なソリューションではありません。
PS:この質問は私によって尋ねられ、答えられました。
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;
}
Validol宣言型検証ライブラリのWellFormedJson
クラスを使用できます。
宣言自体は次のようになります。
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()
);
このような単純なタスクではやり過ぎのように見えるかもしれませんが、複雑な要求を検証する必要がある場合は優れています。validolのクイックスタートセクションをご覧ください。