How to use Java to load weather forecast data

In this article, we will use a RESTful Weather API to load weather forecast data into a simple Java application. We will retrieve the same weather forecast in JSON format so we can manipulate the weather forecast data easily within our Java application.

Steps to retrieving the weather forecast in Java

Retrieving the weather forecast in Java is quite straightforward. Here are the steps involved:

  1. Create a RESTful request to retrieve the weather forecast.
  2. Retrieve the data via HTTP GET query.
  3. Process the data as as CSV or JSON.

You can find the full sample code for this article on our GitHub:

https://github.com/visualcrossing/WeatherApi/blob/master/Java/com/visualcrossing/weather/samples/TimelineApiForecastSample.java

Prerequisites

We are using the Visual Crossing Weather API so we need an API key to get started. Before continuing, please set up a free account and make a note of the API Key.

If you would like to experiment with the available weather data without using the API, you can create an account and view the data directly in the browser using the Weather Data Services web site.

Retrieve the Weather Forecast as JSON in Java

In our first sample code, we will construct the Weather API request and retrieve the JSON formatted result.

Set up Apache HttpComponents

We will use the Apache HttpComponents library to submit the HTTP request. It’s possible to do this using raw Java communication packages, but using a library such as HttpComponents allows us to focus on constructing the Weather API request and processing the result. If you have a different library to submit and retrieve HTTP requests, then that should work as well.

To include the Apache HttpComponents you can use the following Maven Dependency:

<dependency>
   <groupId>org.apache.httpcomponents</groupId>
   <artifactId>httpclient</artifactId>
   <version>4.5.12</version>
</dependency>

Importing the HTTPS certificate into your Java Keystore

As the weather API endpoint is a secure HTTPS endpoint, you may need to import the certificate into your Java keystore. For more information, see https://docs.oracle.com/javase/tutorial/security/toolsign/rstep2.html

Constructing the Weather API request

The Weather API request we will make is straight forward:

https://weather.visualcrossing.com/VisualCrossingWebServices/rest/services/timeline/London%2CUK?unitGroup=metric&key=YOUR_API_KEY

The following code constructs the request to retrieve this same weather forecast request for London, UK by day.

String apiEndPoint="https://weather.visualcrossing.com/VisualCrossingWebServices/rest/services/timeline/";
String location="London, UK";
String startDate=null; //optional (omit for forecast)
String endDate=null; //optional (requires a startDate if present)
String unitGroup="metric"; //us,metric,uk 
String apiKey="YOUR_API_KEY";

We will use the following parameters:

unitGroup=metric – We would like metric units (eg Celsius for temperature and mm for rainfall etc.). We could also specify ‘us’ for the units typically used in the United States (Fahrenheit, inches etc.).

key=YOUR_API_KEY – to unique identify your request. Don’t forget to replace ‘YOUR_API_KEY’ with your actual API key.

location=London,UK – one or more locations specified by address, partial address (for example city, postal code or zip) or latitude, longitude values.

For more information on the parameters of the Weather API, see the API documentation.

We can now build the actual URL:

//Build the URL pieces
StringBuilder requestBuilder=new StringBuilder(apiEndPoint);
requestBuilder.append(location);
		
if (startDate!=null && !startDate.isEmpty()) {
	requestBuilder.append("/").append(startDate);
	if (endDate!=null && !endDate.isEmpty()) {
		requestBuilder.append("/").append(endDate);
	}
}
		
//Build the parameters to send via GET or POST
URIBuilder builder = new URIBuilder(requestBuilder.toString());
builder.setParameter("unitGroup", unitGroup)
	.setParameter("key", apiKey);

//for GET requests, add the parameters to the request
if ("GET".equals(method)) {
	requestBuilder.append("?").append(paramBuilder);
}

Submit the Weather API Request

The following code submits the request to the Weather API. The techniques here are based around the fundamentals of the HttpClient.

HttpGet get = new HttpGet(builder.build());
		
CloseableHttpClient httpclient = HttpClients.createDefault();
		
CloseableHttpResponse response = httpclient.execute(get);    
		
String rawResult=null;
try {
	if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
		System.out.printf("Bad response status code:%d%n",		
					response.getStatusLine().getStatusCode());
		return;
	}			
	HttpEntity entity = response.getEntity();
	if (entity != null) {
		rawResult=EntityUtils.toString(entity, Charset.forName("utf-8"));
	}
		    
} finally {
	response.close();
}
		
parseTimelineJson(rawResult);

Note that we do not perform exception handling for clarity. It is important to ensure that the http response is closed when it’s used.

If the request is successful, we now have the weather forecast populated as a JSON formatted in the ‘rawResult’ variable. It is also possible to request the data in CSV format if that is a more suitable format for your application.

Parse the Weather Forecast JSON data

The previous code sample retrieves the weather forecast data. We will create a simple table from that table by parsing the JSON data.

We are going to use the JSON.org parser for simplicity. Any JSON parser should work however so if you are already using one in your project, feel free to use that.

To add org.json.JSON as a dependency, you can use the following Maven dependency:

<dependency>
  <groupId>org.json</groupId>
  <artifactId>json</artifactId>
  <version>20200518</version>
</dependency>

First we parse the text:

JSONObject timelineResponse = new JSONObject(rawResult);
		
ZoneId zoneId=ZoneId.of(timelineResponse.getString("timezone"));
		
System.out.printf("Weather data for: %s%n", timelineResponse.getString("resolvedAddress"));

Note that the only difference is that we parse the ‘rawResult’ variable as JSON by creating a JSONObject:

Using the JSON Weather Data in Java

After parsing the text, we extract the time zone for the requested location. This is returned in the JSON as the ‘timezone’ property. We can use the result to create a Java ZoneId instance, which we will use to construct ZoneDateTime instances for the weather data.

To use the data, we will create a simple tab limited result on the console using a loop around the ‘days’ property. The days property is an array of dates within the result.

JSONArray values=timelineResponse.getJSONArray("days");
		
System.out.printf("Date\tMaxTemp\tMinTemp\tPrecip\tSource%n");
for (int i = 0; i < values.length(); i++) {
    JSONObject dayValue = values.getJSONObject(i);

    ZonedDateTime datetime=
        ZonedDateTime.ofInstant(Instant.ofEpochSecond(
            dayValue.getLong("datetimeEpoch")), zoneId);
            
    double maxtemp=dayValue.getDouble("tempmax");
    double mintemp=dayValue.getDouble("tempmin");
    double pop=dayValue.getDouble("precip");
    String source=dayValue.getString("source");
    System.out.printf("%s\t%.1f\t%.1f\t%.1f\t%s%n",         
        datetime.format(DateTimeFormatter.ISO_LOCAL_DATE),
            maxtemp, mintemp, pop,source );
}

The date for each date can be reconstructed from the datetimeEpoch property which represents the number of seconds since the UNIX epoch (Midnight on the 1st January 1970 UTC time). We use the ZoneId that we created in the previous step to create a ZonedDateTime instance.

The final result is a simple, tab limited weather data output to the console:

Weather data for: London, England, United Kingdom
 Date    MaxTemp MinTemp Precip  Source
 2021-08-25    22.2    13.7    0.0 comb
 2021-08-26    20.3    13.7    0.0 fcst
 2021-08-27    21.7    12.0    0.1 fcst
 2021-08-28    21.7    12.2    0.0 fcst
 2021-08-29    21.5    12.8    0.0 fcst
 2021-08-30    19.3    9.4     0.0 fcst
 2021-08-31    18.8    10.1    0.0 fcst
 2021-09-01    22.5    10.0    0.0 fcst
 2021-09-02    22.5    10.4    0.0 fcst
 2021-09-03    23.4    10.0    0.0 fcst
 2021-09-04    23.6    10.9    0.0 fcst
 2021-09-05    23.2    14.1    0.1 fcst
 2021-09-06    19.8    13.2    4.5 fcst
 2021-09-07    17.0    11.6    4.6 fcst
 2021-09-08    18.5    9.1     0.0 fcst

Conclusions

Retrieving the weather forecast into a Java application is very straightforward with simple Java application such as this. This can be easily extended to include historical weather data as the Timeline Weather API seamlessly combines both historical and forecast data in a single API call.

Questions or need help?

If you have a question or need help, please post on our actively monitored forum for the fastest replies. You can also contact us via our support site or drop us an email at support@visualcrossing.com.