JSON Объект неверен и вызывает HttpException - PullRequest
0 голосов
/ 24 января 2020

Я пытаюсь проверить этот метод:

private ServiceApiMetadata getConfig(final HttpServletRequest request, final String path)
    throws IOException {
  final Schema schema;
  try (final InputStream inStream = this.getClass().getResourceAsStream(path)) {
    final JSONObject origSchema = new JSONObject(new JSONTokener(inStream));
    if (isGoldStar()) {
      origSchema.getJSONObject("properties")
          .getJSONObject("notifications")
          .getJSONObject("properties")
          .getJSONObject("topic")
          .put("pattern", "^[0-9A-Za-z-.]*$");
    }
    schema = SchemaLoader.load(origSchema);
  }

  final ServiceApiMetadata config;
  try (final BufferedReader reader = request.getReader()) {
    final JSONObject json = new JSONObject(new JSONTokener(reader));
    schema.validate(json);
    config = ServiceApiMetadata.read(json);
  } catch (final ValidationException e) {
    _logger.debug(e.getMessage());
    if (e.getLocation().contains("#/properties/notifications")) {
      throw new ServiceApiException(ServiceApiError.MALFORMED_NOTIFICATIONS_ERROR,
          ServiceApiErrorMessage.MALFORMED_JSON);
    } else {
      throw new ServiceApiException(ServiceApiError.MALFORMED_JSON);
    }
  } catch (final JSONException e) {
    _logger.debug(e.getMessage());
    throw new ServiceApiException(ServiceApiError.MALFORMED_JSON);
  }

  return config;
}

Поскольку он закрыт, я создал следующий метод в своем классе:

@TestOnly
protected void runGetConfig(final HttpServletRequest request, final String schemaPath) throws IOException {
  final ServiceApiMetadata conf = getConfig(request, schemaPath);
}

Когда я запускаю тест getConfig() бросает исключение. Проблема в том, что когда строка final JSONObject json = new JSONObject(new JSONTokener(reader)); получает это исключение:

HttpException(400,{"status_code":400,"error_code":"MalformedJson","uri":"uri","message":"MalformedJson"},null)

, я также вижу эту ошибку в своем журнале:

at 0 [character 1 line 1]

Для HttpServletRequest я использую org.springframework.mock.web.MockHttpServletRequest.MockHttpServletRequest() следующим образом:

final MockHttpServletRequest request = new MockHttpServletRequest();

Возможно ли, что это создает неправильный reader, что, в свою очередь, означает, что JSONObject является неправильным, и если да, то как мне решить эту проблему?

Дополнительная информация Я добавил тело к MockHttpServletRequest, но проблема остается той же. Я добавил некоторые записи, как показано ниже:

final JSONObject rawSchema = new JSONObject(new JSONTokener(inputStream));
      _logger.info("rawSchema: " + rawSchema);
      if (isPulsar()) {
        rawSchema.getJSONObject("properties")
            .getJSONObject("notifications")
            .getJSONObject("properties")
            .getJSONObject("topic")
            .put("pattern", "^[0-9A-Za-z-._:/]*$");
      }
      schema = SchemaLoader.load(rawSchema);
    }

    final ServiceApiContainerMetadata conf;
    try (final BufferedReader reader = request.getReader()) {
      _logger.info("reader: " + reader);
      _logger.info("JSONTokener(reader): " + new JSONTokener(reader.readLine()));
      final JSONObject json = new JSONObject(new JSONTokener(reader.readLine()));

Это показывает мне это в выводе:

rawSchema: {VALID JSON STRUCTURE. IT'S TOO BIG TO INCLUDE IN THIS QUESTION}
reader: java.io.BufferedReader@4c4d27c8
JSONTokener(reader):  at 0 [character 1 line 1]

Информация о MockHttpServletRequest

Тело моего MockHttpServletRequest содержит текст Lorem ipsum. Если я добавлю следующий код ниже моего BufferedReader, этот текст будет напечатан на консоли. Этот же текст также используется в `` final JSONObject json = new JSONObject (new JSONTokener (reader.readLine ())); so the malformed JSON error in my HttpException` не удивительно.

while ((strCurrentLine = reader.readLine()) != null) {
  _logger.info("reader: " + strCurrentLine);
}

Может ли это быть ошибка в моем коде? Должно ли final JSONObject json = new JSONObject(new JSONTokener(reader.readLine())); быть на самом деле final JSONObject json = new JSONObject(schema);? Если я пытаюсь это сделать, я вижу, что код теперь достигает schema.validate(json);, но есть 12 schema violations found. Я не вижу, что это такое. Еще одна мысль: должно ли тело быть JSON?

Я обновил тело до JSON, что привело к 2 ошибкам проверки. Во-первых, отсутствовал service_id и присутствовал testkey, поэтому я решил это, и мой метод больше не выдает исключение при использовании final JSONObject json = new JSONObject(new JSONTokener(reader));.

Ответы [ 2 ]

0 голосов
/ 27 января 2020

Чтобы решить эту проблему, я добавил notifications ключ к своему телу JSON. Это позволило final JSONObject json = new JSONObject(new JSONTokener(reader.readLine())); to work.

0 голосов
/ 24 января 2020

Если вы просто наберете request = new MockHttpServletRequest();, тогда у запроса не будет тела, а у читателя не будет данных.

Вы можете использовать MockMvcRequestBuilders для создания полного запроса.

request = MockMvcRequestBuilders.get("/message")
  .contentType(MediaType.TEXT_PLAIN)
  .content("{... json body ...}")
  .buildRequest(context);
...