How to Share Session Across Distributed SpringBoot Services with Redis and Spring Session
This article walks through the challenges of sharing HTTP session data between micro‑services in a distributed SpringBoot architecture, demonstrates a Redis‑based manual solution, introduces Spring Session for transparent session clustering, and resolves OpenFeign cookie loss with a request interceptor.
In a traditional monolithic application, checking a user's login status before order submission is trivial by reading the Session; however, in a distributed system each service runs in its own process, making the Session inaccessible across service boundaries.
Session Sharing Problem in Distributed Architecture
When the login and order functionalities are split into separate SpringBoot modules, the order module cannot read the Session stored by the login module. Additionally, load‑balancing may route subsequent requests to different instances, causing the Session to be lost and forcing users to log in again.
Demo: Login and Order Modules
@RestController
public class LoginController {
@Autowired
ServiceOrderClient serviceOrderClient;
@GetMapping("/login")
public Result login(User user, HttpSession session) {
String username = user.getUsername();
String password = user.getPassword();
Result result = new Result();
if ("admin".equals(username) && "admin".equals(password)) {
result.setCode(200);
result.setMessage("登录成功");
session.setAttribute("user", user);
} else {
result.setCode(-1);
result.setMessage("登录失败");
}
return result;
}
} @RestController
public class OrderController {
@GetMapping("/order/test")
public String order(@CookieValue("JSESSIONID") String jSessionId) {
return "success";
}
}Running the two services and calling http://localhost:8080/test fails with a MissingRequestCookieException because the JSESSIONID cookie is not present in the order service request.
Solution 1: Manual Session Sharing with Redis
One quick fix is to store the user object in Redis after a successful login and let other services read it.
@RestController
public class LoginController {
@Autowired
StringRedisTemplate redisTemplate;
@GetMapping("/login")
public Result login(User user, HttpSession session) {
Result result = new Result();
if ("admin".equals(user.getUsername()) && "admin".equals(user.getPassword())) {
result.setCode(200);
result.setMessage("登录成功");
String json = JSONObject.toJSONString(user);
redisTemplate.opsForValue().set("session", json);
} else {
result.setCode(-1);
result.setMessage("登录失败");
}
return result;
}
}Other services retrieve the user with:
String json = redisTemplate.opsForValue().get("session");
User user = JSONObject.parseObject(json, User.class);A LoginInterceptor can be registered to check the user before handling a request:
public class LoginInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
StringRedisTemplate redisTemplate = SpringBeanOperator.getBean(StringRedisTemplate.class);
String json = redisTemplate.opsForValue().get("session");
User user = JSONObject.parseObject(json, User.class);
if (user == null) {
System.out.println("用户未登录......");
return false;
} else {
System.out.println("用户已登录......");
return true;
}
}
} @Configuration
public class MyWebConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LoginInterceptor()).addPathPatterns("/**");
}
}Solution 2: Transparent Session Sharing with Spring Session
Spring Session abstracts the storage of HTTP Session data. Add the dependency:
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
</dependency>Configure the session store in application.yml:
spring:
session:
store-type: redisEnable Redis‑backed HTTP Session on the main class:
@EnableRedisHttpSession
@SpringBootApplication
public class Application { ... }The login controller now simply stores the user in the HttpSession:
@GetMapping("/login")
public Result login(User user, HttpSession session) {
Result result = new Result();
if ("admin".equals(user.getUsername()) && "admin".equals(user.getPassword())) {
result.setCode(200);
result.setMessage("登录成功");
session.setAttribute("user", user);
} else {
result.setCode(-1);
result.setMessage("登录失败");
}
return result;
}All services now share the same Session data in Redis automatically. Remember to place the User class in a common module so that each service uses the same fully‑qualified class name.
Problem: OpenFeign Drops SESSION Cookie
When the order service calls the login service via OpenFeign, the request header containing the SESSION (or JSESSIONID) cookie is not forwarded, so the remote service cannot locate the Session and returns a null user.
@FeignClient("service-order")
public interface ServiceOrderClient {
@GetMapping("/order/test")
String order();
}Fix this by adding a Feign request interceptor that copies the original Cookie header into the outgoing request:
@Configuration
public class MyFeignConfig {
@Bean
public RequestInterceptor requestInterceptor() {
return requestTemplate -> {
ServletRequestAttributes attrs = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attrs.getRequest();
String cookie = request.getHeader("Cookie");
requestTemplate.header("Cookie", cookie);
};
}
}After registering this configuration, the remote call carries the SESSION cookie, the user object is correctly retrieved, and the distributed system works as expected.
Ensure that the User class used in both modules resides in a shared library; otherwise, deserialization may fail due to mismatched class names.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Java Tech Enthusiast
Sharing computer programming language knowledge, focusing on Java fundamentals, data structures, related tools, Spring Cloud, IntelliJ IDEA... Book giveaways, red‑packet rewards and other perks await!
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
