├── .classpath ├── .project ├── .settings ├── .jsdtscope ├── org.eclipse.core.resources.prefs ├── org.eclipse.jdt.core.prefs ├── org.eclipse.wst.common.component ├── org.eclipse.wst.common.project.facet.core.xml ├── org.eclipse.wst.jsdt.ui.superType.container └── org.eclipse.wst.jsdt.ui.superType.name ├── build └── classes │ └── MyPackage │ └── MyServlet.class ├── gitignore ├── readme.md └── src └── main ├── java └── MyPackage │ └── MyServlet.java └── webapp ├── META-INF └── MANIFEST.MF ├── WEB-INF ├── lib │ └── gson-2.8.5.jar └── web.xml ├── images └── weather-logo.png ├── index.html ├── index.jsp ├── myScript.js └── style.css /.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | MyWeatherApp 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | org.eclipse.wst.common.project.facet.core.builder 15 | 16 | 17 | 18 | 19 | org.eclipse.wst.validation.validationbuilder 20 | 21 | 22 | 23 | 24 | 25 | org.eclipse.jem.workbench.JavaEMFNature 26 | org.eclipse.wst.common.modulecore.ModuleCoreNature 27 | org.eclipse.wst.common.project.facet.core.nature 28 | org.eclipse.jdt.core.javanature 29 | org.eclipse.wst.jsdt.core.jsNature 30 | 31 | 32 | -------------------------------------------------------------------------------- /.settings/.jsdtscope: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.settings/org.eclipse.core.resources.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | encoding/=UTF-8 3 | -------------------------------------------------------------------------------- /.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled 3 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=17 4 | org.eclipse.jdt.core.compiler.compliance=17 5 | org.eclipse.jdt.core.compiler.problem.assertIdentifier=error 6 | org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled 7 | org.eclipse.jdt.core.compiler.problem.enumIdentifier=error 8 | org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning 9 | org.eclipse.jdt.core.compiler.release=enabled 10 | org.eclipse.jdt.core.compiler.source=17 11 | -------------------------------------------------------------------------------- /.settings/org.eclipse.wst.common.component: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /.settings/org.eclipse.wst.common.project.facet.core.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /.settings/org.eclipse.wst.jsdt.ui.superType.container: -------------------------------------------------------------------------------- 1 | org.eclipse.wst.jsdt.launching.baseBrowserLibrary -------------------------------------------------------------------------------- /.settings/org.eclipse.wst.jsdt.ui.superType.name: -------------------------------------------------------------------------------- 1 | Window -------------------------------------------------------------------------------- /build/classes/MyPackage/MyServlet.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lodhik9/Java-MyWeatherApp/5d3c0fa9e6afa895aaf28b377f359ec7098c8ef3/build/classes/MyPackage/MyServlet.class -------------------------------------------------------------------------------- /gitignore: -------------------------------------------------------------------------------- 1 | *# 2 | *.iml 3 | *.ipr 4 | *.iws 5 | *.jar 6 | *.sw? 7 | *~ 8 | .#* 9 | .*.md.html 10 | .DS_Store 11 | .attach_pid* 12 | .classpath 13 | .factorypath 14 | .gradle 15 | .idea 16 | .metadata 17 | .project 18 | .recommenders 19 | .settings 20 | .springBeans 21 | .vscode 22 | /code 23 | MANIFEST.MF 24 | _site/ 25 | activemq-data 26 | bin 27 | build 28 | !/**/src/**/bin 29 | !/**/src/**/build 30 | build.log 31 | dependency-reduced-pom.xml 32 | dump.rdb 33 | interpolated*.xml 34 | lib/ 35 | manifest.yml 36 | out 37 | overridedb.* 38 | target 39 | .flattened-pom.xml 40 | secrets.yml 41 | .gradletasknamecache 42 | .sts4-cache 43 | 44 | # Created by https://www.toptal.com/developers/gitignore/api/windows,java,eclipse 45 | # Edit at https://www.toptal.com/developers/gitignore?templates=windows,java,eclipse 46 | 47 | ### Eclipse ### 48 | .metadata 49 | bin/ 50 | tmp/ 51 | *.tmp 52 | *.bak 53 | *.swp 54 | *~.nib 55 | local.properties 56 | .settings/ 57 | .loadpath 58 | .recommenders 59 | 60 | # External tool builders 61 | .externalToolBuilders/ 62 | 63 | # Locally stored "Eclipse launch configurations" 64 | *.launch 65 | 66 | # PyDev specific (Python IDE for Eclipse) 67 | *.pydevproject 68 | 69 | # CDT-specific (C/C++ Development Tooling) 70 | .cproject 71 | 72 | # CDT- autotools 73 | .autotools 74 | 75 | # Java annotation processor (APT) 76 | .factorypath 77 | 78 | # PDT-specific (PHP Development Tools) 79 | .buildpath 80 | 81 | # sbteclipse plugin 82 | .target 83 | 84 | # Tern plugin 85 | .tern-project 86 | 87 | # TeXlipse plugin 88 | .texlipse 89 | 90 | # STS (Spring Tool Suite) 91 | .springBeans 92 | 93 | # Code Recommenders 94 | .recommenders/ 95 | 96 | # Annotation Processing 97 | .apt_generated/ 98 | .apt_generated_test/ 99 | 100 | # Scala IDE specific (Scala & Java development for Eclipse) 101 | .cache-main 102 | .scala_dependencies 103 | .worksheet 104 | 105 | # Uncomment this line if you wish to ignore the project description file. 106 | # Typically, this file would be tracked if it contains build/dependency configurations: 107 | #.project 108 | 109 | ### Eclipse Patch ### 110 | # Spring Boot Tooling 111 | .sts4-cache/ 112 | 113 | ### Java ### 114 | # Compiled class file 115 | *.class 116 | 117 | # Log file 118 | *.log 119 | 120 | # BlueJ files 121 | *.ctxt 122 | 123 | # Mobile Tools for Java (J2ME) 124 | .mtj.tmp/ 125 | 126 | # Package Files # 127 | *.jar 128 | *.war 129 | *.nar 130 | *.ear 131 | *.zip 132 | *.tar.gz 133 | *.rar 134 | 135 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 136 | hs_err_pid* 137 | replay_pid* 138 | 139 | ### Windows ### 140 | # Windows thumbnail cache files 141 | Thumbs.db 142 | Thumbs.db:encryptable 143 | ehthumbs.db 144 | ehthumbs_vista.db 145 | 146 | # Dump file 147 | *.stackdump 148 | 149 | # Folder config file 150 | [Dd]esktop.ini 151 | 152 | # Recycle Bin used on file shares 153 | $RECYCLE.BIN/ 154 | 155 | # Windows Installer files 156 | *.cab 157 | *.msi 158 | *.msix 159 | *.msm 160 | *.msp 161 | 162 | # Windows shortcuts 163 | *.lnk 164 | 165 | # End of https://www.toptal.com/developers/gitignore/api/windows,java,eclipse -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # Weather Web App 2 | 3 | This is a web application built using **Java Servlets**, **JSP**, and the **OpenWeatherMap API**. It allows users to retrieve current weather information for a specified city. 4 | 5 | --- 6 | 7 | ### 1.Technologies Used 8 | 9 | --- 10 | 11 | - Java 12 | - Servlets 13 | - JSP 14 | - HTML 15 | - CSS 16 | - JavaScript 17 | - OpenWeatherMap API 18 | - Google Fonts 19 | 20 | --- 21 | 22 | ### 2.Getting Started 23 | 24 | --- 25 | 26 | To run this application locally, you'll need a Java Development Environment (JDK) and a web server like Apache Tomcat. 27 | 28 | 1. Clone the repository or download the source code. 29 | 2. Import the project into your preferred Java IDE (e.g., Eclipse, IntelliJ IDEA). 30 | 3. Configure the web server to deploy the application. 31 | 4. Obtain an API key from the OpenWeatherMap API website (https://openweathermap.org/api). 32 | 5. Replace the placeholder API key in the `MyServlet.java` file with your actual API key. 33 | 6. Run the application and access it through the configured URL (e.g., `http://localhost:8080/WeatherApp`). 34 | 35 | --- 36 | 37 | ### 3.Usage 38 | 39 | --- 40 | 41 | 1. On the main page, enter the name of the city for which you want to retrieve weather information. 42 | 2. Click the search button or press Enter. 43 | 3. The application will fetch the current weather data from the OpenWeatherMap API and display it on the page. 44 | 45 | --- 46 | 47 | ### 4.Features 48 | 49 | --- 50 | 51 | - User-friendly interface with a search input field and a submit button. 52 | - Displays the current weather information for the specified city, including temperature, humidity, wind speed, and a weather icon representing the current conditions. 53 | - Responsive design for optimal viewing on different devices. 54 | 55 | --- 56 | 57 | ### 5.File Structure and Code 58 | 59 | --- 60 | 61 | - `MyServlet.java`: The main servlet class that handles the HTTP requests and integrates with the OpenWeatherMap API. 62 | 63 | _[src/main/java/MyPackage/MyServlet.java](src/main/java/MyPackage/MyServlet.java)_ 64 | 65 | ```java 66 | package MyPackage; 67 | 68 | import jakarta.servlet.ServletException; 69 | import jakarta.servlet.annotation.WebServlet; 70 | import jakarta.servlet.http.HttpServlet; 71 | import jakarta.servlet.http.HttpServletRequest; 72 | import jakarta.servlet.http.HttpServletResponse; 73 | import java.io.IOException; 74 | import java.io.InputStream; 75 | import java.io.InputStreamReader; 76 | import java.net.HttpURLConnection; 77 | import java.net.URL; 78 | import java.util.Date; 79 | import java.util.Scanner; 80 | 81 | import com.google.gson.Gson; 82 | import com.google.gson.JsonElement; 83 | import com.google.gson.JsonObject; 84 | 85 | /** 86 | * Servlet implementation class MyServlet 87 | */ 88 | public class MyServlet extends HttpServlet { 89 | private static final long serialVersionUID = 1L; 90 | 91 | /** 92 | * @see HttpServlet#HttpServlet() 93 | */ 94 | public MyServlet() { 95 | super(); 96 | } 97 | 98 | /** 99 | * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) 100 | */ 101 | protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 102 | response.getWriter().append("Served at: ").append(request.getContextPath()); 103 | } 104 | 105 | /** 106 | * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) 107 | */ 108 | protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 109 | 110 | //API Setup 111 | String apiKey = "8071998b04156cb295e9e3c3b8336359"; 112 | // Get the City name from the form's input 113 | String city = request.getParameter("city"); 114 | // Create the URL for the OpenWeatherMap API request 115 | String apiUrl = "https://api.openweathermap.org/data/2.5/weather?q=" + city + "&appid=" + apiKey; 116 | 117 | // API Integration 118 | URL url = new URL(apiUrl); 119 | HttpURLConnection connection = (HttpURLConnection)url.openConnection(); 120 | connection.setRequestMethod("GET"); 121 | 122 | // Reading the data from the Network 123 | InputStream inputStream = connection.getInputStream(); 124 | InputStreamReader inputStreamReader = new InputStreamReader(inputStream); 125 | 126 | // Store data in String 127 | StringBuilder responseContent = new StringBuilder(); 128 | 129 | // To take input from inputStreamReader 130 | Scanner scanner = new Scanner(inputStreamReader); 131 | 132 | while(scanner.hasNext()) { 133 | responseContent.append(scanner.nextLine()); 134 | } 135 | 136 | scanner.close(); 137 | //System.out.println(responseContent); 138 | 139 | // TypeCasting the data into JSON (separate data) 140 | Gson gson = new Gson(); 141 | JsonObject jsonObject = gson.fromJson(responseContent.toString(), JsonObject.class); 142 | //System.out.println(jsonObject); 143 | 144 | // SEPARATION of DATA 145 | 146 | // Date & Time 147 | long dateTimeStamp = jsonObject.get("dt").getAsLong() * 1000; 148 | String date = new Date(dateTimeStamp).toString(); 149 | 150 | // Temperature 151 | double temperatureKelvin = jsonObject.getAsJsonObject("main").get("temp").getAsDouble(); 152 | int temperatureCelsius = (int) (temperatureKelvin - 273.15); 153 | 154 | // Humidity 155 | int humidity = jsonObject.getAsJsonObject("main").get("humidity").getAsInt(); 156 | 157 | // Wind Speed 158 | double windSpeed = jsonObject.getAsJsonObject("wind").get("speed").getAsDouble(); 159 | 160 | // Weather Condition 161 | JsonElement weatherCondition = jsonObject.getAsJsonArray("weather").get(0).getAsJsonObject().get("main"); 162 | 163 | // THIS DATA CANT BE PRESENTED BY HTML SO WE WILL USE JSP 164 | // Set the data as request attributes (for sending the jsp page) 165 | request.setAttribute("date", date); 166 | request.setAttribute("city", city); 167 | request.setAttribute("temperature", temperatureCelsius); 168 | request.setAttribute("weatherCondition", weatherCondition); 169 | request.setAttribute("humidity", humidity); 170 | request.setAttribute("windSpeed", windSpeed); 171 | request.setAttribute("weatherData", responseContent.toString()); 172 | 173 | connection.disconnect(); 174 | // Forward the request to the weather.jsp page for rendering 175 | request.getRequestDispatcher("index.jsp").forward(request, response); 176 | } 177 | } 178 | ``` 179 | 180 | - `index.jsp`: The JSP file for the main page, containing the HTML, CSS, and JavaScript code. 181 | 182 | _[src/main/webapp/index.jsp](src/main/webapp/index.jsp)_ 183 | 184 | ```jsp 185 | <%@ page language="java" contentType="text/html; charset=UTF-8" 186 | pageEncoding="UTF-8"%> 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | Weather App 195 | 196 | 197 | 198 | 199 | 200 | 201 |
202 |
203 | 204 | 205 |
206 |
207 |
208 | Clouds 209 |

${temperature} °C

210 | 211 |
212 | 213 |
214 |
${city}
215 |
${date}
216 |
217 |
218 |
219 | Humidity 220 |
221 | Humidity 222 |

${humidity}%

223 |
224 |
225 | 226 |
227 | 228 |
229 | Wind Speed 230 |

${windSpeed} km/h

231 |
232 |
233 |
234 |
235 |
236 | 237 | 238 | 239 | 240 | 241 | 242 | ``` 243 | 244 | - `style.css`: The CSS file containing the styles for the application. 245 | 246 | _[src/main/webapp/style.css](src/main/webapp/style.css)_ 247 | 248 | ```css 249 | @charset "ISO-8859-1"; 250 | * { 251 | margin: 0; 252 | padding: 0; 253 | box-sizing: border-box; 254 | font-family: "Ubuntu", sans-serif; 255 | } 256 | 257 | body { 258 | display: flex; 259 | height: 100vh; 260 | align-items: center; 261 | justify-content: center; 262 | background: linear-gradient(to right, #2b40ff, #07121a); 263 | } 264 | 265 | .mainContainer { 266 | width: 25rem; 267 | height: auto; 268 | border-radius: 1rem; 269 | background: #fff; 270 | box-shadow: 0 14px 28px rgba(0, 0, 0, 0.25), 0 10px 10px rgba(0, 0, 0, 0.22); 271 | } 272 | 273 | .searchInput { 274 | width: 100%; 275 | display: flex; 276 | padding: 1rem 1rem; 277 | justify-content: center; 278 | } 279 | 280 | .searchInput input { 281 | width: 100%; 282 | height: 2rem; 283 | outline: none; 284 | font-size: 1rem; 285 | color: #525050; 286 | padding: 0.2rem 0.5rem; 287 | border-radius: 1.5rem; 288 | border: 1px solid #b3b3b3; 289 | } 290 | 291 | .searchInput input:focus { 292 | border: 1px solid #9c9dde; 293 | } 294 | 295 | .searchInput button { 296 | width: 2.2rem; 297 | height: 2rem; 298 | cursor: pointer; 299 | color: #9b9b9b; 300 | border-radius: 50%; 301 | margin-left: 0.4rem; 302 | transition: all 0.3s ease; 303 | background-color: #fff; 304 | border: 1px solid #b3b3b3; 305 | } 306 | 307 | .searchInput button:hover { 308 | color: #fff; 309 | background-color: #9c9dde; 310 | border: 1px solid #9c9dde; 311 | } 312 | 313 | .weatherIcon { 314 | display: flex; 315 | padding-top: 0.5rem; 316 | padding-bottom: 0.5rem; 317 | justify-content: center; 318 | } 319 | 320 | .weatherIcon img { 321 | max-width: 100%; 322 | width: 8rem; 323 | } 324 | 325 | .weatherDetails .temp { 326 | font-size: 2rem; 327 | } 328 | .cityDetails { 329 | color: #323232; 330 | font-size: 2.5rem; 331 | text-align: center; 332 | margin-bottom: 0.5rem; 333 | } 334 | 335 | .cityDetails .date { 336 | color: #323232; 337 | font-size: 1.5rem; 338 | text-align: center; 339 | margin-bottom: 0.5rem; 340 | } 341 | 342 | .windDetails { 343 | display: flex; 344 | margin-top: 1rem; 345 | margin-bottom: 1.5rem; 346 | justify-content: space-around; 347 | } 348 | 349 | .windDetails .humidityBox { 350 | display: flex; 351 | font-size: 1rem; 352 | color: #323232; 353 | } 354 | 355 | .windDetails .humidity .humidityValue { 356 | text-align: center; 357 | font-size: 2rem; 358 | color: #323232; 359 | } 360 | 361 | .windDetails .humidityBox img { 362 | max-height: 3rem; 363 | margin-right: 0.5rem; 364 | } 365 | 366 | .windDetails .windSpeed { 367 | display: flex; 368 | font-size: 1rem; 369 | color: #323232; 370 | } 371 | 372 | .windDetails .windSpeed img { 373 | max-height: 3rem; 374 | margin-right: 0.5rem; 375 | } 376 | 377 | image-logo { 378 | height: auto; 379 | width: auto; 380 | filter: drop-shadow(20px 10px 10px black); 381 | } 382 | ``` 383 | 384 | - `myScript.js`: The JavaScript file containing the code for dynamically updating the weather icon based on the current weather conditions. 385 | 386 | _[src/main/webapp/myScript.js](src/main/webapp/myScript.js)_ 387 | 388 | ```js 389 | var weatherIcon = document.getElementById("weather-icon"); 390 | 391 | var val = document.getElementById("wc").value; 392 | switch (val) { 393 | case "Clouds": 394 | weatherIcon.src = 395 | "https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiwFTkt5z_dxU6w1UnS1PxiZV3HDiPGsAW5Lrsp09MnlCmkQre9GzO8MnGytaaY1eZoqBN6SMJ4U578_uDtiuXswovr1T3o-Kt5KK0mlN_zC0RDodJFaKHQ3Uk-HIZ3vuMvAKNJi8DDFwWA7F6BOxz78Oh-UePwJTuc3PG0ZIZypPE1xlMPl5z46joaEw/s320/Clouds.png"; 396 | break; 397 | case "Clear": 398 | weatherIcon.src = 399 | "https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj7pmzNCftryAfpa1YBSzVeYtjgxDQnw09Ug0HVV47J8GEtHPYTH9hJgZ2M1k0YgE0pcZ1qekr4C14zyPCiVuQAfXLClK8Ww3hYB6v77yElP7Lo5BnUKo4n-w6yB17FAbw51WST6YKS0GMwyA4fYNxOZxEyNL6HhUfFRgVhOW0GyRdBRriMHFQ-qfh4cA/s320/sun.png"; 400 | break; 401 | case "Rain": 402 | weatherIcon.src = 403 | "https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgDW_NdwvxV796rkFf43qmUDiTQePn5dg7PDfn1SijfpjtB0AWJMBcifU6LWyW7iOtjZhfqIJnKEGQ1PwbbXS7NoKMSAmvy7i2ljWXMYLue3EBIBBR2qTFbs6QCe5eoFr2CU9WzCVJ8u0J3z3eAo3Ajv1LXamZASFtbj9sA_gD-Kp3hfgAk17Xh17RoLQ/s320/rainy.png"; 404 | break; 405 | case "Mist": 406 | weatherIcon.src = 407 | "https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgVpL23l0t1U_ibWi01TFcHMF6J_t-9Ada5PavGlwG4M_mKIcx0pV1md9SN9ip1d84NaVowml5Do16XO3nsuttnM2-Ov05d-wCjEYjdzaOYfKvijw8k6Hfj9pOiPyEZTp2W20EPbTeONTgJE2Rdxs4KZUfg6f2PmbMF1094NcqJ7DwSFUQwYiRmVCNvuA/s320/mist.png"; 408 | break; 409 | case "Snow": 410 | weatherIcon.src = 411 | "https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj-P3iT_uQK95qFY4h7QGdEtbRc1aVQo9BZy0ZWyPBvCNrP-4wnRStw0xYj9e4xa4ZlYISeNZqVJ33UP4YukR4jBennDD_obIN4QxYNZHdzG_z6_MNL2U08wMXwdFhtfvitW5LGiHgrwMJFC8QJFqbSO3woGSBqOdagGxaEQ20_S31Gc-GYL4vYzPzaPw/s320/snow.png"; 412 | break; 413 | case "Haze": 414 | weatherIcon.src = 415 | "https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjld66Ia5g_hpBn3Impi3zzOBHqWkjQInGLxTb2uXksuCsrkQU8HjlVyLobEJEGg8fRSIxeFzldGEHUmWcaiZBwAcRy4dGDpFX1BjTSB56qmBjW5tEW3RSC9_mCuLU_a8RuXchxGY7Oc8HLLl-IfaDW19Z0ZJJfNae9tECXRIyEu7rmJ3da08z8cI-phw/s320/haze.png"; 416 | break; 417 | } 418 | ``` 419 | 420 | - `weather-logo.png`: The logo image used on the main page. 421 | 422 | ![Weather Logo](src/main/webapp/images/weather-logo.png) 423 | 424 | --- 425 | 426 | ### 6.Contributing 427 | 428 | --- 429 | 430 | Contributions are welcome! If you find any issues or have suggestions for improvement, please open an issue or submit a pull request. 431 | 432 | --- 433 | 434 | ### 7.License 435 | 436 | --- 437 | 438 | This project is licensed under the [MIT License](LICENSE). 439 | -------------------------------------------------------------------------------- /src/main/java/MyPackage/MyServlet.java: -------------------------------------------------------------------------------- 1 | package MyPackage; 2 | 3 | import jakarta.servlet.ServletException; 4 | import jakarta.servlet.annotation.WebServlet; 5 | import jakarta.servlet.http.HttpServlet; 6 | import jakarta.servlet.http.HttpServletRequest; 7 | import jakarta.servlet.http.HttpServletResponse; 8 | import java.io.IOException; 9 | import java.io.InputStream; 10 | import java.io.InputStreamReader; 11 | import java.net.HttpURLConnection; 12 | import java.net.URL; 13 | import java.util.Date; 14 | import java.util.Scanner; 15 | 16 | import com.google.gson.Gson; 17 | import com.google.gson.JsonElement; 18 | import com.google.gson.JsonObject; 19 | 20 | /** 21 | * Servlet implementation class MyServlet 22 | */ 23 | public class MyServlet extends HttpServlet { 24 | private static final long serialVersionUID = 1L; 25 | 26 | /** 27 | * @see HttpServlet#HttpServlet() 28 | */ 29 | public MyServlet() { 30 | super(); 31 | } 32 | 33 | /** 34 | * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) 35 | */ 36 | protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 37 | response.getWriter().append("Served at: ").append(request.getContextPath()); 38 | } 39 | 40 | /** 41 | * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) 42 | */ 43 | protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 44 | 45 | //API Setup 46 | String apiKey = "8071998b04156cb295e9e3c3b8336359"; 47 | // Get the City name from the form's input 48 | String city = request.getParameter("city"); 49 | // Create the URL for the OpenWeatherMap API request 50 | String apiUrl = "https://api.openweathermap.org/data/2.5/weather?q=" + city + "&appid=" + apiKey; 51 | 52 | // API Integration 53 | URL url = new URL(apiUrl); 54 | HttpURLConnection connection = (HttpURLConnection)url.openConnection(); 55 | connection.setRequestMethod("GET"); 56 | 57 | // Reading the data from the Network 58 | InputStream inputStream = connection.getInputStream(); 59 | InputStreamReader inputStreamReader = new InputStreamReader(inputStream); 60 | 61 | // Store data in String 62 | StringBuilder responseContent = new StringBuilder(); 63 | 64 | // To take input from inputStreamReader 65 | Scanner scanner = new Scanner(inputStreamReader); 66 | 67 | while(scanner.hasNext()) { 68 | responseContent.append(scanner.nextLine()); 69 | } 70 | 71 | scanner.close(); 72 | //System.out.println(responseContent); 73 | 74 | // TypeCasting the data into JSON (separate data) 75 | Gson gson = new Gson(); 76 | JsonObject jsonObject = gson.fromJson(responseContent.toString(), JsonObject.class); 77 | //System.out.println(jsonObject); 78 | 79 | // SEPARATION of DATA 80 | 81 | // Date & Time 82 | long dateTimeStamp = jsonObject.get("dt").getAsLong() * 1000; 83 | String date = new Date(dateTimeStamp).toString(); 84 | 85 | // Temperature 86 | double temperatureKelvin = jsonObject.getAsJsonObject("main").get("temp").getAsDouble(); 87 | int temperatureCelsius = (int) (temperatureKelvin - 273.15); 88 | 89 | // Humidity 90 | int humidity = jsonObject.getAsJsonObject("main").get("humidity").getAsInt(); 91 | 92 | // Wind Speed 93 | double windSpeed = jsonObject.getAsJsonObject("wind").get("speed").getAsDouble(); 94 | 95 | // Weather Condition 96 | JsonElement weatherCondition = jsonObject.getAsJsonArray("weather").get(0).getAsJsonObject().get("main"); 97 | 98 | // THIS DATA CANT BE PRESENTED BY HTML SO WE WILL USE JSP 99 | // Set the data as request attributes (for sending the jsp page) 100 | request.setAttribute("date", date); 101 | request.setAttribute("city", city); 102 | request.setAttribute("temperature", temperatureCelsius); 103 | request.setAttribute("weatherCondition", weatherCondition); 104 | request.setAttribute("humidity", humidity); 105 | request.setAttribute("windSpeed", windSpeed); 106 | request.setAttribute("weatherData", responseContent.toString()); 107 | 108 | connection.disconnect(); 109 | // Forward the request to the weather.jsp page for rendering 110 | request.getRequestDispatcher("index.jsp").forward(request, response); 111 | } 112 | 113 | } 114 | -------------------------------------------------------------------------------- /src/main/webapp/META-INF/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | Class-Path: 3 | 4 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/lib/gson-2.8.5.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lodhik9/Java-MyWeatherApp/5d3c0fa9e6afa895aaf28b377f359ec7098c8ef3/src/main/webapp/WEB-INF/lib/gson-2.8.5.jar -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | MyWeatherApp 4 | 5 | index.html 6 | index.jsp 7 | index.htm 8 | default.html 9 | default.jsp 10 | default.htm 11 | 12 | 13 | 14 | MyServlet 15 | MyServlet 16 | MyPackage.MyServlet 17 | 18 | 19 | MyServlet 20 | /MyServlet 21 | 22 | -------------------------------------------------------------------------------- /src/main/webapp/images/weather-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lodhik9/Java-MyWeatherApp/5d3c0fa9e6afa895aaf28b377f359ec7098c8ef3/src/main/webapp/images/weather-logo.png -------------------------------------------------------------------------------- /src/main/webapp/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Weather App - CodingWallahSir 8 | 9 | 10 | 11 | 12 | 13 |
14 | 15 |

Welcome to the Weather Web App

16 |

Explain & Made by @Lodhi

17 | 18 |

Technologies Used:

HTML, CSS, JS, Java, Servlet, JSP, OpenWeather API

19 |
20 | 21 | 22 |
23 |
24 | 25 | 26 | -------------------------------------------------------------------------------- /src/main/webapp/index.jsp: -------------------------------------------------------------------------------- 1 | <%@ page language="java" contentType="text/html; charset=UTF-8" 2 | pageEncoding="UTF-8"%> 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Weather App 11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 |
19 | 20 | 21 |
22 |
23 |
24 | Clouds 25 |

${temperature} °C

26 | 27 |
28 | 29 |
30 |
${city}
31 |
${date}
32 |
33 |
34 |
35 | Humidity 36 |
37 | Humidity 38 |

${humidity}%

39 |
40 |
41 | 42 |
43 | 44 |
45 | Wind Speed 46 |

${windSpeed} km/h

47 |
48 |
49 |
50 |
51 |
52 | 53 | 54 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /src/main/webapp/myScript.js: -------------------------------------------------------------------------------- 1 | var weatherIcon = document.getElementById("weather-icon"); 2 | 3 | var val = document.getElementById("wc").value; 4 | switch (val) { 5 | case 'Clouds': 6 | weatherIcon.src = "https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiwFTkt5z_dxU6w1UnS1PxiZV3HDiPGsAW5Lrsp09MnlCmkQre9GzO8MnGytaaY1eZoqBN6SMJ4U578_uDtiuXswovr1T3o-Kt5KK0mlN_zC0RDodJFaKHQ3Uk-HIZ3vuMvAKNJi8DDFwWA7F6BOxz78Oh-UePwJTuc3PG0ZIZypPE1xlMPl5z46joaEw/s320/Clouds.png"; 7 | break; 8 | case 'Clear': 9 | weatherIcon.src = "https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj7pmzNCftryAfpa1YBSzVeYtjgxDQnw09Ug0HVV47J8GEtHPYTH9hJgZ2M1k0YgE0pcZ1qekr4C14zyPCiVuQAfXLClK8Ww3hYB6v77yElP7Lo5BnUKo4n-w6yB17FAbw51WST6YKS0GMwyA4fYNxOZxEyNL6HhUfFRgVhOW0GyRdBRriMHFQ-qfh4cA/s320/sun.png"; 10 | break; 11 | case 'Rain': 12 | weatherIcon.src = "https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgDW_NdwvxV796rkFf43qmUDiTQePn5dg7PDfn1SijfpjtB0AWJMBcifU6LWyW7iOtjZhfqIJnKEGQ1PwbbXS7NoKMSAmvy7i2ljWXMYLue3EBIBBR2qTFbs6QCe5eoFr2CU9WzCVJ8u0J3z3eAo3Ajv1LXamZASFtbj9sA_gD-Kp3hfgAk17Xh17RoLQ/s320/rainy.png"; 13 | break; 14 | case 'Mist': 15 | weatherIcon.src = "https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgVpL23l0t1U_ibWi01TFcHMF6J_t-9Ada5PavGlwG4M_mKIcx0pV1md9SN9ip1d84NaVowml5Do16XO3nsuttnM2-Ov05d-wCjEYjdzaOYfKvijw8k6Hfj9pOiPyEZTp2W20EPbTeONTgJE2Rdxs4KZUfg6f2PmbMF1094NcqJ7DwSFUQwYiRmVCNvuA/s320/mist.png"; 16 | break; 17 | case 'Snow': 18 | weatherIcon.src = "https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj-P3iT_uQK95qFY4h7QGdEtbRc1aVQo9BZy0ZWyPBvCNrP-4wnRStw0xYj9e4xa4ZlYISeNZqVJ33UP4YukR4jBennDD_obIN4QxYNZHdzG_z6_MNL2U08wMXwdFhtfvitW5LGiHgrwMJFC8QJFqbSO3woGSBqOdagGxaEQ20_S31Gc-GYL4vYzPzaPw/s320/snow.png"; 19 | break; 20 | case 'Haze': 21 | weatherIcon.src = "https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjld66Ia5g_hpBn3Impi3zzOBHqWkjQInGLxTb2uXksuCsrkQU8HjlVyLobEJEGg8fRSIxeFzldGEHUmWcaiZBwAcRy4dGDpFX1BjTSB56qmBjW5tEW3RSC9_mCuLU_a8RuXchxGY7Oc8HLLl-IfaDW19Z0ZJJfNae9tECXRIyEu7rmJ3da08z8cI-phw/s320/haze.png"; 22 | break; 23 | } -------------------------------------------------------------------------------- /src/main/webapp/style.css: -------------------------------------------------------------------------------- 1 | @charset "ISO-8859-1"; 2 | * { 3 | margin: 0; 4 | padding: 0; 5 | box-sizing: border-box; 6 | font-family: "Ubuntu", sans-serif; 7 | } 8 | 9 | body { 10 | display: flex; 11 | height: 100vh; 12 | align-items: center; 13 | justify-content: center; 14 | background: linear-gradient(to right, #2b40ff,#07121a); 15 | } 16 | 17 | .mainContainer { 18 | width: 25rem; 19 | height: auto; 20 | border-radius: 1rem; 21 | background: #fff; 22 | box-shadow: 0 14px 28px rgba(0,0,0,0.25), 23 | 0 10px 10px rgba(0,0,0,0.22); 24 | } 25 | 26 | .searchInput { 27 | width: 100%; 28 | display: flex; 29 | padding: 1rem 1rem; 30 | justify-content: center; 31 | } 32 | 33 | .searchInput input { 34 | width: 100%; 35 | height: 2rem; 36 | outline: none; 37 | font-size: 1rem; 38 | color: #525050; 39 | padding: 0.2rem 0.5rem; 40 | border-radius: 1.5rem; 41 | border: 1px solid #b3b3b3; 42 | } 43 | 44 | .searchInput input:focus { 45 | border: 1px solid #9c9dde; 46 | } 47 | 48 | .searchInput button { 49 | width: 2.2rem; 50 | height: 2rem; 51 | cursor: pointer; 52 | color: #9b9b9b; 53 | border-radius: 50%; 54 | margin-left: 0.4rem; 55 | transition: all 0.3s ease; 56 | background-color: #fff; 57 | border: 1px solid #b3b3b3; 58 | } 59 | 60 | .searchInput button:hover { 61 | color: #fff; 62 | background-color: #9c9dde; 63 | border: 1px solid #9c9dde; 64 | } 65 | 66 | .weatherIcon { 67 | display: flex; 68 | padding-top: 0.5rem; 69 | padding-bottom: 0.5rem; 70 | justify-content: center; 71 | } 72 | 73 | .weatherIcon img { 74 | max-width: 100%; 75 | width: 8rem; 76 | } 77 | 78 | .weatherDetails .temp{ 79 | font-size: 2rem; 80 | } 81 | .cityDetails { 82 | color: #323232; 83 | font-size: 2.5rem; 84 | text-align: center; 85 | margin-bottom: 0.5rem; 86 | } 87 | 88 | .cityDetails .date { 89 | color: #323232; 90 | font-size: 1.5rem; 91 | text-align: center; 92 | margin-bottom: 0.5rem; 93 | } 94 | 95 | .windDetails { 96 | display: flex; 97 | margin-top: 1rem; 98 | margin-bottom: 1.5rem; 99 | justify-content: space-around; 100 | } 101 | 102 | .windDetails .humidityBox { 103 | display: flex; 104 | font-size: 1rem; 105 | color: #323232; 106 | } 107 | 108 | .windDetails .humidity .humidityValue { 109 | text-align: center; 110 | font-size: 2rem; 111 | color: #323232; 112 | } 113 | 114 | .windDetails .humidityBox img { 115 | max-height: 3rem; 116 | margin-right: 0.5rem; 117 | } 118 | 119 | .windDetails .windSpeed { 120 | display: flex; 121 | font-size: 1rem; 122 | color: #323232; 123 | } 124 | 125 | .windDetails .windSpeed img { 126 | max-height: 3rem; 127 | margin-right: 0.5rem; 128 | } 129 | 130 | 131 | image-logo{ 132 | height: auto; 133 | width: auto; 134 | filter: drop-shadow(20px 10px 10px black); 135 | } --------------------------------------------------------------------------------