기타 메모
서블릿과 톰캣의 본질
자바 뿐만 아니라 다른 언어들도 웹 기능을 프로그래밍으로 동적으로 생성하는 내용들이 있다.
자바에서는 그 기능들을 정의한 것이 Servlet (인터페이스).
Servlet은 자바 파일일 뿐이고,
톰캣은 Servlet의 구현체와 여러 웹에서 사용할 자바 클래스(HttpServletRequest 등)들의 모음일 뿐이다.
세션 정리
“세션은 서버가 관리하는 단순한 맵(Map) 객체일 뿐이다”
1. 세션의 실체: 서버 메모리의 보관함
서버(Tomcat 등) 내부에는 세션을 관리하는 Manager와 개별 사용자의 Session 객체가 있다.
// [개념적 코드] 서버 내부의 모습
public class SessionManager {
// JSESSIONID를 키로, 세션 객체를 값으로 관리하는 거대한 저장소
private Map<String, HttpSession> sessions = new ConcurrentHashMap<>();
public HttpSession getSession(String id) {
return sessions.get(id); // ID(열쇠)로 객체(금고)를 찾음
}
}
public class StandardSession implements HttpSession {
private String id; // JSESSIONID
private Map<String, Object> attributes = new HashMap<>(); // 실제 데이터 저장소
public void setAttribute(String name, Object value) {
this.attributes.put(name, value); // 단순한 Map 조작
}
}
2. 세션의 생성 타이밍 (request.getSession)
세션은 “필요하다고 선언하는 순간”에만 만들어진다.
request.getSession(true)(또는 매개변수 없음): 없으면 새로 생성request.getSession(false): 없으면 null 반환. 새로 만들지 않음
3. JSP에서 왜 자동으로 생성될까?
톰캣이 JSP를 서블릿 자바 코드로 변환할 때 강제로 세션 생성 코드를 집어넣기 때문이다.
// 톰캣이 생성한 JSP 변환 서블릿 내부 (.java)
public void _jspService(HttpServletRequest request, HttpServletResponse response) {
// 별도 설정을 안 하면 아래 코드가 자동으로 삽입됨
HttpSession session = pageContext.getSession(); // 내부적으로 getSession(true) 호출
}
팁: <%@ page session="false" %>를 적으면 이 자동 생성 코드가 사라진다.
4. Spring Controller 파라미터에 따른 동작 차이
방식 A: 무조건 생성 (Eager)
@GetMapping("/test")
public String test(HttpSession session) {
// 메서드가 시작되기도 전에 스프링이 getSession(true)를 호출함.
// 방문자 모두에게 메모리(세션)를 할당함 → 비용 낭비 발생 가능
return "view";
}
방식 B: 필요할 때만 생성/조회 (Lazy) ← 권장
@GetMapping("/test")
public String test(HttpServletRequest request) {
// 아직 세션 안 만들어짐. 메모리 깨끗함.
HttpSession session = request.getSession(false); // 존재 여부만 체크
if (session == null) {
// 아직 로그인 안 한 손님. 세션 만들지 말고 그냥 구경시켜주자.
}
return "view";
}
5. 실무 권장 코드
public String profile(HttpServletRequest request, Model model) {
// 1. 세션이 없을 때 새로 만들지 않도록 false 사용
HttpSession session = request.getSession(false);
// 2. 세션이 null인 경우 = 로그인 안 했거나 세션 만료됨
if (session == null || session.getAttribute("user") == null) {
return "redirect:/login";
}
// 3. 세션이 있을 때만 로직 수행
User user = (User) session.getAttribute("user");
model.addAttribute("name", user.getName());
return "profilePage";
}
요약
- 세션은 서버 메모리에 있는 Map 객체다.
- JSESSIONID는 그 객체를 찾기 위한 쿠키 키다.
- JSP는 기본적으로 세션을 자동 생성한다.
- 컨트롤러 파라미터에
HttpSession을 쓰면 무조건 생성되니 주의하자. getSession(false)를 활용해 세션이 꼭 필요한 순간에만 메모리를 쓰도록 제어하자.
추가로 세션에 담은 데이터가 많아질 때 발생하는 성능 문제(분산 세션, Redis 세션 저장소 등)도 알아두면 좋다.