주어진 문자열이 Java에서 유효한 JSON인지 확인하는 방법


155

Java에서 JSON 문자열의 유효성을 어떻게 확인합니까? 아니면 정규 표현식을 사용하여 구문 분석 할 수 있습니까?


gson으로 구문 분석 해보십시오. 정규 표현식을 통한 검증은 좋은 생각이 아닐 수도 있습니다
aishwarya

2
json.org 는 많은 파서들과 연결되어 있습니다
MartinK

답변:


261

거친 생각, 그것을 파싱하고 예외를 잡으십시오.

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 구현을 사용 합니다 .


2
가까이 있지만 JSONArray에 대한 유효성 검사가 누락되었습니다 (이 게시물을보다 적합한 기능으로 업데이트했습니다)
Arthur

9
"{ 'hello': 'foo'} 'invalid'"({} 외부에 'invalid'추가됨)와 같은 json 문자열을 시도했지만 JSONObject가 ParseException을 발생시키지 않습니다. org.json.JSONObject를 사용하고 있습니다. 이것이 예상됩니까?
Hayichi Soashi

16
당신은 된 JSONObject를 가지고 라이브러리를 언급하지 않았다, 나는 표준 자바 lib에 그것을 보지 않았다
르지 Krasoń

6
이 솔루션은 대부분의 경우 작동하지만 특정 상황에서는 실패 할 수 있습니다. 예를 들어, 닫는 중괄호 바로 앞에 쉼표를 사용할 수 있으며 이는 실제로 구문 오류입니다. 다른 경우에 대해서는 json.org/javadoc/org/json/JSONObject.html 을 참조하십시오 .
Hua2308

9
포스터가 코드 스 니펫과 함께 import 문을 포함하도록 귀찮게 할 수없는 이유를 이해할 수 없습니다. 여기서 중요합니다. 여기에 두 번째 등급의 답변이 훨씬 좋습니다.
seansand

100

잭슨 도서관

하나의 옵션은 Jackson library 를 사용하는 것 입니다. 먼저 최신 버전을 가져옵니다 (현재).

<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.


일치하지 않는 따옴표 또는 괄호가 누락과 같은 큰 일이 작동하는 동안, GSON 행복을 준수하지 않는 콤마와 JSON 배열, 구문 분석 RFC-4627
eurythmia

@eurythmia 사실! 버전 3.0에서는 문제를 해결
JeanValjean

1
이것은 {key : value}의 유효성을 검사하지만 유효한 json은 아닙니다
Pratapi Hemant Patel

2
잭슨 함정 : new ObjectMapper().readTree("28xjRBuOQqupRopHeSuhRQ")예외없이 IntNode (28)로 구문 분석합니다. 실제로 예상하지
못한

1
내가 이해하는 것처럼이 솔루션은 전체 json을 유효성 검사뿐만 아니라 구문 분석 (및 저장)합니다. 숫자를 Integer / Long / Double 등으로 변환합니다. 이것은 구문 검사 그 이상이며 전체 json을 메모리에 저장합니다. 이는 집중적 인로드에 중요 할 수 있습니다. 구문 검사에 대한 더 나은 솔루션이 존재합니까?
javapowered

15

함께 구글 GSON 당신은 JsonParser을 사용할 수 있습니다 :

import com.google.gson.JsonParser;

JsonParser parser = new JsonParser();
parser.parse(json_string); // throws JsonSyntaxException

3
이것은 괄호 안 문자열 ala "asdf"에 오류를 발생시키지 않습니다.
Andrew

1
JSON 배열에서 후행 쉼표도 거부하지 않습니다.
Sotirios Delimanolis 2016 년

나는 그것을 믿을 수 없다 ... 문자열 "저장"이 구문 분석 가능하다고 말한다.
Dherik

여기서 gson 예제는 여전히 많은 편차를 허용하는 관대 한 구문 분석 모드를 사용합니다 . 다른 답변에서 testcase엄격한 구문 분석 예제자세한 내용을 참조하십시오 .
Vadzim

14

당신은 사용할 수 .mayBeJSON (문자열 str을)를 에서 사용할 수를 JSONUtils의 라이브러리입니다.


예 ...이 작동합니다. 고마워 npinti. 나는 gson으로 시도했지만 내가 본 그런 방법은 없다.
sappu April

@ sappu :이 답변으로 질문이 해결되면 표시하십시오. 대부분의 라이브러리는 문자열을 가져 와서 구문 분석하려고 시도합니다. 구문 분석에 실패하면, 즉 문자열이 유효한 JSON 문자열이 아닌 경우 예외가 발생합니다.
npinti

@npinti : 추가 실패}. 여분의 대괄호 =>} 인 유효하지 않은 문자열에 대해 true를 반환
Vivek

3
이 방법은 문자 그대로 문자열이 따옴표 나 괄호로 시작하고 끝나는 지 확인합니다. 매우 신뢰할 수 없습니다.
Michael Munsey

2
그렇기 때문에 메소드 이름이 'is'가 아닌 'maybe'인 이유가 있습니다.
Khoa

5

검증으로 증명하려는 대상에 따라 다릅니다. 다른 사람들이 제안한 것처럼 json을 구문 분석하는 것이 정규 표현식을 사용하는 것보다 낫습니다 .json의 문법은 정규 표현식으로 표현할 수있는 것보다 더 복잡하기 때문입니다.

json이 Java 코드로만 구문 분석되는 경우 동일한 구문 분석기를 사용하여 유효성을 검증하십시오.

그러나 파싱만으로 다른 환경에서 허용되는지 반드시 알려주지는 않습니다. 예 :

  • 많은 파서는 객체 나 배열에서 후행 쉼표를 무시하지만 후행 쉼표에 도달하면 이전 버전의 IE가 실패 할 수 있습니다.
  • 다른 파서는 후행 쉼표를 사용할 수 있지만 그 뒤에 정의되지 않은 / 널 항목을 추가하십시오.
  • 일부 파서는 인용되지 않은 속성 이름을 허용 할 수 있습니다.
  • 일부 파서는 문자열에서 비 ASCII 문자에 다르게 반응 할 수 있습니다.

검증이 매우 철저해야하는 경우 다음을 수행 할 수 있습니다.


4
String jsonInput = "{\"mob no\":\"9846716175\"}";//Read input Here
JSONReader reader = new JSONValidatingReader();
Object result = reader.read(jsonInput);
System.out.println("Validation Success !!");

stringtree-json 라이브러리를 다운로드하십시오


위와 같이 문자열을 정의 할 수 있습니까? 아니면 그냥 아이디어입니다.
Santron Manibharathi 2014 년

불가능 인해 내 mistake.now의 corrected.Thanks하는 것이라고
Jamsheer

1
JSONValidatingReader는 자바 API의 일부가 아닙니다
IgorGanapolsky

위에서 언급 한 라이브러리를 사용하십시오. 감사합니다
Jamsheer

2

파싱에 대한 약간의 :

Json과 실제로는 모든 언어에서 대체로 사용할 수있는 규칙 세트 인 문법 을 사용합니다 . json을 구문 분석하려면 기본적으로 이러한 대체를 반대로 수행해야합니다.

Json은 컨텍스트 프리 문법입니다 . 즉, 중첩 된 객체 / 배열을 가질 수 있으며 json은 여전히 ​​유효합니다. 정규 표현식은 정규 문법 (따라서 이름의 'reg') 만 처리합니다 . 이는 무한 중첩을 허용하지 않는 컨텍스트 프리 문법의 하위 집합이므로 정규 표현식 만 사용하여 모든 유효한 json을 구문 분석하는 것은 불가능합니다. 아무도 100 레벨 깊이의 과거 말을 중첩시키지 않을 것이라는 가정하에 복잡한 정규 표현식과 루프를 사용할 수 있지만 여전히 매우 어려울 것입니다.

당신이 당신의 자신의 파서를 작성
하는 경우 문법을 운동 후 재귀 하강 파서를 만들 수 있습니다


2

주어진 문자열이 Kotlin 에서 유효한 JSON인지 확인하십시오 . MByD Java의 답변 을 Kotlin으로 변환했습니다.

fun isJSONValid(test: String): Boolean {
    try {
        JSONObject(test);
    } catch (ex: JSONException) {
        try {
            JSONArray(test);
        } catch (ex1: JSONException) {
            return false;
        }
    }
    return true;
}

1

여기 에서 JSON 파일의 유효성을 검사 할 수있는 도구 를 찾 거나 JSON 라이브러리로 JSON 파일을 직렬화 해제 할 수 있으며 작업이 성공하면 유효해야합니다 ( 예 : google-json 인 경우 입력이 예외가 발생합니다) 구문 분석이 유효한 JSON이 아닙니다).


1

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;
        }
    }

1

가장 우아한 방법 인 IMHO 는 JSR 374 를 준수하는 JavaEE 표준 중 하나 인 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 공식 페이지 를 방문 하십시오.


1

다음은 gson 라이브러리 를 사용하여 엄격한 json 구문 분석에 대한 실제 예제입니다 .

public static JsonElement parseStrict(String json) {
    // throws on almost any non-valid json
    return new Gson().getAdapter(JsonElement.class).fromJson(json); 
}

자세한 정보가있는 GSON사용 하고 다양한 비 유효 예제가있는 확장 테스트 사례를 사용하여 Java에서 JSON이 유효한지 확인하는 방법에 대한 다른 자세한 답변을 참조하십시오 .


1

보시다시피 많은 솔루션이 있습니다. 주로 JSON을 파싱하여 확인하고 결국에는 파싱해야합니다.

그러나 상황에 따라 사전 확인을 통해 성능을 향상시킬 수 있습니다.

API를 호출 할 때 첫 번째 문자가 '{'이고 마지막 문자가 '}'인지 확인하는 것입니다. 그렇지 않은 경우 파서를 만드는 것을 귀찮게하지 않습니다.


0

나는 그것을위한 매우 간단한 해결책을 찾았습니다.

먼저이 라이브러리 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
    }

끝난. 즐겨


0

답은 부분적으로 맞습니다. 나는 또한 같은 문제에 직면했다. JSON을 파싱하고 예외를 확인하는 것이 일반적인 방법으로 보이지만 입력 json에 대해 솔루션이 실패합니다.

{ "outputValueSchemaFormat": "", "sortByIndexInRecord": 0, "sortOrder": 847874874387209 "내림차순"} kajhfsadkjh

보시다시피 후손 가비지 문자가 있으므로 json이 유효하지 않습니다. 그러나 jackson 또는 gson을 사용하여 위의 json을 구문 분석하려고하면 유효한 json의 구문 분석 된 맵이 표시되고 가비지 후행 문자는 무시됩니다. json 유효성 검사를 위해 파서를 사용하는 경우 필요한 솔루션이 아닙니다.

이 문제에 대한 해결책은 여기를 참조 하십시오 .

추신 :이 질문은 저에게 묻고 대답했습니다.


0
import static net.minidev.json.JSONValue.isValidJson;

그런 다음 JSON 문자열을 전달 하여이 함수를 호출하십시오. :)


0
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.");
        }
    }
}

위의 솔루션은 두 시나리오를 모두 다룹니다.

  • 중복 키
  • 불일치 한 따옴표 또는 누락 된 괄호 등

0

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;
}

0

ValidolWellFormedJson 에서 수업을 사용할 수 있습니다 선언적 유효성 검사 라이브러리 .

선언 자체는 다음과 같습니다.

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의 빠른 시작 섹션을 확인하십시오 .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.