[Servlet] ServletContext vs HttpSession vs ServletRequest

artp·2025년 5월 14일
0

web

목록 보기
4/9
post-thumbnail

웹 애플리케이션에서는 요청이나 사용자, 애플리케이션 전체에 걸쳐 데이터를 저장하고 관리해야 하는 경우가 많습니다.

이런 데이터들은 저장되는 범위(Scope)에 따라 적절한 객체에 담아야 하며, 자바 서블릿에서는 이를 위해 세 가지 주요 객체를 제공합니다.

  • ServletRequest
  • HttpSession
  • ServletContext

Scope란?
웹 애플리케이션에서 데이터를 저장할 수 있는 범위(scope)를 의미합니다.
Scope에 따라 데이터가 저장되는 위치와 지속 시간(생명주기)가 달라집니다.

이 글에서는 각각의 객체가 어떤 범위를 가지는지, 언제 생성되고 사라지는지, 어떤 상황에서 어떤 객체를 써야 하는지 정리해보겠습니다.

1. ServletContext – 애플리케이션(Application) 범위

개념 및 역할

  • ServletContext는 웹 애플리케이션 전체에서 공유되는 전역 객체입니다.
  • 서버에 애플리케이션이 배포되거나 시작될 때 생성되어, 모든 서블릿과 JSP에서 접근할 수 있습니다.
  • 흔히 Application Scope라고 하며, 전역 설정값, 공통 객체, 리소스 경로 등을 저장하는 데 사용됩니다.

대표적으로 서비스명, DAO 객체, 공통 설정값, 초기화 파라미터 공유 등에 사용됩니다.

생성 시점 & 생명주기

생성 시점생명주기
웹 애플리케이션 배포(서버 시작)웹 애플리케이션 종료(서버 중지)까지 (서버 재시작 포함)
  • ServletContext는 웹 애플리케이션이 실행되는 동안 계속 유지됩니다.

주요 사용 목적

  • 전역 설정값(서비스명, 파일 경로 등) 저장
  • web.xml에 정의된 초기화 파라미터 공유
  • DAO, Service 객체 등 공통 객체 공유
  • 리소스 경로 얻기 → getRealPath("/") 등으로 실제 경로 반환

예제 코드

1. Servlet에서 저장

ServletContext context = getServletContext();
context.setAttribute("appName", "MyWebApp");

2. JSP에서 출력

애플리케이션 이름: ${applicationScope.appName}
  • applicationScope는 EL(Expression Language) 문법에서 ServletContext 영역을 의미합니다.

3. 예제 흐름 설명

  • 서블릿에서 getServletContext()로 전역 객체를 가져와 값을 저장합니다.
  • JSP에서는 ${applicationScope.속성명}을 통해 해당 값을 출력할 수 있습니다.

특징 및 주의사항

특징

  • 전역 저장소 역할 → 모든 서블릿과 JSP가 공유
  • 웹 애플리케이션 전반에서 재사용 가능한 객체를 저장할 때 유용
  • ServletContext에 저장된 값은 애플리케이션 종료 전까지 유지

주의사항

  • 보안 정보 저장 금지: 모든 요청에서 접근 가능하므로 민감한 정보 저장은 위험
  • 동시성 문제 주의: 다수의 요청이 동시에 접근할 수 있어 thread-safe 객체 사용 필요
    • → 예: ConcurrentHashMap, 동기화 처리 등
  • 공통 객체 초기화는 ServletContextListener를 통해 한 번만 설정하는 것이 좋음
public class AppInitListener implements ServletContextListener {
    
    // 애플리케이션이 시작될 때 실행됨
    @Override
    public void contextInitialized(ServletContextEvent sce) {
        ServletContext context = sce.getServletContext(); // 컨텍스트 객체 꺼냄
        context.setAttribute("appName", "MyWebApp");      // 전역 속성 등록
    }

    // 애플리케이션이 종료될 때 실행됨 (필요 없으면 생략 가능)
    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        // 리소스 정리 작업 등 수행 가능
    }
}

2. HttpSession – 세션(Session) 범위

개념 및 역할

  • HttpSession은 사용자(브라우저) 단위로 생성되는 객체입니다.
  • 동일 브라우저에서 여러 요청을 보내더라도, 같은 세션 ID로 사용자 상태를 유지할 수 있습니다.
  • 로그인, 장바구니 등 사용자별 상태 정보 관리에 필수적입니다.

대표적으로 로그인 상태 유지, 사용자 정보 저장, 장바구니 기능 구현 등에 사용됩니다.

생성 시점 & 생명주기

생성 시점생명주기
사용자가 최초로 request.getSession() 호출 시마지막 요청 후 기본 30분(설정 가능) 또는 session.invalidate() 호출 시까지
  • request.getSession()은 HttpServletRequest 객체에서 세션을 꺼내오는 메서드이며, 세션이 없으면 새로 생성합니다.
    • 참고로, request.getSession(false)의 false는 “세션이 없으면 새로 만들지 말고 null을 반환하라”는 의미입니다.
  • 세션은 사용자가 웹사이트에 처음 접속하거나, 세션이 만료된 후 새로 생성됩니다.
  • 기본 세션 유효시간은 30분이며, web.xml이나 코드에서 조정 가능합니다.

세션 유효시간 설정 코드 예:

// 세션 유효시간을 10분(600초)으로 설정
HttpSession session = request.getSession();
session.setMaxInactiveInterval(600); // 초 단위 (예: 10분)

주요 사용 목적

  • 로그인 상태, 사용자 정보, 장바구니 등 사용자별 데이터 저장
  • 클라이언트가 직접 접근할 수 없는 서버 측 저장소로 활용
  • 요청 간 상태 유지

예제 코드: 로그인 처리

1. 로그인 처리 서블릿 (LoginServlet.java)

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    // 1. 클라이언트에서 보낸 아이디와 비밀번호 받기
    String userId = request.getParameter("userId");
    String password = request.getParameter("password");

    // 2. 간단한 로그인 검증
    if ("hong123".equals(userId) && "pass123".equals(password)) {
        // 3. 세션 가져오기 (없으면 새로 생성됨)
        HttpSession session = request.getSession();

        // 4. 세션에 사용자 정보 저장
        session.setAttribute("userId", userId);

        // 5. 로그인 성공 후 이동
        response.sendRedirect("loginSuccess.jsp");
    } else {
        response.sendRedirect("loginFail.jsp");
    }
}

2. 로그인 성공 후 사용자 이름 출력 (loginSuccess.jsp)

<%@ page session="true" %>
<html>
<head><title>로그인 성공</title></head>
<body>
    <h2>로그인 성공!</h2>
    <p>환영합니다, <strong>${sessionScope.userId}</strong> 님!</p>
</body>
</html>
  • ${sessionScope.속성명}은 JSP의 EL(Expression Language) 문법입니다.

3. 예제 흐름 설명

  • 사용자가 로그인 정보를 입력해 제출하면, 서버에서는 doPost() 메서드에서 세션을 생성하고 사용자 정보를 저장합니다.
  • 이후 로그인 성공 페이지에서는 ${sessionScope.userId}를 통해 해당 사용자의 이름을 출력할 수 있습니다.

세션 만료 관리

  • 기본 세션 유효시간: 30분
  • 명시적 종료: session.invalidate()
  • web.xml에서 세션 타임아웃 설정 가능
<session-config>
  <session-timeout>15</session-timeout> <!-- 분 단위 -->
</session-config>

특징 및 주의사항

특징

  • 사용자별로 독립적인 저장소 (브라우저마다 세션이 따로 생성됨)
  • 요청 간 상태 유지 가능 (Stateless한 HTTP의 단점을 보완)
  • 로그인, 장바구니 등 사용자 인증/정보 유지에 필수적
  • 세션 ID는 주로 쿠키(JSESSIONID)로 클라이언트에 전달됨
  • 쿠키가 비활성화된 경우, URL Rewriting 방식으로 세션 ID 전달 가능
    • 예: /loginSuccess.jsp;jsessionid=ABC123DEF456

주의사항

  • 세션 탈취 등 보안 이슈에 주의 → 세션 고정 공격, 세션 ID 노출 등에 대비한 보안 설정 필요
  • 세션은 서버 자원을 사용하는 객체이므로, 과도한 저장은 피해야 함
  • 로그인 검증 시에는 항상 세션 유무와 유효성 확인 필요
HttpSession session = request.getSession(false);
if (session == null || session.getAttribute("userId") == null) {
    response.sendRedirect("login.jsp");
}

3. ServletRequest – 요청(Request) 범위

개념 및 역할

  • HttpServletRequest는 클라이언트(브라우저)가 서버에 요청을 보낼 때마다 생성되는 객체입니다.
  • 한 번의 요청과 응답 사이에서만 잠깐 존재하는 객체이며, 서버가 요청 처리에 필요한 모든 정보를 담고 있습니다.
  • 이 객체는 서블릿이나 JSP에서 클라이언트의 요청 데이터를 읽고, 필요한 정보를 전달하거나 가공하는 데 사용됩니다.

대표적으로 폼 입력값 처리, 페이지 간 데이터 전달, 요청 속성 설정 등에 쓰입니다.

생성 시점 & 생명주기

생성 시점생명주기
사용자가 서버에 요청할 때요청 처리 → 응답 완료 시 소멸
  • 요청이 끝나면 소멸되므로, 데이터는 요청 간에 공유되지 않습니다.
  • 따라서 유지가 필요한 정보는 세션(HttpSession) 또는 DB, 쿠키 등을 사용해야 합니다.

주요 사용 목적

  • 사용자 입력값 처리 (request.getParameter("name"))
  • 요청에 필요한 임시 데이터 저장 (request.setAttribute)
  • 서블릿 간 forward() 시 데이터 전달

예제 코드: 폼 데이터를 받아서 처리하고 결과를 전달

1. 사용자 입력 폼 (inputForm.jsp)

<form action="/submit" method="post">
    이름: <input type="text" name="username" />
    <input type="submit" value="전송" />
</form>

2. 요청을 처리하는 서블릿 (SubmintServlet.java)

protected void doPost(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
    
    // 1. 요청 파라미터에서 값 꺼내기
    String username = request.getParameter("username");

    // 2. 처리 결과를 request 범위에 저장
    request.setAttribute("result", username + "님, 접수 완료!");

    // 3. 결과를 출력할 JSP로 포워딩
    request.getRequestDispatcher("result.jsp").forward(request, response);
}

3. 결과를 출력하는 JSP (result.jsp)

<%@ page contentType="text/html; charset=UTF-8" %>
<html>
<body>
    <h2>요청 결과</h2>
    <p>${requestScope.result}</p>
</body>
</html>
  • ${requestScope.속성명}은 JSP의 EL(Expression Language) 문법입니다.

4. 예제 흐름 설명

  • 사용자가 폼을 제출하면 서블릿은 요청 파라미터를 받아 처리 결과를 request 범위에 저장합니다.
  • forward()로 전달된 JSP에서는 ${requestScope.속성명}을 통해 해당 값을 출력할 수 있습니다.

특징 및 주의사항

특징

  • 요청마다 새로 생성되는 임시 저장소 (단기 저장소)
  • forward()로 넘기면 데이터 유지 가능
  • redirect()는 새로운 요청이므로 리디렉션 시 소멸됨
  • Request Scope는 가장 짧은 생명주기를 가짐 (요청 → 응답까지 잠깐만 존재)

주의사항

  • 상태 유지 불가: 여러 요청 간 데이터를 유지하려면 HttpSession이나 DB 사용
  • 리디렉션 시 데이터 전달 불가: redirect()는 브라우저가 새 요청을 보내는 것이기 때문에, 기존 request 객체는 사라짐
  • 동일 요청 내 데이터 공유: 같은 요청 안에서 여러 서블릿 또는 JSP가 데이터를 공유해야 할 때 유용

4. 세 객체의 범위, 생명주기, 대표 메서드 비교

구분저장 범위생명주기데이터 예시대표 메서드
ServletContext웹 애플리케이션 전체서버 시작 ~ 종료공통 설정값, DAOgetServletContext()
HttpSession사용자(브라우저) 단위최초 요청 ~ 세션 만료로그인 정보, 장바구니request.getSession()
ServletRequestHTTP 요청 단위요청 시작 ~ 응답 완료폼 입력값, 임시 결과request.getParameter(),
request.setAttribute()

5. 주의사항

  • 사용자 정보는 반드시 HttpSession에 저장
    → ServletContext는 모든 사용자에게 공유되므로 보안상 위험
  • ServletRequest는 생명주기가 짧음
    → 리디렉션 시 데이터가 유지되지 않으므로, 상태 유지는 반드시 세션이나 DB 사용
  • ServletContext는 멀티스레드 환경에서 동기화 주의
    → 저장 객체가 thread-safe하도록 설계 필요(예: ConcurrentHashMap 사용)
  • HttpSession의 세션 타임아웃 및 보안 관리
    → 세션 만료 정책, 세션 고정 공격 방지 등 보안 설정 필수
  • Request Scope는 임시 데이터에만 사용
    → 장기 상태 정보는 Session/DB에 저장

6. 정리

언제 어떤 Scope를 써야 할까?

  • 공통 데이터(설정값, 리소스 등) → ServletContext
  • 사용자별 상태(로그인, 장바구니 등) → HttpSession
  • 요청 처리용 임시 데이터(폼 입력값, 처리 결과 등) → ServletRequest

요약

  • ServletContext: 애플리케이션 전역 공유, 서버 시작~종료
  • HttpSession: 사용자별 세션, 최초 요청~세션 만료
  • ServletRequest: 요청 단위, 요청~응답까지
profile
donggyun_ee

0개의 댓글