본문 바로가기
☕ Java 웹 프로그래밍/Servlet & JSP

[Servlet&JSP] Application 객체로 상태 값 저장하기

by 일단연 2023. 5. 29.

* 본 글은 [뉴렉처]의 Servlet&JSP 프로그래밍 강의를 듣고 정리한 글입니다.

 

2020 Servlet&JSP 프로그래밍

 

www.youtube.com

 

 Application 객체로 상태 값 저장하기 

Application 객체/저장소

  • 상태를 저장하거나 앞에서 다룬 결과를 잠깐 저장하기 위해 사용하는 객체

  • 클라이언트가 1번 서블릿을 요청하면, 1번 서블릿은 잠깐 올라왔다가 메모리에서 사라짐
  • 클라이언트가 2번 서블릿을 요청하면, 2번 서블릿 또한 잠깐 올라왔다가 메모리에서 사라짐
  • 이런 사이클로 돌아가니까 1번이 처리한 일을 2번이 받아서 처리할 수 없고, 1번을 재실행할 때 1번 본인이 이전에 실행했던 결과물을 받아서 쓸 수 없음
  • 서블릿을 사용할 때 서블릿들 간의, 서블릿 자신 간의 데이터를 이용할 수 있는 저장소가 필요 > 서블릿 컨텍스트(context)

 

서블릿 컨텍스트(context)

  • 서블릿들이 서로 간에 문맥을 이어나갈 수 있게 하는 저장소로 사용할 수 있는 상태 저장 공간 (서블릿들이 서로 자원을 공유)
  • A 서블릿이 만들어진 결과물을 서블릿 컨텍스트에 저장하면, B 서블릿이 그 결과를 이어서 새로운 결과물을 만들어낼 수 있음
  • 웹 애플리케이션에서는 Application 저장소 라고 함
  • 속성 처리 메소드
메소드 리턴타입 설명
setAttribute(String name, Object value) void 이름이 name인 속성의 값을 value로 지정
getAttribute(String name) Object - 이름이 name인 속성읠 값을 구함
- 지정한 이름의 속성이 존재하지 않을 경우 null을 리턴
removeAttribute(String name) void 이름이 name인 속성을 삭제
getAttributeNames( ) java.util Enumeration 속성의 이름 목록을 구함

 

서블릿 컨텍스트(context) 사용법

  • 사용자가 전달하는 입력 데이터를 저장해 다음 요청에서 그 값을 꺼내볼 수 있도록 함
  • 사용자가 전달하는 값 v를 String형 변수 v_로 받음 사용자가 전달하는 연산자 값 operator를 String형 변수 op로 받음
  • 값 v를 저장하기 위해 request의 getServletContext( )메소드를 사용하고, ServletContext형 변수에 저장
    • ServletContext application = request.getServletContext( );
    • 전체에서 사용할 테니 클래스 맨위로 위치 이동
  • 사용자가 값을 입력하지 않는 경우엔 기본값 0으로 처리
  • op가 =면 계산하고, op가 +나 - 면 값을 저장하는 조건문 작성
    • op가 =일 경우
      • x는 앞에서 저장했던(Application 저장소에 담겨있는) 값
      • getAttribute( )메소드를 이용해 Application 저장소에서 값 가져오기
        • int x = application.getAttribute("value");
      • getAttribute( )메소드의 리턴타입이 Object여서 에러 발생 > Integer로 명시적 형변환 해줘야 함
        • int x = (Integer)application.getAttribute("value");
      • y는 지금 사용자가 전달한 값 (v)
      • op가 +면 x와 y를 더하고, -면 x에서 y를 빼는 조건문을 써야 하니까 앞에서 저장했던(Application 저장소에 담겨있는) 값을 가져와야 함
        • getAttribute( )메소드를 이용해 Application 저장소에서 값 가져오기
          • String op = application.getAttribute("op");
        • getAttribute( )메소드의 리턴타입이 Object여서 에러 발생 > String으로 명시적 형변환 해줘야 함
          • String op = (String)application.getAttribute("op");\
        • if문 밖에 있는 지역변수(String op = request.getParameter("operator");)와 변수명이 같아서 에러 발생 > 변수명을 operator로 변경
          • String operator = (String)application.getAttribute("op");
    • op가 +나 -일 경우
      • 변수 application에 v 값과 op를 저장 > v와 op는 두고두고 쓸 수 있음
        • 서블릿 컨텍스트는 일종의 맵 컬렉션이라고 생각하면 됨
        • ServletContext의 setAttribute(name, object)메소드 사용
          • application.setAttribute("value", v); application.setAttribute("operator", op);
  • Calc2.java 코드
package com.newlecture.web;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/calc2")
public class Calc2 extends HttpServlet {
  @Override
  protected void service(HttpServletRequest request
                        , HttpServletResponse response)
                        throws ServletException, IOException
  {
    //서블릿 컨텍스트 변수 생성
    ServletContext application = request.getServletContext();
		
    //response의 인코딩 방식 지정
    response.setContentType("text/html; charset=UTF-8");
    response.setCharacterEncoding("UTF-8");
		
    PrintWriter out = response.getWriter();
		
    String v_ = request.getParameter("v");
    String op = request.getParameter("operator");
		
    //기본값 처리
    int v = 0;
    if(!v_.equals("")) {v = Integer.parseInt(v_);}
		
    //값을 계산
    if(op.equals("=")) {
      int x = (Integer)application.getAttribute("value");
      int y = v;
      String operator = (String)application.getAttribute("op");
			
      int result = 0;
			
      if(operator.equals("+")) {
        result = x + y;
      } else {
        result = x - y;
      }
      response.getWriter().printf("계산 결과는 %d\\n", result);
    }
    //값을 저장
    else {
      application.setAttribute("value", v);
      application.setAttribute("op", op);
		}
  }
}
  • calc2.html 코드
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>계산기 웹 프로그램</title>
</head>
<body>
  <form action="calc2" method="post">
    <div>
      <p>계산할 값을 입력하세요.</p>
    </div>
    <div>
      <label>입력 : </label>
      <input type="text" name="v"/>
    </div>
    <div>
      <input type="submit" name="operator" value="+">
      <input type="submit" name="operator" value="-">
      <input type="submit" name="operator" value="=">
		</div>
  </form>
</body>
</html>

 

calc2 애플리케이션 실행 순서

  • 사용자가 입력 박스에 첫 번째 값 x을 입력하고 +나 - 클릭
    • 서버: 서블릿 컨텍스트에 값이 저장됨
    • 브라우저: 아무것도 출력되지 않은 화면으로 이동 > 뒤로 가기
      • 이 문제는 이후에 해결할 예정

  • 사용자가 입력 박스에 두 번째 값 y을 입력하고 = 클릭
    • 서버: 이전에 저장한 값 x와 현재 입력된 값 y를 더하거나 빼서 결과 출력
    • 브라우저: x와 y를 더하거나 뺀 값이 출력됨