Redirect 시 사용자에게 피드백 메시지를 전달하고 싶은데, 서버 이중화 환경에서는 메시지가 유실된다면?
Spring Boot + Thymeleaf 기반의 SSR 웹 애플리케이션에서 RedirectAttributes를 사용해 리다이렉트 이후 사용자에게 알림 메시지를 출력하는 상황
예:
@PutMapping("/{postId}/isFixed")
public String updatePostIsFixed(@PathVariable Long postId, @RequestParam Boolean isFixed,
RedirectAttributes redirectAttributes) {
redirectAttributes.addFlashAttribute("message", "게시글이 고정되었습니다.");
return "redirect:/posts/" + postId;
}
이 방식은 단일 서버에서는 잘 동작하지만, 이중화된 서버 구조(Blue/Green 배포 등) 에서는 문제가 생깁니다.
리다이렉트 이후 연결된 서버가 다르면 세션이 공유되지 않아 메시지가 유실됩니다.
메시지를 쿠키에 담아 브라우저에 전달하고, 클라이언트에서 꺼내 사용하는 방식입니다.
@PutMapping("/{postId}/isFixed")
public String updatePostIsFixed(@PathVariable Long postId, @RequestParam Boolean isFixed,
HttpServletResponse response) {
String message = "게시글이 고정되었습니다.";
Cookie cookie = new Cookie("alertMessage", URLEncoder.encode(message, StandardCharsets.UTF_8));
cookie.setPath("/");
cookie.setMaxAge(10); // 메시지 노출 후 짧게 유지
response.addCookie(cookie);
return "redirect:/posts/" + postId;
}
<div id="alertBox" class="alert-box">
<span id="alertMessage"></span>
<span class="closeBtn" onclick="closeAlert()">×</span>
</div>
<script>
function getCookie(name) {
const cookies = document.cookie.split(';').map(c => c.trim());
for (let cookie of cookies) {
if (cookie.startsWith(name + '=')) {
let value = cookie.substring(name.length + 1);
value = value.replace(/\+/g, ' '); // + → 공백
return decodeURIComponent(value);
}
}
return null;
}
function deleteCookie(name) {
document.cookie = name + '=; Max-Age=0; path=/;';
}
function showAlert(message) {
const alertBox = document.getElementById('alertBox');
const alertMessage = document.getElementById('alertMessage');
alertMessage.textContent = message;
alertBox.classList.add("show");
setTimeout(() => {
alertBox.classList.remove('show');
deleteCookie('alertMessage');
}, 5000);
}
document.addEventListener("DOMContentLoaded", function () {
const message = getCookie('alertMessage');
if (message) {
showAlert(message);
}
});
</script>
이중화 서버 환경에서도 RedirectAttributes를 그대로 유지하고 싶다면, Redis 기반의 세션 공유 설정이 필요합니다.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
</dependency>
application.yml)spring:
session:
store-type: redis
data:
redis:
host: localhost
port: 6379
password: yourpassword
@Configuration
@EnableRedisHttpSession
public class SessionConfig {
}
@Configuration
@RequiredArgsConstructor
public class RedisConfig {
@Value("${spring.data.redis.host}")
private String hostname;
@Value("${spring.data.redis.password}")
private String password;
@Bean("sessionRedisConnectionFactory")
public RedisConnectionFactory sessionRedisConnectionFactory() {
RedisStandaloneConfiguration config = new RedisStandaloneConfiguration();
config.setHostName(hostname);
config.setPort(6379);
config.setPassword(password);
config.setDatabase(5); // 세션용 DB
return new LettuceConnectionFactory(config);
}
}
이렇게 하면
RedirectAttributes.addFlashAttribute()로 추가한 메시지가 Redis를 통해 서버 간 공유되며, 다른 서버로 리다이렉트 되어도 메시지가 유지됩니다.
| 상황 | 추천 방법 |
|---|---|
| 간단한 메시지, 빠른 구현 | 👉 쿠키 방식 |
| 보안, 다중 페이지 유지, 이중화 대응 | 👉 Redis 세션 방식 |
| 메시지 유지를 위해 Redis 도입 고려 가능 | 👉 세션 방식 적극 추천 |