복습
페이지모듈화
- 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)
종료 이벤트
- invalidate(명확한 로그아웃)
- timeout 이내에 새로운 요청이 발생하지 않으면 세션 만료
- 브라우저 종료 (케바케: 옛날 브라우저는 종료해도 세션 안 끝남) = timeout과 같은 상황
- 쿠키 삭제
세션이 유지되는 구조 (session tracking)
- 세션 유지를 위한 session id 재전송 방법 (우선순위: 쿠키)
1. cookie
- 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";
String targetUrl = "/06";
String path = application.getRealPath(url);
String targetPath = application.getRealPath(targerUrl);
File file = new File(path);
File targetFile = new File(targetPath, file.getName());
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
- d 드라이브 b_buitl 압축풀기
- conf폴더-settings.xml의 55번에 아래추가
<localRepository>D:/B_Util/6.maven/.m2/repository</localRepository>
- 이클립스 (window-preferences-maven-installation-add-directory- (D:\B_Util\6.maven\apache-maven-3.6.3)- 목록에서 해당 체크
- user settings- browse-maven폴더-conf-settings.xml)
- show view- maven repositories
- maven repositories - global repositories - central - 우클릭 - rebuild index - ok - 밑에 퍼센테이지돌아감