Search code examples
javaspring-boothttpsgetyahoo-weather-api

How to consume a HTTPS GET service with Spring Boot


I am trying to consume the following HTTPS endpoints from Yahoo Weather Service:

Yahoo Weather Service API

I am doing some special query according to the API to get the current weather at some parametrized location.

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

Location is a class that provides the attribute "name" that is a String description of the location, such as "New York" or "Manila".

Condition an other classes just map the returning object.

When executing I get the following HTTP response:

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

So this means I am not authorized to access the resource from what I understand.

The URL works great if I just copy & paste it in a web browser:

Yahoo Weather Query

I think that mapping is not a problem since I am not getting "400" (Bad Request) but "403" (Forbidden)

There must be some error on the way I use the RestTemplate object. I am researching but I can't find an answer.


Solution

  • I finally found the answer. It finally WAS a Bad Request because I needed to pass the parameters differently (not as part of the URL).

    I found the answer here. Here goes the code for my particular Yahoo Weather API call return a String (I still will have to do some work to use the mapping).

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