【问题标题】:Destination Weather API for REST API not returning JSON data in postmanREST API 的目的地天气 API 未在邮递员中返回 JSON 数据
【发布时间】:2020-04-22 23:13:39
【问题描述】:

我正在用 java 创建一个 REST API 并在 postman 中对其进行测试,并且在数据库中有纬度和经度,我正在尝试使用 OpenWeather API 根据纬度和经度返回天气数据。但是,在邮递员中对其进行测试时,它返回的是 HTML 而不是我请求的 JSON 数据。

我要测试的路径是

http://localhost:8080/Assignment2C/map/weather/4

我的控制器中的代码是

  @GetMapping(value = "weather/{id}", produces = MediaType.APPLICATION_JSON_VALUE)
    public String getWeather(@PathVariable("id") int id) {
        BreweriesGeocode geocode = geocode_service.getGeocode(id);
        Breweries brewerie = breweries_service.getBrewerieById(id);

        double latitude = geocode.getLatitude();
        double longitude = geocode.getLongitude();
       String output = "https://api.openweathermap.org/data/2.5/weather?lat=" + latitude + "&lon=" + longitude + "&appid=4a1f5501b2798f409961c62d384a1c74";
       return output;

当使用 Postman 时,它会返回这个

https: //api.openweathermap.org/data/2.5/weather?lat=59.74509811401367&lon=10.213500022888184&appid=4a1f5501b2798f409961c62d384a1c74

但是当我测试邮递员在浏览器中生成的路径时

https://api.openweathermap.org/data/2.5/weather?lat=59.74509811401367&lon=10.213500022888184&appid=4a1f5501b2798f409961c62d384a1c74

它返回正确的 JSON 数据

这是

{"coord":{"lon":10.21,"lat":59.75},"weather":[{"id":800,"main":"Clear","description":"clear sky","icon":"01d"}],"base":"stations","main":{"temp":291.36,"feels_like":289.49,"temp_min":288.71,"temp_max":294.26,"pressure":1028,"humidity":40},"wind":{"speed":0.89,"deg":190},"clouds":{"all":1},"dt":1587551663,"sys":{"type":3,"id":2006615,"country":"NO","sunrise":1587526916,"sunset":1587581574},"timezone":7200,"id":6453372,"name":"Drammen","cod":200}

我在测试时如何让 JSON 数据出现在 postman 中?

【问题讨论】:

    标签: java json rest postman openweathermap


    【解决方案1】:

    当您在响应中发送 url 时,邮递员正在解析/显示正确的值。

    要在代码中调用 API,您需要使用 HTTP 客户端/处理程序。如果您只是将 URL 分配给变量,它只会将其存储为字符串,并且永远不会调用给定的 url。

    RestTemplate 类(在 Spring 中默认可用,不需要其他依赖项)是一个简单的 HTTP 客户端,它允许从您的代码中进行 API 调用。
    您可以使用 RestTemplate 调用 OpenWeather API 并获取 JSON 响应,可以在 Postman 中返回和查看相同的响应。


    如果您确定只进行 HTTP 调用而不进行 HTTPS,则遵循方法 1,否则遵循方法 2 -

    方法一:

    @RestController
    public class WeatherController{
    
        @Autowired
        RestTemplate restTemplate;
    
        @GetMapping(value = "weather/{id}", produces = MediaType.APPLICATION_JSON_VALUE)
        public String getWeather(@PathVariable("id") int id) {
            BreweriesGeocode geocode = geocode_service.getGeocode(id);
            Breweries brewerie = breweries_service.getBrewerieById(id);
    
            double latitude = geocode.getLatitude();
            double longitude = geocode.getLongitude();
            String url = "http://api.openweathermap.org/data/2.5/weather?lat="+latitude+"&lon="+longitude+"&appid=4a1f5501b2798f409961c62d384a1c74";
    
            //Calling OpenWeather API
            ResponseEntity<String> response = restTemplate.getForEntity(url, String.class);
            String output = response.getBody();
            return output;
        }
    }
    
    

    方法二:

    import java.security.KeyManagementException;
    import java.security.KeyStoreException;
    import java.security.NoSuchAlgorithmException;
    import java.security.cert.X509Certificate;
    
    import javax.net.ssl.SSLContext;
    
    import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
    import org.apache.http.conn.ssl.TrustStrategy;
    import org.apache.http.impl.client.CloseableHttpClient;
    import org.apache.http.impl.client.HttpClients;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
    import org.springframework.stereotype.Component;
    import org.springframework.web.client.RestTemplate;
    
    @Component
    public class CustomRestTemplate {
    
        /**
         * @param isHttpsRequired - pass true if you need to call a https url, otherwise pass false
         */
        public RestTemplate getRestTemplate(boolean isHttpsRequired)
                throws KeyManagementException, NoSuchAlgorithmException, KeyStoreException {
    
            // if https is not required,
            if (!isHttpsRequired) {
                return new RestTemplate();
            }
    
            // else below code adds key ignoring logic for https calls
            TrustStrategy acceptingTrustStrategy = (X509Certificate[] chain, String authType) -> true;
            SSLContext sslContext = org.apache.http.ssl.SSLContexts.custom().loadTrustMaterial(null, acceptingTrustStrategy)
                    .build();
    
            SSLConnectionSocketFactory csf = new SSLConnectionSocketFactory(sslContext);
    
            CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(csf).build();
    
            HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
            requestFactory.setHttpClient(httpClient);
    
            RestTemplate restTemplate = new RestTemplate(requestFactory);       
            return restTemplate;
        }
    }
    
    

    然后在控制器类中你可以做如下-

    @RestController
    public class WeatherController{
    
    
        @Autowired
        CustomRestTemplate customRestTemplate;
    
        @GetMapping(value = "weather/{id}", produces = MediaType.APPLICATION_JSON_VALUE)
        public String getWeather(@PathVariable("id") int id) {
            BreweriesGeocode geocode = geocode_service.getGeocode(id);
            Breweries brewerie = breweries_service.getBrewerieById(id);
    
            double latitude = geocode.getLatitude();
            double longitude = geocode.getLongitude();
            String url = "https://api.openweathermap.org/data/2.5/weather?lat="+latitude+"&lon="+longitude+"&appid=4a1f5501b2798f409961c62d384a1c74";
    
            // Getting instance of Rest Template
            // Passing true becuase the url is a HTTPS url
            RestTemplate restTemplate = customRestTemplate.getRestTemplate(true);
    
            //Calling OpenWeather API
            ResponseEntity<String> response = restTemplate.getForEntity(url, String.class);
    
            String output = response.getBody();
    
            return output;
        }
    }
    
    

    如果响应代码不是成功代码,您可以为 RestTemplate 响应编写 Http 错误处理程序。

    【讨论】:

    • 感谢您的回答,HTTP 不需要是 HTTPS,所以为了避免添加不必要的依赖项,如何更改控制器使其不需要使用 customRestTemplate?
    • @GreyWolf18 我们不需要对 RestTemplate 的任何依赖,它在 Spring 中默认可用。
    • 另外,您不能仅通过将 url 分配给字符串变量来调用 api。您的代码中需要一些 HTTP 客户端/处理程序,它将使用 url 调用 api。同样,RestTemplate 类提供现成的 http 客户端,您只需要使用它调用 url。
    • 我知道我不需要 RestTemplate 的依赖项,但是在 customRestTemplate 中,我无法添加 TrustStrategy、SSLContext、HttpComponentsClientHttpRequestFactory 和其他一些,我认为需要依赖项,什么是有办法解决这个问题吗?
    • @GreyWolf18 我已经更新了答案,如果你确定你只会使用 Http 然后按照方法 1,它很小、干净且易于理解。调用 api 就足够了。
    【解决方案2】:

    我在邮递员中测试了 URL,它返回了正确的响应。 检查下面的屏幕,也许你正在做一些不同的事情。

    确保 url 中没有空格,我看到您在 Postman 中使用的 url 在“:”之后有空格

    【讨论】:

    • 是的,我意识到 http 后面的空格,对不起,我忘了提到我正在测试路径 localhost:8080/Assignment2C/map/weather/4 以及如何通过调用我的 API 使用邮递员搜索浏览器
    • 这是您的本地环境,我无法访问,但希望我的回答对您有所帮助
    猜你喜欢
    • 2021-12-26
    • 1970-01-01
    • 1970-01-01
    • 2018-09-11
    • 2015-11-11
    • 2020-08-02
    • 1970-01-01
    • 2021-05-21
    • 2016-02-15
    相关资源
    最近更新 更多