Как использовать службу HTTPS GET с Spring Boot

Я пытаюсь использовать следующие конечные точки HTTPS из службы погоды Yahoo:

API службы погоды Yahoo

Я делаю специальный запрос в соответствии с API, чтобы получить текущую погоду в каком-то параметризованном месте.

@Service("weatherConditionService")
public class WeatherConditionServiceImpl implements WeatherConditionService {

    private static final String URL = "http://query.yahooapis.com/v1/public/yql";

    public WeatherCondition getCurrentWeatherConditionsFor(Location location) {
        RestTemplate restTemplate = new RestTemplate();
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append(URL);
        stringBuilder.append("?q=select%20item.condition%20from%20weather.forecast%20where%20woeid%20in%20(select%20woeid%20from%20geo.places(1)%20where%20text%3D%22");
        // TODO: Validate YQL query injection
        stringBuilder.append(location.getName());
        stringBuilder.append("%22)&format=json&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys");
        WeatherQuery weatherQuery = restTemplate.getForObject(stringBuilder.toString(), WeatherQuery.class);
        // TODO: Test Json mapping response
        Condition condition = weatherQuery.getQuery().getResults().getChannel().getItem().getCondition();
        return new WeatherCondition(condition.getDate(), Integer.parseInt(condition.getTemp()), condition.getText());
    }

Местоположение — это класс, предоставляющий атрибут «имя», представляющий собой строковое описание местоположения, например «Нью-Йорк» или «Манила».

Условие других классов просто отображает возвращаемый объект.

При выполнении я получаю следующий HTTP-ответ:

org.springframework.web.client.HttpClientErrorException: 403 Forbidden

Итак, это означает, что я не авторизован для доступа к ресурсу, насколько я понимаю.

URL-адрес отлично работает, если я просто скопирую и вставлю его в веб-браузере:

Запрос погоды Yahoo

Я думаю, что сопоставление не является проблемой, поскольку я получаю не «400» (неверный запрос), а «403» (запрещено)

Должна быть какая-то ошибка в том, как я использую объект RestTemplate. Я исследую, но я не могу найти ответ.


person Sebastian D'Agostino    schedule 02.11.2017    source источник


Ответы (2)


В документах сказано, что вам нужен ключ API. Но когда я делаю вызов следующим образом:

fetch('https://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20weather.forecast%20where%20woeid%20in%20(select%20woeid%20from%20geo.places(1)%20where%20text%3D%22nome%2C%20ak%22)&format=json&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys')
.then(resp=> resp.json())
.then((res)=>console.log(res.query.results))

https://repl.it/NeoM

Без него нормально работает. Возможно, вас занесли в черный список за слишком частое обращение к API.

Ваш код выглядит нормально.

person Robert Moskal    schedule 02.11.2017
comment
Спасибо. Я могу сделать это с помощью javascript или непосредственно в веб-браузере. Примеров Java нет, поэтому я догадался, что мне не нужен ключ API. Это может быть все. Мне нужно проверить, как это сделать в Java. - person Sebastian D'Agostino; 02.11.2017

Я наконец нашел ответ. Наконец, это БЫЛО неверным запросом, потому что мне нужно было передать параметры по-другому (не как часть URL-адреса).

Я нашел ответ здесь. Вот код для моего конкретного вызова API погоды Yahoo, возвращающего строку (мне все равно придется проделать некоторую работу, чтобы использовать сопоставление).

   private static final String URL = "http://query.yahooapis.com/v1/public/yql";

   public String callYahooWeatherApi() {

        RestTemplate restTemplate = new RestTemplate();

        HttpHeaders headers = new HttpHeaders();
        headers.set("Accept", MediaType.APPLICATION_JSON_VALUE);

        UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(URL)
                .queryParam("q", "select wind from weather.forecast where woeid=2460286")
                .queryParam("format", "json");

        HttpEntity<?> entity = new HttpEntity<>(headers);

        HttpEntity<String> response = restTemplate.exchange(
                builder.build().encode().toUri(),
                HttpMethod.GET,
                entity,
                String.class);

        return response.getBody();

    }
person Sebastian D'Agostino    schedule 28.11.2017