Servlet / JSP ) 8. 상태 유지의 필요성

60jong·2022년 6월 14일
0

Servlet / JSP

목록 보기
8/17

Server 공부 흐름

[Servlet] --HTML코드 출력 문제--> JSP --스파게티 코드 문제--> JSP MVC -> Spring MVC -> SpringBoot


상태 유지의 필요성

WAS에서는 요청에 의해 실행된 Servlet 객체는 실행하며 응답한 뒤에 바로 소멸한다. 그래서 Servlet끼리 정보를 주고 받는 것이 불가능하다.
조각나있는 서버 프로그램인 Servlet들이 종료된 후에도 유지할 수 있는, 공유할 수 있는 데이터가 필요하다면 상태 유지가 필요하다. 상태 유지를 위해서 Servlet은 다음과 같은 객체를 이용한다.

  • Application 객체
  • Session 객체
  • Cookie 객체

Application 객체

Application객체, Servlet Context라고도 부르며 Servlet끼리 정보를 주고 받게 해주는 저장소로서 이용할 수 있다.

Java 코드 내에서는 ServletContext객체로서 존재하며 request.getServletContext()로 호출 가능하다.
(이전 글 참고)

  • Application Method
public String getInitParameter(String name) 파라미터 name에 대한 파라미터 값을 반환한다.
public Enumeration getInitParameterNames() 컨텍스트의 초기화 파라미터의 name값들을 String객체의 Enumeration으로 반환한다.
public void setAttribute(String name,Object object) 어플리케이션범위에 주어진 객체를 설정한다.
public Object getAttribute(String name) 명시된 name에 대한 object를 반환한다..
public void removeAttribute(String name) ServletContext부터 주어진 name에 대한 속성을 제거한다.

Session 객체

Session객체 또한 Application과 개념은 비슷하다.
(코드또한 ServletContext객체 -> HttpSession객체 교환하면 사용 가능)
다만, Application객체는 Applicaion 범주 안에서 / Session객체는 Session 범주 안에서 사용이 가능하다.

Application 범주 : 전체 Servlet 범위 전역
Session 범주 : 사용자 (현재 접속자, 프로세스) 범위

따라서 Session객체는 접속하는 브라우저가 달라지면 다른 Session이기에(다른 프로세스이기에) Context 공유가 불가능하다.

Chrome 다른 창이지만 같은 SID(Session ID)를 가지고 있음을 확인할 수 있다. 이건 MicroSoft Edge로 접속했는데 SID가 다르다.

참고할 점은

  • 처음 서버에 접속할 때에는 SID가 따로 없다.
  • 접속 후에는 서버에서 해당 요청에 대해 SID를 부여하게 되고 Respond한다.
  • 서버에 요청을 보낼 때 부여 받은 SID를 같이 보내면 서버는 SID에 해당하는 Session 저장소를 사용하게 한다.

Calc_session.java

@WebServlet("/calc")
public class Calc_session extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        HttpSession session = request.getSession();
        String _value = request.getParameter("value");
        String op = request.getParameter("op");

        int result = 0;
        int value = (_value!= null && !_value.equals(""))
                ? Integer.parseInt(_value) : 0;

        if(op.equals("=")) {
            int sum = (int) session.getAttribute("value");
            String prevOp = (String) session.getAttribute("op");

            if (prevOp.equals("+"))
                result = sum + value;
            else
                result = sum - value;

            response.getWriter().printf("Result is %d",result);
        } else {
            session.setAttribute("value", value);
            session.setAttribute("op", op);
        }
    }
}
  • Session Method
String getId() 세션의 ID 출력
void setAttributes(String name, Object value) name으로 Object객체 매핑
Object getAttribute(String name) name으로 매핑된 Object객체 반환
void invalidate 세션에서 사용되는 객체들을 바로 해제
void getMaxInactiveInterval() 세션 타임아웃을 초 단위로 출력 (defaut 30분)
void setMaxInactiveInterval(int interval) 세션 타임아웃을 interval로 설정 (defaut 30분)
boolean isNew() 세션이 새로 생성됐는지 확인
long getCreateionTime() 세션이 시작된 시간을 반환, 1970.01.01을 시작으로 하는 ms
long getLastAccessedTime() 마지막 요청 시간, 1970.01.01을 시작으로 하는 ms

Cookie 객체 또한 상태 유지를 위해 사용될 수 있는 저장소이다.
Application 객체, Session 객체와는 다르게 브라우저에 저장되며, Client에서 보내는 Request와 Client로 보내는 Respond의 Header정보에 담아서 주고 받는다.

Calc_cookie.java

@WebServlet("/calc")
public class Calc_cookie extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        Cookie[] cookies = request.getCookies();

        response.setContentType("text/html; charset=UTF-8");
        response.setCharacterEncoding("UTF-8");

        String _value = request.getParameter("value");
        String op = request.getParameter("op");

        int result = 0;
        int value = (_value!= null && !_value.equals(""))
                ? Integer.parseInt(_value) : 0;

        if(op.equals("=")) {

            int sum = 0;
            String prevOp = "";
            for(Cookie c : cookies) {
                if (c.getName().equals("value"))
                    sum = Integer.parseInt(c.getValue());
                if (c.getName().equals("op"))
                    prevOp = c.getValue();
            }

            if (prevOp.equals("+"))
                result = sum + value;
            else
                result = sum - value;

            response.getWriter().printf("Result is %d",result);

        } else {
            Cookie valueCookie = new Cookie("value", String.valueOf(value));
            Cookie opCookie = new Cookie("op", op);
            response.addCookie(valueCookie);
            response.addCookie(opCookie);
        }
    }
}


실제로 요청 헤더에 Cookie가 담겨서 전송되고, Cookie안에 입력했던 value와 op가 그대로 전송됨을 확인할 수 있다.


실제로 Chrome 브라우저에 Cookie가 저장됐고

입력했던 정보가 저장됐다.

그렇다면 Cookie객체는 Application객체와 Session객체처럼 어느 범위에서 사용이 가능할까?? 또한 수명은 어떻게 될까??

  • Cookie객체의 경로 설정
  • Cookie객체의 maxAge 설정

Cookie의 경로 설정

Chrome에 저장된 Cookie를 자세히 보면

모든 경로(/)에서 이 Cookie를 사용할 수 있게 돼있다.

Cookie의 경로를 설정해주지 않으면, 모든 Servlet에서 Cookie호출이 가능해지게 되고, 이는 Cookie에 대한 관리도 어려울 뿐더러 원하지 않았던 Cookie로 정보를 주고 받게될 수도 있다.

Cookie를 생성할 때

valueCookie.setPath("/calc");
opCookie.setPath("/calc";

경로 설정을 /calc로 해주면

Cookie 경로가 /calc로 바뀐 것을 확인할 수 있다. (이제 Calc로 매핑된 Servlet에서만 호출이 가능하다.)


Cookie의 maxAge 설정

Cookie는 현재 Session이 만료될 때 같이 삭제된다. 하지만 수명을 설정해줄 수 있다.

valueCookie.setMaxAge(60*60);
opCookie.setMaxAge(60*60);
현재 시간으로부터 1시간 (60*60초)이 수명으로 설정된 것을 확인할 수 있다.

이렇게 수명 설정이 되고나면 해당 Cookie를 File로 저장하게 된다.
C:\Users\s_rudwhd515\AppData\Local\Google\Chrome\User Data\Default\Cookies 파일로 존재한다.

  • Cookie Method
void setMaxAge(int expiry) 쿠키의 유효 시간 설정 (0으로 할 경우 무효화)
int getMaxAge() 쿠키의 유효 시간 반환 (default 세션 만료시 삭제)
void setPath(String uri) 쿠키 사용의 유효 디렉토리 설정
String getPath() 설정된 유효 디렉토리 반환
void setValue(String newValue) 쿠키의 값을 수정
String Cookie.getName() 쿠키의 이름 반환
void setVersion(int v) 쿠키의 버전 정보 설정
int getVersion() 쿠키의 버전 정보 반환
void setComment(String purpose) 쿠키에 코멘트 설정
String getComment() 쿠키의 코멘트 반환

Redirection 리다이렉션

Servlet이 종료된 뒤에는 빈 페이지만 남게 된다. Servlet 코드 마지막에 Redirection처리를 해주면,
Servlet이 종료되고 처리된 페이지로 경로를 전환(Redirection)하게 된다.

response.sendRedirect("calc.html");

Servlet코드 마지막에 추가해주면 Servlet 로직을 마치고 다시 calc.html로 페이지를 전환해주게 된다.

profile
울릉도에 별장 짓고 싶다

0개의 댓글