API погоды для REST API не возвращает JSON данных в почтальоне - PullRequest
0 голосов
/ 22 апреля 2020

Я создаю REST API в java и тестирую его в почтальоне и в базе данных с указанием широты и долготы. Я пытаюсь использовать 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 появляться в почтальоне при тестировании?

Ответы [ 2 ]

1 голос
/ 22 апреля 2020

Почтальон анализирует / показывает правильное значение, так как вы отправляете URL в ответе.

Для вызова API в вашем коде вам нужно использовать HTTP-клиент / обработчик. Если вы просто назначите URL переменной, она просто сохранит ее в виде строки и никогда не будет вызывать данный URL.

RestTemplate class (доступен по умолчанию в Spring, другие зависимости не требуются) - это простой HTTP-клиент, который позволяет выполнять вызовы API из вашего кода.
Вы можете использовать RestTemplate для вызовите API OpenWeather и получите ответ 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;
    }
}

Затем в классе контроллеров вы можете сделать следующее:

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

Вы можете написать Http Error Handler для ответов RestTemplate, если код ответа не является кодом успеха.

1 голос
/ 22 апреля 2020

Я проверил URL в почтальоне, он возвращает правильный ответ. Проверьте экран ниже, возможно, вы делаете что-то другое. Postman response

Убедитесь, что в URL нет пробелов, я вижу, что URL, который вы использовали в Почтальоне, имел пробел после ":"

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...