목차 | |
1. | 새로고침 시 날씨 API null |
2. | 무한 새로고침 |
3. | href = "/" 클릭 시 null |
1. 새로고침 시 날씨 API null
처음에 출력되는 메인 페이지는 @PostMapping("/")가 아닌 @GetMapping("/")을 사용해야 함(@PostMapping("/")은 href = " " or href = "/"를 이용한 새로고침을 하면 계속 address 정보를 가져오지 못 함) 또한 다른 페이지에서 다시 메인 페이지로 돌아가기 위해서는 redirect:/를 사용해야 함!
=> PostMapping만 사용하면 새로고침을 할 때마다 날씨 API의 정보를 못 가져올 수 있기에 GetMapping 또는 비동기 방식으로 하기
▣ 문제 상황
◈ WeatherController.java
package com.project.joonggo.controller;
import com.project.joonggo.service.WeatherService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.HashMap;
import java.util.Map;
@Slf4j
@Controller
@RequiredArgsConstructor
public class WeatherController {
private final WeatherService weatherService;
@GetMapping
public String home(){
return "index";
}
@PostMapping("/")
public String showWeather(@RequestParam("address") String address, Model model){
Map<String, String> lanLon = weatherService.returnLanLon(address);
log.info("post: 1");
log.info("address: {}",address);
model.addAttribute("weather", weatherService.returnWeather(lanLon));
return "index";
}
}
▣ 문제 해결
◈ WeatherController.java
package com.project.joonggo.controller;
import com.project.joonggo.service.WeatherService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.HashMap;
import java.util.Map;
@Slf4j
@Controller
@RequiredArgsConstructor
public class WeatherController {
private final WeatherService weatherService;
@GetMapping("/")
public String showWeatherForm(@RequestParam(name = "address", required = false) String address, Model model) {
// 날씨 정보를 기본적으로 model에 넣어서 전달
// 예를 들어, 기본적인 날씨 정보나 기본값을 전달할 수 있습니다.
Map<String, String> weather = new HashMap<>();
log.info("get: address");
log.info("address: {}",address);
Map<String, String> lanLon = weatherService.returnLanLon(address);
model.addAttribute("weather", weatherService.returnWeather(lanLon));
return "index";
}
}
(참고: 비동기 방식)
<!DOCTYPE html>
<html lang="en"
xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultrap.net.nz/thymeleaf/layout"
layout:decorate="~{layout/layout}">
<div layout:fragment="content">
<div class="container-md">
<!-- 카카오맵 API 로딩 (HTTPS 사용) -->
<script type="text/javascript"
th:src="@{'https://dapi.kakao.com/v2/maps/sdk.js?appkey=0fef19877ef5e7f71e4ae9f828a6265b&libraries=services'}"></script>
<p id="status">위치를 찾지 못했습니다</p>
<div id="map" style="width:500px;height:400px;"></div>
<ul id="places"></ul>
<script th:src="@{/js/currentLocationMap.js}"></script>
<hr>
<form id="addressForm" th:action="@{/}" method="post" style="display: none;">
<input id="addressInput" name="address" type="text" />
</form>
<div id="weatherInfo" th:if="${weather != null}">
<li th:text="'날씨 : ' + ${weather['weather_main']}"></li>
<li th:text="'날씨 설명 : ' + ${weather['weather_description']}"></li>
<li th:text="'온도 : ' + ${weather['temperature']}"></li>
<li th:text="'습도 : ' + ${weather['humidity']}"></li>
</div>
<h3><a th:href="@{/chat/chatting}">chatting test</a></h3>
<button type="button" id="openChatBtn">대화방 열기</button>
<div id="chatSidebar" class="chat-sidebar">
<div class="chat-header">
<span>대화방</span>
<button id="closeChatBtn">×</button>
</div>
<div class="chat-messages">
<div class="message">
안녕하세요!<br>대화방에 오신 것을 환영합니다.
</div>
</div>
<input type="text" id="chatInput" placeholder="메시지를 입력하세요...">
<button id="sendBtn">전송</button>
</div>
<script th:src="@{/js/chatside.js}"></script>
</div>
<script>
// 위치 정보를 자동으로 가져와서 날씨 정보를 요청하는 함수
function getWeatherByLocation(latitude, longitude) {
fetch(`/weather?lat=${latitude}&lon=${longitude}`)
.then(response => response.json())
.then(data => {
const weatherInfo = document.getElementById("weatherInfo");
weatherInfo.innerHTML = `
<li>날씨 : ${data.weather_main}</li>
<li>날씨 설명 : ${data.weather_description}</li>
<li>온도 : ${data.temperature}</li>
<li>습도 : ${data.humidity}</li>
`;
})
.catch(error => console.error('날씨 정보 요청 실패:', error));
}
// 사용자의 위치를 가져오는 함수
function getUserLocation() {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(
function (position) {
const latitude = position.coords.latitude;
const longitude = position.coords.longitude;
getWeatherByLocation(latitude, longitude);
},
function (error) {
console.error('위치 정보를 가져오는 데 실패했습니다.', error);
document.getElementById('status').textContent = '위치 정보를 가져올 수 없습니다.';
}
);
} else {
document.getElementById('status').textContent = '이 브라우저는 Geolocation을 지원하지 않습니다.';
}
}
// 페이지 로드 시 자동으로 사용자 위치 기반 날씨 정보 가져오기
window.onload = function() {
getUserLocation();
};
</script>
</div>
2. 무한 새로고침
▣ 문제 상황
◈ currentLocationMap.js
sessionStorage.removeItem('addressSubmitted'); // sessionStorage 초기화
-> sessionStrorage.removeItem을 이용하면 sessionStorage를 초기화해서 날씨 API의 정보를 계속 받아옴
=> 무한 새로고침이 실행됨!
▷ 출력
▣ 문제 해결
◈ currentLocationMap.js
if (!sessionStorage.getItem('addressSubmitted')) {
// addressSubmitted가 없을 경우에만 초기화
sessionStorage.removeItem('addressSubmitted'); // sessionStorage 초기화
}
=> sessionStorage에 addressSubmitted가 없을 경우에만 초기화하는 조건을 해주면 무한 새로고침을 하지 않음!
▷ 출력
3. href = "/" 클릭 시 null
날씨 API 호출에 필요한 주소 값(address)이 서버로 제대로 전달되지 않아 weather 데이터를 가져오지 못했을 수 있음. 그렇기에 다음과 같은 방법으로 해결할 수 있음
1. Session Storage에 새로고침하기 전에 이용한 Address를 저장하여 새로고침할 때마다 불러와서 사용하기
2. null일 경우 주소의 기본값을 지정하여 날씨 출력하기
Session Storage에 userAddress의 값을 저장하여 address에 userAddress를 저장하려 했으나 Storage의 값을 js로 불러오는 과정이 2번보다 상대적으로 복잡하기도 하며, 현재 출력하려는 파트는 로그인 하기 전 화면을 출력하는 경우이기에 기본값의 위치를 띄워도 상관이 없다. 그렇기에 2번 과정으로 간단하게 해결했다.
※ 컴퓨터는 공용 자원으로 사용될 수 있기에 컴퓨터 자체의 위치와 같은 개인정보를 담고 있지는 않지만 핸드폰은 대부분 개인 자원으로 사용하기에 위치와 같은 개인정보를 가지고 있기에 앱에서 바로 활용할 수 있어서 앱을 실행할 때 로그인 하지 않아도 현재 위치를 보여줄 수 있음. 그에 반면에 컴퓨터는 현재 위치를 바로 보여주기 어려워 비로그인 상태에는 관리자가 정한 기본값을 활용함 => 컴퓨터는 핸드폰처럼 이용자의 개인 정보를 바로바로 활용하기 어렵기에 핸드폰 앱과 같은 서비스를 구현하는 것에 대해 어려움이 있음
▣ 문제 상황
◈ index.html
<form id="addressForm" th:action="@{/}" method="post" style="display: none;">
<input id="addressInput" name="address" type="text" />
</form>
◈ WeatherController.java
@GetMapping("/")
public String showWeatherForm(@RequestParam(name = "address", required = false) String address, Model model) {
// 날씨 정보를 기본적으로 model에 넣어서 전달
// 예를 들어, 기본적인 날씨 정보나 기본값을 전달할 수 있습니다.
Map<String, String> weather = new HashMap<>();
log.info("get: address");
log.info("address: {}",address);
Map<String, String> lanLon = weatherService.returnLanLon(address);
model.addAttribute("weather", weatherService.returnWeather(lanLon));
return "index";
}
-> href="/"를 클릭시 날씨 API 호출에 필요한 주소 값(address)이 서버로 제대로 전달되지 않아 weather 데이터를 가져오지 못했을 수 있음
=> 날씨 API의 정보가 null로 표시됨!
▷ 출력
▣ 문제 해결
◈ index.html
<form id="addressForm" th:action="@{/}" method="get" style="display: none;">
<input id="addressInput" name="address" type="text" />
</form>
◈ WeatherController.java
@GetMapping("/")
public String showWeatherForm(@RequestParam(name = "address", required = false) String address, Model model) {
// 날씨 정보를 기본적으로 model에 넣어서 전달
// 예를 들어, 기본적인 날씨 정보나 기본값을 전달할 수 있습니다.
Map<String, String> weather = new HashMap<>();
log.info("get: address");
log.info("address: {}",address);
if(address == null){
address="인천 남동구 구월동";
}
log.info("address: {}",address);
Map<String, String> lanLon = weatherService.returnLanLon(address);
model.addAttribute("weather", weatherService.returnWeather(lanLon));
return "index";
}
=> href="/" 클릭 시 날씨 API의 정보가 null로 표시되지 않고 기본값의 날씨 정보가 출력됨!
▷ 출력
'Project > AWS-Final' 카테고리의 다른 글
최종 프로젝트(9) - AWS 풀스택 과정 98일차 (0) | 2024.12.17 |
---|---|
최종 프로젝트(8) - AWS 풀스택 과정 97일차 (0) | 2024.12.16 |
최종 프로젝트(6) - AWS 풀스택 과정 95일차 (0) | 2024.12.12 |
최종 프로젝트(5) - AWS 풀스택 과정 94일차 (0) | 2024.12.11 |
최종 프로젝트(4) - AWS 풀스택 과정 93일차 (0) | 2024.12.10 |