Weather forecast


This project aims at using third party software components. It may not be appropriate if you fancy bottom up coding yourself.

In this project you'll implement a terminal based weather forecast application. Consider the following invocation:

Figure 587. Sample forecast session Slide presentation

Figure 588. Sample forecast invocation Slide presentation
goik@goiki target> java -jar weather-1.0.jar Stuttgart 
1 = Stadtkreis Stuttgart         
2 = Regierungsbezirk Stuttgart 
3 = Stuttgart
4 = Stuttgart Feuerbach
5 = Stuttgart Muehlhausen

Bitte gültige Auswahl 1 bis 5 treffen:2 
Vorhersage für Regierungsbezirk Stuttgart 
Dienstag, 15.05
    23:00:  11°C, Leichter Regen
Mittwoch, 16.05
    02:00:  10°C, Leichter Regen
    05:00:  10°C, Leichter Regen
    08:00:  11°C, Leichter Regen

Command line argument Stuttgart acting as a search filter.

The filter Stuttgart yields five matching towns / regions.

User choosing second match.

Forecast corresponding to Regierungsbezirk Stuttgart.

The actual weather data is being provided by a web service:

Figure 589. Underlying data provider Slide presentation 

"description":"Leichter Regen","icon":"10n"}],"clouds":
{"3h":0.315},"sys":{"pod":"n"},"dt_txt":"2018-05-16 00:00:00"},           
{"dt":1526439600,"main": ...

An URL containing an id value corresponding to a uniquely defined town or region. We identify the following components:


Provide German localization e.g. «Leichter Regen» in favour of «light rain».


This parameter allows for accessing the service: «7cufdhdcgdhsgdhgfcgsdss67b3» is actually a fake value. Your project requires obtaining an APPID token.


Favour metric over imperial units.


«3214105» identifies «Regierungsbezirk Stuttgart», see line 262703 in cities.list.json:

"id": 3214105,
"name": "Regierungsbezirk Stuttgart",
"country": "DE",
"coord": {
  "lon": 9.66667,
  "lat": 49.083328
}'s reply providing JSON based weather data.

Figure 590. cities.list.json.gz providing cities Slide presentation
    "id": 2886241,
    "name": "Regierungsbezirk Köln",
    "country": "DE",
    "coord": {
      "lon": 7.16667,
      "lat": 50.833328
    "id": 3247452,
    "name": "Kreis Euskirchen",

Figure 591. ma/Copy URL result to file Slide presentation
  new File("weatherData.json"));

Figure 592. Parse city data Slide presentation
public class Cities {
  static public final City[] cities;
@Test public void testParsedCityCount() {
  Assert.assertEquals(209579, Cities.cities.length);

Figure 593. Parse weather data Slide presentation
public class WeatherDataParser {

  static public final Weather parse(final String jsonWeatherDataFilename)
     throws IOException {
    return ...;
@Test public void testParseWeatherData() {
  Weather weather = WeatherDataParser.parse(

Figure 594. Requirements Slide presentation
  1. The application shall accept a command line parameter like e.g. «Stuttgart» to filter matching cities from cities.list.json.

  2. If a given filter matches multiple locations the user shall have an option for choosing the desired one.

  3. The most recent city id value shall be cached in a file. Subsequent invocations without command line parameter shall provide a current forecast corresponding to this value.

  4. Weather data belonging to a given id value shall be cached locally for 10 minutes. Subsequent weather queries within this period shall be read from cache rather than by accessing .

    Provide logging to a file rather than to the console to avoid cluttering the user interface. Log cache handling.

Figure 595. Logging Slide presentation
  • Provide logging to a file rather than to the console to avoid cluttering the user interface.

  • Log cache handling.

main INFO  weather.Forecast - Re-using cache file
 '/ma/goik/Forecast/6930414.json' from 196 seconds ago


See the related skeleton project.