REST API 的目标天气 API 未在邮递员中返回 JSON 数据

Destination Weather API for REST API not returning JSON data in postman

我正在 java 中创建一个 REST API 并在邮递员和数据库中测试它有纬度和经度,我正在尝试使用 OpenWeather API 到 return 基于经纬度的天气数据。然而,当在邮递员中测试它时,它 returning 一个 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 时,return是这个

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

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

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

它 return 是正确的 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 中?

我在 postman 中测试了 URL,它 returns 的响应是正确的。 检查下面的屏幕,也许您正在做一些不同的事情。

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

]

Postman 是 parsing/showing 正确的值,因为您在响应中发送 url。

要在您的代码中调用 API,您需要使用 HTTP Client/Handler。如果您只是将 URL 分配给一个变量,它只会将其存储为一个字符串,并且永远不会调用 given url。

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


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

方法 1:

@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;
    }
}

方法 2:

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;
    }
}

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

@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 错误处理程序。