[JSP&Servlet] 서블릿의 상태 저장 및 유지 객체들 : ServletConetxt

Re_Go·2024년 7월 31일
0

JSP&Servlet

목록 보기
8/19
post-thumbnail

1. 상태 저장의 중요성

네트워크의 연결은 어느 한 쪽의 일방적인 행위에 의해서 발생되지 않습니다. 이를 좀 더 풀어서 설명해 보자면 클라이언트의 요청이라는 행위와, 서버의 응답이라는 행위가 일어나는 일련의 과정을 거친 상태가 네트워크가 연결된 상태라고 할 수 있는데요.

이때 네트워크의 연결은 매번 일어나는 상황이라고 가정 할 때 클라이언트의 제공 정보와 서버측의 제공 정보를 매번 새로 생성하는 것은 매우 비효율적이라고 할 수 있겠는데요. 그래서 클라이언트에서는 서버에 제공했던 정보를 쿠키(cookie) 형식으로 저장을 하게되고, 서버측은 서버 언어의 각 기술에 따라 서버의 상태 정보를 저장하는데요.

웹 페이지의 특정 요소를 클릭 시 서버측에 전달하는 정보를 클라이언트 측에서 쿠키 형태로 저장하고 재전송시 활용하게 되는데, 이때 개발자 도구의 cookies 항목을 보면 해당 정보들의 이름과 값, 데이터 타입, 용량 및 유효기간 등을 확인할 수 있습니다.

특히 서블릿에서는 쿠키 외에도 ServletContext(웹 어플리케이션의 전반적인 정보를 저장), HttpSession(사용자의 개별 세션 보관 및 관리), HttpServletRequest(사용자의 HTTP 요청 정보 저장) 이렇게 세 가지 객체로 전반적인 서버의 정보들을 저장하고 관리하게 됩니다.

각 객체 별 상태 유지 기간

(자료 출처 : https://velog.io/@yeppi/%ED%99%94%EB%A9%B4-%EC%9D%B4%EB%8F%99-%EB%B0%A9%EC%8B%9D-Redirect-VS-Forwarding-VS-Session-VS-Context)

2. ServletConetxt 개요

ServletContext 객체는 위에서 언급했다시피 웹 어플리케이션의 전반적인 정보를 담고 있는 객체인데요. 그와 동시에 서블릿 간에 통신할 수 있는 기능도 제공합니다.

(자료 출처 : https://nesoy.github.io/articles/2019-02/Servlet)

ServletConetxt 추출 방법

이러한 서블릿을 추출하는 방법은 ServletConfig 객체를 사용할 수 있는 init() 메서드에서 해당 객체를 이용한 메서드로 추출을 하거나, GenericServlet으로부터 상속 받은 서블릿 추출 메서드로 추출을 하면 됩니다.

// 서블릿 컨텍스트의 정보값을 보관하기 위한 변수
ServletContext scContent;

@Override
// 개별 서블릿의 초기화 작업 시 활용되는 servletConfig로도 getServletContext 메서드를 호출할 수 있습니다.
public void init(ServletConfig config) throws ServletException {
	scContent = config.getServletContext();
}


@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
	res.setContentType("text/html;charset=UTF-8");
	PrintWriter out = res.getWriter();
    // this는 제네릭서블릿의 메서드를 상속 받은 http서블릿을 상속 받은 현재 서블릿, 즉 현재 서블릿에서 상속 받은 getServletContext 메서드를 호출하겠다는 의미.
	scContent = this.getServletContext();
	out.print("<h3> 컨텍스트 추출값 </h3>");
	out.print("<p>" + scContent + "<p>");	
}

ServletConetxt 전역 파라미터 할당 방법

이러한 서블릿 컨텍스트에는 주로 특정 파라미터, 그러니까 모든 서블릿과 JSP들이 공유가 가능한 전역 파라미터가 저장되는데요. 이 값들은 주로 해당 어플리케이션 전역에 걸쳐 설정해야할 공통적인 값을 지정할 때라든지, 서블릿이 초기화 될 때 사용될 초기값으로서 사용된다든지 하는 경우로서 사용될 수 있습니다.

그리고 이러한 web.xml 파일에 안에서 똑같이 과 에 이름과 값을 지정한 뒤 특정 시점에서 해당 이름의 컨텍스트 값을 추출하여 사용할 수 있죠.

  1. XML 페이지
<display-name>project</display-name>
ㆍ
ㆍ
ㆍ
<!-- 컨텍스트 -->
<context-param>
  <param-name>firstContextParam</param-name>
  <param-value>hello</param-value> 
</context-param>
<context-param>
  <param-name>secondContextParam</param-name>
  <param-value>world</param-value> 
</context-param>
  1. JAVA 페이지
@Override
  protected void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {

  // 서블릿 컨텍스트 정보 획득
  ServletContext sc = this.getServletContext();
  // 특정 이름의 컨텍스트 파라미터 값을 각각 변수에 할당
  String var1 = sc.getInitParameter("firstContextParam");
  String var2 = sc.getInitParameter("secondContextParam");
  res.setContentType("text/html;charset=UTF-8");
  PrintWriter out = res.getWriter();
  // 변수들을 화면에 출력
  out.print("<h3> 첫번째 컨텍스트 변수의 값 </h3>");
  out.print("<p>" + var1 + "<p>");

  out.print("<h3> 두번째 컨텍스트 변수의 값 </h3>");
  out.print("<p>" + var2 + "<p>");
	}

물론 서블릿 컨텍스트의 전역 파라미터를 web.xml 에서만 만들 수 있는건 아니고, 서블릿 컨텍스트 인스턴스의 setAttribute 메서드를 이용해 만들 수도, getAttribute 메서드를 이용해 받을 수도 있습니다. (단 getAttribute로 해당 파라미터를 받을 시 전달한 값의 타입에 상관 없이 오브젝트로 반환 받으므로 받고자 하는 변수의 타입으로 적절하게 형변환을 해줘야 합니다.)

// setAttribute로 컨텍스트의 특정 파라미터의 이름과 값을 전달합니다.
sc.setAttribute("thirdContextParam", "this is made by Set Method!");
// getAttribute 메서드로 특정 파라미터의 이름을 전달해주고 값을 받아오는데, 이때 문자열로 받을 거니까 String으로 형변환을 해줍니다.
String var3 = (String) sc.getAttribute("thirdContextParam");

물론 값은 문자열 뿐만 아니라 여러 데이터 타입의 값도 할당 가능합니다. 단 주의할 점은 파라미터의 값은 여러 타입이 가능해도, 이름 부분은 문자열만 가능하다는 사실!

  1. Person 객체
package com.practice.test;

public class Person {
    private String name;
    private int age;

    // 기본 생성자
    public Person() {
        this.name = "Unknown";
        this.age = 0;
    }

    // 생성자
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "Name: " + name + ", Age: " + age;
    }
}
  1. Person 타입의 인스턴스를 하나 생성해 컨텍스트의 특정 전역 변수의 값으로 전달한 뒤 가져와 출력하기
ServletContext sc = this.getServletContext();
// 인스턴스 선언
Person people1 = new Person("Re_Go", 30);
// 값 전달
sc.setAttribute("myInfo", people1);
// 가지고 와서 적절하게 형변환 한 뒤 변수에 저장
Person var3 = (Person) sc.getAttribute("myInfo");
res.setContentType("text/html;charset=UTF-8");
PrintWriter out = res.getWriter();
// 출력
out.print("<h3> 주인장 인적사항 </h3>");
out.print("<p>" + var3 + "<p>");

profile
인생은 본인의 삶을 곱씹어보는 R과 타인의 삶을 배워 나아가는 L의 연속이다.

0개의 댓글