如何从服务获取响应的 JSON

Posted

技术标签:

【中文标题】如何从服务获取响应的 JSON【英文标题】:How to get the JSON of a response from a service 【发布时间】:2019-07-03 16:49:54 【问题描述】:

大家好,我正试图从这项服务 (http://ip-api.com) 获得响应,该服务会根据 ip 为您提供纬度和经度:

因此,当您传递 ip 55.130.54.69 时,它会返回以下 json:


    "query": "55.130.54.69",
    "status": "success",
    "continent": "North America",
    "continentCode": "NA",
    "country": "United States",
    "countryCode": "US",
    "region": "AZ",
    "regionName": "Arizona",
    "city": "Sierra Vista",
    "district": "Fort Huachuca",
    "zip": "85613",
    "lat": 31.5552,
    "lon": -110.35,
    "timezone": "America/Phoenix",
    "currency": "USD",
    "isp": "CONUS-RCAS",
    "org": "USAISC",
    "as": "AS721 DoD Network Information Center",
    "asname": "DNIC-ASBLK-00721-00726",
    "mobile": false,
    "proxy": false

http://ip-api.com/#55.130.54.69

所以在我的服务中,我做了以下事情(我用这个Best way to get geo-location in Java 指导):

    @POST
    @Path("/test2")
    public void test2(@Context HttpServletRequest request) 

        String ip = request.getRemoteAddr();
        System.out.println("ip: " + ip);
        //Im changing value of ip cause I have an issue with "private range" ip of my machine
        ip = "55.130.54.69";
        // This is working
        Client client = ClientBuilder.newClient();
        Response response = client.target("http://ip-api.com/json/" + ip).request(MediaType.TEXT_PLAIN_TYPE)
                .header("Accept", "application/json").get();

        System.out.println("status: " + response.getStatus()); // Printing 200 so it worked
        System.out.println("body:" + response.getEntity());
        System.out.println("metadata: " + response.getMetadata());
        System.out.println(response);
    

所以你可以看到我试图在我的问题中得到上面的那个 json,但我不知道怎么做,你能告诉我方法吗?

【问题讨论】:

【参考方案1】:

如果需要将json作为纯文本获取,可以尝试下一个:

@POST
@Path("/test2")
public void test2(@Context HttpServletRequest request) 

    ...

    Response response = client.target("http://ip-api.com/json/" + ip)
        .request(MediaType.TEXT_PLAIN_TYPE)
        .header("Accept", "application/json").get();

   String json = response.readEntity(String.class);
   response.close();

   // now you can do with json whatever you want to do

您还可以创建一个实体类,其中字段名称与 json 中的值名称匹配:

public class Geolocation 
    private String query;
    private String status;
    private String continent;

    // ... rest of fields and their getters and setters      

然后你可以读取数据作为实体的实例:

@POST
@Path("/test2")
public void test2(@Context HttpServletRequest request) 

    ...

    Response response = client.target("http://ip-api.com/json/" + ip)
        .request(MediaType.TEXT_PLAIN_TYPE)
        .header("Accept", "application/json").get();

   Geolocation location = response.readEntity(Geolocation.class);
   response.close();

   // now the instance of Geolocation contains all data from the message

如果您对获取响应的详细信息不感兴趣,则无法直接从 get() 方法获得结果消息:

Geolocation location = client.target("http://ip-api.com/json/" + ip)
    .request(MediaType.TEXT_PLAIN_TYPE)
    .header("Accept", "application/json").get(Geolocation.class);

// just the same has to work for String

【讨论】:

嘿,看起来不错,但是我的响应变量没有 readyEntity 方法:(知道为什么吗? @BugsForBreakfast 你能检查一下你的响应类的全名是javax.ws.rs.core.Response吗? 是的,是男人,你认为它的版本?进口来自哪里?哪个依赖项检查版本 @BugsForBreakfast 它取决于您使用的 Servlet 应用服务器类型。是Tomcat还是别的什么? @BugsForBreakfast 我更新了答案。你有get(Class<T> responseType) 方法吗?你能调用它而不是get()吗?【参考方案2】:

这打印什么? System.out.println("body:" + response.getEntity()); 另外,您使用哪些库来发布?,那是球衣吗?

【讨论】:

打印 body:org.jboss.resteasy.client.jaxrs.internal.ClientResponse$InputStreamWrapper@160a4908 试试这个:BufferedReader in = new BufferedReader( new InputStreamReader(response.getEntity())); String inputLine; StringBuffer content = new StringBuffer(); while ((inputLine = in.readLine()) != null) content.append(inputLine); in.close();

以上是关于如何从服务获取响应的 JSON的主要内容,如果未能解决你的问题,请参考以下文章

Swift 2,如何从多阶段 JSON 响应中获取值

如何从get请求获取json响应而不是html响应?

如何从包含其他参数的响应中获取 JSON 对象列表

如何在 Javascript 中从 Spring 获取 JSON 响应

如何获取 Xcode 服务器代码覆盖率 API JSON 响应

通过 AFNetworking 从服务器获取 Json 响应