Разобрать ответ JSON как объект
Добрый вечер,
Я новичок в веб-сервисах, и я просто хочу написать простой клиент, который просто получает ответы от вызовов REST.
Я скачал и добавил jersey-bundle-1.17.1.jar
к моему пути сборки, и я нашел рабочий кусок кода, который делает REST-вызов URL-адреса и возвращает ответ в виде String
,
import javax.ws.rs.core.MediaType;
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.WebResource;
public class TestJerseyClient {
public static void main(String[] args) {
try {
Client client = Client.create();
WebResource webResource = client
.resource("http://path/to/service");
ClientResponse response = webResource
.accept(MediaType.APPLICATION_JSON)
.get(ClientResponse.class);
if (response.getStatus() != 200)
throw new RuntimeException("Failed : HTTP error code : " + response.getStatus());
String output = response.getEntity(String.class);
System.out.println("Output from Server .... \n");
System.out.println(output);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Но я не хочу делать строковые манипуляции, чтобы получить части ответа, которые меня интересуют.
Я бы предпочел более структурированный подход, например, получить Object
вместо строки
(а JSON
Объект, а Map<K,V>
Объект и т.д...)
ПОПЫТКА № 1 -
Map<K,V>
Sep 15, 2013 2:46:13 AM com.sun.jersey.api.client.ClientResponse getEntity
SEVERE: A message body reader for Java class java.util.Map, and Java type java.util.Map<java.lang.String, java.lang.Object>, and MIME media type application/json; charset=UTF-8 was not found
Sep 15, 2013 2:46:13 AM com.sun.jersey.api.client.ClientResponse getEntity
SEVERE: The registered message body readers compatible with the MIME media type are:
application/json; charset=UTF-8 ->
com.sun.jersey.json.impl.provider.entity.JSONJAXBElementProvider$App
com.sun.jersey.json.impl.provider.entity.JSONRootElementProvider$App
com.sun.jersey.json.impl.provider.entity.JSONListElementProvider$App
*/* ->
com.sun.jersey.core.impl.provider.entity.FormProvider
com.sun.jersey.core.impl.provider.entity.StringProvider
com.sun.jersey.core.impl.provider.entity.ByteArrayProvider
com.sun.jersey.core.impl.provider.entity.FileProvider
com.sun.jersey.core.impl.provider.entity.InputStreamProvider
com.sun.jersey.core.impl.provider.entity.DataSourceProvider
com.sun.jersey.core.impl.provider.entity.XMLJAXBElementProvider$General
com.sun.jersey.core.impl.provider.entity.ReaderProvider
com.sun.jersey.core.impl.provider.entity.DocumentProvider
com.sun.jersey.core.impl.provider.entity.SourceProvider$StreamSourceReader
com.sun.jersey.core.impl.provider.entity.SourceProvider$SAXSourceReader
com.sun.jersey.core.impl.provider.entity.SourceProvider$DOMSourceReader
com.sun.jersey.json.impl.provider.entity.JSONJAXBElementProvider$General
com.sun.jersey.core.impl.provider.entity.XMLRootElementProvider$General
com.sun.jersey.core.impl.provider.entity.XMLListElementProvider$General
com.sun.jersey.core.impl.provider.entity.XMLRootObjectProvider$General
com.sun.jersey.core.impl.provider.entity.EntityHolderReader
com.sun.jersey.json.impl.provider.entity.JSONRootElementProvider$General
com.sun.jersey.json.impl.provider.entity.JSONListElementProvider$General
com.sun.jersey.api.client.ClientHandlerException: A message body reader for Java class java.util.Map, and Java type java.util.Map<java.lang.String, java.lang.Object>, and MIME media type application/json; charset=UTF-8 was not found
at com.sun.jersey.api.client.ClientResponse.getEntity(ClientResponse.java:561)
at com.sun.jersey.api.client.ClientResponse.getEntity(ClientResponse.java:535)
at com.sun.jersey.api.client.WebResource.handle(WebResource.java:696)
at com.sun.jersey.api.client.WebResource.access$300(WebResource.java:74)
at com.sun.jersey.api.client.WebResource$Builder.get(WebResource.java:512)
at rest.TestJerseyClientAdvanced.main(TestJerseyClientAdvanced.java:36)
5 ответов
Я рекомендую вам использовать Джексона для (не) сортировки ответов JSON. Это можно сделать в два этапа, как показано ниже.
Шаг 1. создайте Java-бин с именами членов / объектов, которые соответствуют ожидаемому ответу. например, MyResponse.class
Шаг 2. используйте Java-бин при чтении объекта из ответа клиента.
private static ClientConfig clientConfig = new DefaultClientConfig();
clientConfig.getFeatures().put(JSONConfiguration.FEATURE_POJO_MAPPING, Boolean.TRUE);
ClientResponse response = Client.create(clientConfig).
resource(uri).accept(MediaType.APPLICATION_JSON).
header("content-type", MediaType.APPLICATION_JSON).
get(MY_RESPONSE.class);
MyResponse output = response.getEntity(MyResponse.class);
Вы можете использовать библиотеку Genson.
// register genson in jersey client
ClientConfig cfg = new DefaultClientConfig(GensonJsonConverter.class);
Client client = Client.create(cfg);
WebResource webResource = client.resource("http://path/to/service");
// you can map it to a pojo, no need to have a string or map
SomePojo pojo = webResource
.accept(MediaType.APPLICATION_JSON)
.get(SomePojo.class);
Если вам нужно получить только несколько свойств из большого ответа JSON, вы можете использовать клиент Jersey и объект JsonArray или JsonObject.
String url = "http://api.goeuro.com/api/v2/position/suggest/en/";
String city = "New York";
Client client = ClientBuilder.newClient();
WebTarget webTarget = client.register(JsonProcessingFeature.class).target(url);
JsonArray jsonArray = webTarget.path(city)
.request(MediaType.APPLICATION_JSON_TYPE).get(JsonArray.class);
for (JsonObject jsonObject : jsonArray.getValuesAs(JsonObject.class)) {
JsonObject geoPosition = jsonObject.getJsonObject("geo_position");
System.out.println(Arrays.asList(
jsonObject.getString("name"), jsonObject.getString("type"),
geoPosition.get("latitude"), geoPosition.get("longitude")));
}
Maven зависимости
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-client</artifactId>
<version>2.22.1</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-processing</artifactId>
<version>2.22.1</version>
</dependency>
Просто как тот:
ObjectMapper mapper = new ObjectMapper();
String json = "json value";
MyClass obj = mapper.readValue(json , MyClass .class);
Посмотрите этот пример... нажмите на эту ссылку для получения дополнительной информации
// The request also includes the userip parameter which provides the end
// user's IP address. Doing so will help distinguish this legitimate
// server-side traffic from traffic which doesn't come from an end-user.
URL url = new URL(
"https://www.websitelink.com//folderresponsedata
+ "q=Paris%20Hilton&userip=USERS-IP-ADDRESS");
URLConnection connection = url.openConnection();
connection.addRequestProperty("Referer", /* Enter the URL of your site here */);
String line;
StringBuilder builder = new StringBuilder();
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
while((line = reader.readLine()) != null) {
builder.append(line);
}
JSONObject json = new JSONObject(builder.toString());
// now have some fun with the results...