복습

페이지모듈화

  • preScript.jsp에 jquery넣고 script를 모두 넣어놓음

buffer

  • 응답데이터가 나가기전에 쌓이는 영역
  • 존재하지않는다면 forward나 include가 불가능한 방식이 됨

예시

  • 요청받고 응답을 바로바로 내보내면 에러를 잘 내보낼 수 없음
  • 모든 jsp의 기본 설정은 8kb 버퍼
  • forward: A에서 1,2,3을 만들고 B에서 1',2',3', B에서 응답나가면 브라우저에는 1',2',3'만 남음 (버퍼가 있을때)
  • 버퍼없으면: 1만들어지고 바로 out.println으로 내보내면 브라우저에 1,2,3 이 이미있음,

  • 버퍼 1kb, (512문자), 513문자 발생 -> autoflush없으면 overflow발생,
  • 자동방출이 한번 일어나고나면 forward못함

A방향으로 원본요청발생 (reqA생성) reqA를 없애기위해 respA를 브라우저에 body없고 302상태코드, location 있는 respA를 내보냄, 클라이언트가 다시 location에 요청을 또 발생시킴, (이때 이미 reqA는 없음), 서버사이드에서 reqA와 reqB는 완전히 별개(=stateless)

톰캣에러페이지구성방식

  • 버퍼있는거다지우고 에러페이지담는것
  • 이미 방출되어있으면 데이터를 회수할수없기때문에 에러페이지내보낼수없음
  • 버퍼를 잘못제어하면 foward, inlcude에서 문제 생길수있음



기본객체

  • 기본객체: 개발자가 선언, 생성한적 없지만 사용할 수 있도록 제공되고 있는 것
    • ex) js의 기본객체: window, location
  • jsp코드 = 지역코드 => _jspservice()안으로 들어가게됨 -> 기본객체=지역변수
  • 6,7,8 당장많이안쓰임

1. request(HttpServletRequest)

2. response(HttpServletResponse)

3. out(JspWriter)

  • 응답데이터 기록이나 버퍼 제어 및 관리에 사용
  • 정적텍스트 -> out.write로 바뀜

4. session(HttpSession)

  • 06/sessionDesc.jsp
    • DB에서의 세션?
      • 자바단에서 어플구성한후 DB써야해, 그럼 드라이버로딩먼저하고 커넥션만들고, 커넥션통해 쿼리객체 만들어야함, 쿼리실행, 돌아오는 결과집합, 거기서 데이터꺼내서 논다음에, CLOSE
        • 왜 CLOSE? : DB도 서버, 쓸수있는자원 한계점있음, 클라이언트를 제한해서 받으려고, 커넥션열리면서 생긴 연결통로 하나하나가 세션이었던것
        • 그동안 IBATIS가 해줬음
        • 오라클 express: 세션20개 허용
  • 세션맨
  • 최초의 리퀘스트가 들어왔을 떄 세션시작, 끝나는건 언제?
    • 30분의 타임아웃: 마지막요청을 발생시키고 다음요청까지의 시간의 갭

세션이란?

  • 통로: 두 피어 사이에 유일하게 개바오딘 연결 (웹에서는 애매한 개념)
  • 기간: 한 클라이언트가 하나의 브라우저를 이용해서 어플리케이션 사용 시작 이벤트를 발생시킨 후, 종료 이벤트를 발생시킬 때까지의 기간

세션의 생명주기

  • '한 클라이언트가 하나의 브라우저를 이용해서'라는 전제조건

시작 이벤트

  • 최초의 요청이 발생하면 세션 시작
  • session id : session.getId()
  • 세션 생성시간: new Date(session.getCreationTime())
  • 마지막 접속시간: new Date(session.getLastAccessedTime())
  • timeout(MaxInactive): session.getMaxInactiveInterval()
  • timeout 셋팅: session.setMaxInactiveInterval(3*60)

종료 이벤트

  1. invalidate(명확한 로그아웃)
  2. timeout 이내에 새로운 요청이 발생하지 않으면 세션 만료
  3. 브라우저 종료 (케바케: 옛날 브라우저는 종료해도 세션 안 끝남) = timeout과 같은 상황
  4. 쿠키 삭제

세션이 유지되는 구조 (session tracking)

  • 세션 유지를 위한 session id 재전송 방법 (우선순위: 쿠키)
  • session id가 쿠키의 형태로 클라이언트에 저장되어 재전송
  • 세션유지여부가 클라이언트에게 달려있음, 클라이언트가 다 지워버리면 끝

2. URL

  • 세션 파라미터 재전송 구조
  • ``세션유지
  • 단점
    • 1) 모든 url이 jsessionid를 가지고 있도록 재작성 되어야함
    • 2) cookie로 가도 불안한 마당에 request line에 session id를 넣는다? -> 누구나 하이재킹 가능
      • 암호화 해버리면 하이재킹 당하는 상황에서도 보안유지 가능
      • (복호화 가능하도록 양방향 기법 사용 => 나와 톰캣모두 알수 있도록 https)

3. SSL

  • Secure Socket Layer를 이용해 암호화된 재전송 구조

5. application(ServletContext)

  • 06/servletContextDesc.jsp
  • Servlet Context
    • 하나의 웹어플리케이션과 어플리케이션이 운영되는 컨테이너에 대한 정보를 캡슐화한 객체(singleton)
    • 서블릿이 놓여있는 어플리케이션에 관한 정보 + 어플리케이션이 있는 서버에 관한 정보
  • CAC(Context Aware Computing)
    • 영화관 안에서 알아서 진동모드로 전환
      • 지리적, 시간적, 예약된 공연 데이터 등등.. 을 계산할 수 있어야함
    • Context: 핸드폰이 놓여진 상황에 관한 모든 정보

기능

1. dynamic web module version 확인

  • application.getMajorVersion().application.getMinorVersion()
    • 서블릿2.0 vs 3.0 차이점
      • 1) 업로드 시 파트 데이터 다루는 방법 2) EL버전

2. 파일의 mime type 확인

3. logging

  • application.log("의도적으로 등록한 로그 메시지");
  • 하나에 어플리케이션 안에서 튜닝을 위한 기본데이터를 남겨야하는 경우 로그를 활용 (하지만 이제는 주로 log4j를 사용)
  • 사용자의 모든 요청을 로그로 남기려면?
    • 필터로 요청을 인터셉트 후 log4j의 jdbc appender로 db에 남기기

4. 컨텍스트 파라미터 확보

  • application.getInitParameter("contentFolder")

5. ★★ web resource 확보

  • getRealPath(), getResource(), getResourceAsStream()
String url = "/images/cat1.jpg"; // url은 virtual path
String targetUrl = "/06";

// 최종경로를 하드코딩하지 않고 얻을 수 있음 (하드코딩 할수도 없지만)
String path = application.getRealPath(url);
String targetPath = application.getRealPath(targerUrl);

// file객체 생성을 위해서 필요한 경로
// webstudy01, webapp, catlainhome 등등 다 알아야 절대경로 알 수 있음
// = 톰캣위치따라 달라짐
File file = new File(path); 
File targetFile = new File(targetPath, file.getName());

// try-catch문 없이도 IOException 뜨지 않는 이유
// _jspService()에서 try문으로 IOException 처리해줌
try(
  FileInputStream input = new FileInputStream(file);
  FileOutputStream output = new FileOutputStream(targetFile);
){
  IOUtils.copy(input, output);
}

6. page(Object) == this(현재 클래스의 인스턴스)

  • 커스텀태그에서 간혹 쓰임

7. config(ServletConfig)

  • 초기화 콜백 (init())에서 파라미터 꺼낼때 본 녀석
  • config는 jsp에서 잘안씀
    • 서블릿 개발 후, web.xml에 서블릿을 등록하고 매핑해야 서블릿을 사용할 수 있음.
    • web.xml 태그들이 객체가 되어 ServletConfig로 캡슐화가 됨
    • config가 있다는 건 jsp도 서블릿 이라는 것이지만 jsp는 서블릿처럼 매핑과 등록이 필요없음, 그래서 config는 jsp에서 잘안씀

8. exception(Throwable)

  • page 지시자의 isErrorPage="true"로 활성화시켜야 보임
    • 일반 페이지에서는 비활성화
  • 디렉티브
    • errorPage: 지금 이 jsp에서 코드를 실행하다가 에러가 발생하면 여기에 설정된 페이지로 넘기겠다
    • isErrorPage: 에러처리하는 해당 페이지에서는 true로 설정되어있음

9. pageContext(★★★★)

  • 가장 먼저 생성되는 기본객체
  • 나머지 기본객체에 대한 getter를 가짐
  • el에서 유일하게 쓸 수 있는 기본객체
    • ${pageContext.request.contextPath}
    • el 안에는 pageContext만 똑같고 나머지애들다없음 -> 어케써요? -> pC에서 호출
  • pageContext를 통해서 모든 객체 사용 가능
    • pageContext.getReqeust() == request

기능

1. Scope 제어

  • 내부의 map형태의 scope를 가지고 있음
    • request, session, servlet context도 마찬가지
  • attribute의 scope단위 지정가능
    • pageContext.setAttribute("test", "value", pageContext.REQUEST_SCOPE);
    • request.getAttribute("test"

2. 흐름제어

  • dispatch 방식 only (redirect 없음)
  • pageContext.include("/06/sessionDesc.jsp");
    • 예상위치에 잘 박힘
    • b한테 가기전에 방출해서 기존 코드 출력, b코드 출력, 기존 코드의 맨 마지막 부분출력
    • 문제점: 방출 이후 예외 발생하면 예외처리 불가능
  • request.getRequestDispatcher("/06/sessionDesc.jsp").include(request, response);
    • sessionDesc.jsp 코드 보인후, 이 페이지의 코드가 나옴

3. 에러데이터 확보

_jspService() 내의 기본객체 생성과정

  • pageContext가 제일 먼저 생성됨
  • 나머지 기본객체는 pageContext의 getter로 꺼내씀
  • ==> 나머지 기본객체필요하면 pC에서 잘 호출하면된다
  public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response)
      throws java.io.IOException, javax.servlet.ServletException {

    final javax.servlet.jsp.PageContext pageContext;
    javax.servlet.http.HttpSession session = null;
    java.lang.Throwable exception = org.apache.jasper.runtime.JspRuntimeLibrary.getThrowable(request);
    if (exception != null) {
      response.setStatus(javax.servlet.http.HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
    }
    final javax.servlet.ServletContext application;
    final javax.servlet.ServletConfig config;
    javax.servlet.jsp.JspWriter out = null;
    final java.lang.Object page = this;
    javax.servlet.jsp.JspWriter _jspx_out = null;
    javax.servlet.jsp.PageContext _jspx_page_context = null;


    try {
      response.setContentType("text/html; charset=UTF-8");
      pageContext = _jspxFactory.getPageContext(this, request, response,
      			null, true, 8192, true);
      _jspx_page_context = pageContext;
      application = pageContext.getServletContext();
      config = pageContext.getServletConfig();
      session = pageContext.getSession();
      out = pageContext.getOut();
      _jspx_out = out;
    } catch (java.lang.Throwable t) {
      if (!(t instanceof javax.servlet.jsp.SkipPageException)){
        out = _jspx_out;
        if (out != null && out.getBufferSize() != 0)
          try {
            if (response.isCommitted()) {
              out.flush();
            } else {
              out.clearBuffer();
            }
          } catch (java.io.IOException e) {}
        if (_jspx_page_context != null) _jspx_page_context.handlePageException(t);
        else throw new ServletException(t);
      }
    } finally {
      _jspxFactory.releasePageContext(_jspx_page_context);
    }
  }
}

클래스패스는 하나의 어플에서도 여러개!

  • rt.jar
  • lib.jar
  • web-inf/classes
  • work/catalina/loocalhost/..
  • 각자 자기에게 필요한 클래스패스 뒤짐

_jspService()밑의 코드는 우리 jsp에서 만들어진것

서블릿 처리과정

  • 최초요청 > 요청처리할 서블릿 있나 확인 > 객체 있나 확인 > 클래스 컴파일 확인 > 컴파일 > 싱글톤객체생성 > _jspservice 메서드불러
  • 최초요청 이후 다음 요청 > 싱글톤있나 > 있어 > _jspservice 메서드불러

pageContext, request, session, application

  • scope를 가진 4가지 기본객체
  • 자기 안에 데이터를 저장할 수 있는 영역(스코프)을 하나씩 가지고 있고, 그 저장영역의 타입은 Map
  • 기본객체가 다르다면 기본객체마다 가지고 있는 특성도 다름
  • 스코프 분리기준
    • 공유범위를 어디까지할 것이냐
    • 공유범위를 최소한으로 하도록
      • 물리적으로 결정하는 것 x = 결정에 공식이 있는것 x
    • 언제 데이터를 사라지게할것이냐

pageContext

  • pageContext는 jsp 하나당 1개씩 만들어지는 것
  • 한 페이지 내에서만 scope가 제한됨

request

  • 응답데이터 나가면서 request와 그 맵도 사라짐
  • 디스패치: a 페이지 -> b 페이지 디스패치로 전송되면 request 살아있음
    • a 와 b에서 하나의 리퀘스트 바라볼수있음 = 공유 가능
  • 리다이렉트: 응답이 송출되면서 request가 사라지기때문에 기존의 request는 없는 채로 새로운 요청이 발생함, a -> b하고싶어서 request에 data를 넣는다하더라도 a와 b가 가지고 있는 request는 완전히 별개이기때문에 데이터 공유 불가능

session

  • 세션: 하나의 클라이언트, 하나의 브라우저 라는 전제조건
  • 로그인정보유지하기위해 세션스코프 맵 활용
    • ex1) chrome으로 naver login하다가 firefox로 들어가봤자 로그인 유지 x
      • 핵심은 쿠키의 트래킹모드
      • 파폭의 쿠키저장소 =/= 크롬의 쿠키저장소 (완전히 별개, 상대방의 쿠키저장소 갈 수 없음)
      • 사람은 1명이어도 브라우저가 다르면 완전히 다른 세션이 만들어지는 것
      • 세션의 공유범위: 하나의 클라이언트, 하나의 브라우저
      • 리퀘스트 보다 넓은 범위

application = servlet context

  • application: servlet context!! 가장 넓은 공유 영역
    • ex) 네이버카페의 카페접속자목록
      • (나말고 다른 카페회원도 접근할수있는 공유할수있는부분)
      • pageContext X
      • request : 응답나가는 순간 사라지기때문에 불가능
      • session: 최소한의 데이터 공유영역이 아님, 메모리 공간 낭비, 모든 세션에 같은 정보를 담아두는것 말도안대



보강 Maven

  1. d 드라이브 b_buitl 압축풀기
  2. conf폴더-settings.xml의 55번에 아래추가
    <localRepository>D:/B_Util/6.maven/.m2/repository</localRepository>
  3. 이클립스 (window-preferences-maven-installation-add-directory- (D:\B_Util\6.maven\apache-maven-3.6.3)- 목록에서 해당 체크
  • user settings- browse-maven폴더-conf-settings.xml)
  1. show view- maven repositories
  2. maven repositories - global repositories - central - 우클릭 - rebuild index - ok - 밑에 퍼센테이지돌아감
profile
갈 길이 멀다

0개의 댓글