Запросить JSON и распарсить на Java (JUnit/TestNG)

Добрый день.

Есть некий сервис, который отдает JSON. Как можно средствами JUnit/TestNG получить JSON и распарсить его? Гуглил, заблудился в 3 соснах. 2 дня сидел не разобрался.

Ищу что-то простое, типа
res = makeRequest(URL, params);
findValue = res.getInt(1).getText();

Спасибо

Самое простое это Jackson или Gson

1 лайк

Gson - GitHub - google/gson: A Java serialization/deserialization library to convert Java Objects into JSON and back

“Provide simple toJson() and fromJson() methods to convert Java objects to JSON and vice-versa”

На сегодня самое простое и функциональное.

1 лайк
  1. Вам надо отправить HTTP запрос. Библиотек для этого куча, одна из самых простых Retrofit
  2. Преобразовать ответ в объект, это можно сделать как через Retrofit тот же, так и вышеприведенным Gson

Что то такое?

public static String sendPostJSONRequest(String url, String request) throws Exception {
		URL obj = new URL(url);
		HttpURLConnection con = (HttpURLConnection) obj.openConnection();
		con.setRequestMethod("POST");
		con.setRequestProperty("User-Agent", USER_AGENT);
		con.setRequestProperty("Content-Type", "application/json");
		con.setDoOutput(true);
		DataOutputStream wr = new DataOutputStream(con.getOutputStream());
		wr.writeBytes(request);
		wr.flush();
		wr.close();
		BufferedReader in = new BufferedReader(new     InputStreamReader(con.getInputStream()));
		String inputLine;
		StringBuffer response = new StringBuffer();
		while ((inputLine = in.readLine()) != null) {
			response.append(inputLine);
		}
		in.close();
		ObjectMapper mapper = new ObjectMapper();
		Object json = mapper.readValue(response.toString(), Object.class);
		String indented = mapper.writeValueAsString(json);
		return indented;
	}

Результат потом парситься как JSON объект Jackson библиотекой. Полный код метода:

public static ArrayList<Map> executeQuery(String dbServer, String dbPort, String indexName, String esQuery) throws Exception{
		String url = "http://"+dbServer+":"+dbPort+"/"+indexName+"/_search";
		String response = HTTP.sendPostJSONRequest(url, esQuery);
		ArrayList<Map> out = new ArrayList<Map>();
		JsonFactory jfactory = new JsonFactory();
		JsonParser jParser = jfactory.createJsonParser(response);
		ObjectMapper mapper = new ObjectMapper();
	    JsonNode input = mapper.readTree(jParser);
	    JsonNode results = input.get("hits");
	    results = results.get("hits");
	    
	    for (final JsonNode element: results) {
	        JsonNode fieldname = element.get("_source");
	        Iterator<Map.Entry<String,JsonNode>> fieldsIterator=fieldname.getFields();
	        Map<String, String> map = new HashMap<String, String>();
	        while (fieldsIterator.hasNext()) {
	            Map.Entry<String,JsonNode> field = fieldsIterator.next();
	            map.put(field.getKey(), field.getValue().toString());
	        }
	        out.add(map);
	    }
		return out;
	}

P.S. Использую для отправки запросов в Elasticsearch

1 лайк

Рекомендую попробовать RestAssured:

Я использую достаточно долгое время - мне очень нравится.

Из ридми:
Getting and parsing a response body:

// Example with JsonPath
String json = get(“/lotto”).asString()
List winnderIds = from(json).get(“lotto.winners.winnerId”);

// Example with XmlPath
String xml = post(“/shopping”).andReturn().body().asString()
Node category = from(xml).get(“shopping.category[0]”);

2 лайка

Тоже думаю начать использовать Rest Assured, расскажите пожалуйста о каких-нибудь минусах и недостатках? И можно ли как то создавать проекты для импорта в клиенты типа Postman, чтобы нубы могли у себя быстренько все открыть и воспроизвести?

Есть ли версия для C#? Как интегрируется с CI?

Есть ли хелперы для авторизации, окружений разных… Как вы объекты храните, где пишите их? Используете БД или папку с файлами?

Лично я пользуюсь вот этими двумя библиотеками и крайне доволен:

<dependency>
    <groupId>org.json</groupId>
    <artifactId>json</artifactId>
    <version>LATEST</version>
</dependency>
<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>fluent-hc</artifactId>
    <version>4.2.6</version>
</dependency>

Пример использования (для красоты пара вспомогательных методов пишется, я их убрал для наглядности):

HttpResponse response = Request.Get(uri).execute().returnResponse();
HttpResponse response = Request.Post(uri).stringBody("request_body","content_type").execute().returnResponse();

Можно добавить хедеры:
.addHeader("Header: value")

Соответственно, сделав запрос вы получаете ответ, с ним работаем так (для красоты пара вспомогательных методов пишется, я их убрал для наглядности):

Для проверки кода ответа :

Assert.assertEquals(response.getStatusLine().getStatusCode(), 200, "comment")

Для работы с телом ответа как JSON:

JSONObject jsonResponse = new JSONObject(IOUtils.toString(response.getEntity().getContent()))
JSONArray jsonResponse = new JSONArray(IOUtils.toString(response.getEntity().getContent()))

Обращение к полям простое (в случае с array - добавляется цикл по элементам списка):

jsonResponse.get("field") 
jsonResponse.getString("field")
или любой другой формат.
1 лайк

Если JSON надо распарсить в объект, то можно использовать JsonDeserializer и той же библиотеки Gson.
Выглядит примерно так.
Класс отвечающий за десериализацию:
public class TestDataClientJsonDeserializer implements JsonDeserializer<TestDataClient> { @Override public TestDataClient deserialize(JsonElement json, Type type, JsonDeserializationContext context) throws JsonParseException { JsonObject jsonObject = json.getAsJsonObject(); String clientName = jsonObject.get("name").getAsString(); String clientPass = jsonObject.get("password").getAsString(); String clientAddress = jsonObject.get("address").getAsString(); OperatingSystem clientOperSystem = HelpUtils.parseEnum(OperatingSystem.class,jsonObject.get("arch").getAsString()); TestDataClient client = new TestDataClient(clientName, clientPass, clientAddress, clientOperSystem); client.setGlobalId(jsonObject.get("globalId").getAsString()); client.setClientDesc(jsonObject.get("description").getAsString()); return client; } }

Использование:
public TestDataClient getClienе(String json) { TestDataClient client = this.gson.fromJson(json, TestDataClient.class); return client; }

Вам не просто надо распарсить его, а еще и получить, как я понял, по такой вот строчке :slight_smile:

res = makeRequest(URL, params);

RestAssured

Вот простой примерчик - Usage · rest-assured/rest-assured Wiki · GitHub

{
"lotto":{
 "lottoId":5,
 "winning-numbers":[2,45,34,23,7,5,3],
 "winners":[{
   "winnerId":23,
   "numbers":[2,45,34,23,3,5]
 },{
   "winnerId":54,
   "numbers":[52,3,12,11,18,22]
 }]
}
}
get("/lotto").then().body("lotto.lottoId", equalTo(5));

//

get("/lotto").then().body("lotto.winners.winnerId", hasItems(23, 54));
1 лайк

Спасибо ) На момент написания комментария уже столкнулся с ею, хорошая библиотека.