4일차 - tomcat메모리영역(request,response)/EL표현식
<오늘 내용>
◆데이터를 화면에 랜더링하기
◆EL 표현식
◆JSTL
통신을 통해서 받은 데이터 즉, 문자열을 자바 클래스 같은 곳에 담아주면 좋겠죠?
그래야 활용하기 편하다!!
예를들어,
String s = "username=ssar"&password=12345;
문자열은 자바에서 처리하기 힘들다. 그런데 통신을 통해서 들어오는건 문자열이다.
그러므로 위처럼 들어온 데이터를
String username="ssar";
String password="12345";
로 바꿔주는게 좋다
톰캣이 모든 요청들어온 정보들을 request객체 안에 담아준다. -> 자바에게 전달 -> 처리
톰캣은 response객체도 만들어준다.
다음과 같이 웹에 주소 입력한다.
그 결과 콘솔창에 다음과 같이 출력된다.
[ 톰켓 메모리 영역 ]
1.application영역 (공용)
크게 사용 안함, 신중하게 저장해야함
들어올때마다 check해야하는 정보를 저장하거나, 공격해오는 IP주소 같은 블랙리스트 정보를 저장해놓음
생명주기는? 톰켓이 '성'이라고하면, 성이 만들어질때 뜨고 성이 무너질때 사라진다.
2.session영역 (공용)
사용자가 주소 요청(브라우저로 요청)하는 순간, 사용자에 대한 key = value(HashMap)가 만들어진다.
ex) A7 = value
사용자에게 A7을 돌려준다. 이후 사용자가 요청할때마다 A7 을 계속 날린다.
근데 사용자가 모든 브라우저를 닫으면 key,value날라간다.
ex) 로그인 되어있다가 브라우저 닫았다가 열면 로그인이 풀린다. 왜?? 로그인 정보를 세션에 저장해놓았기 때문에
로그아웃을 하면??? 이 사용자의 key값에 대한 정보가 다 날라간다. => session.invalicdate()
session id를 부여해서 기억하게 한다. 그래서 stateless이지만,,,statefull처럼 된다.
그다음 사용자가 요청한다. 이 사용자에게느 B6를 돌려준다.
ID와 Password를 날린다. key는 Principal로 잡고 value는 User오브젝트에 아이디와 비번을 저장한다. 브라우저 닫거나 로그아웃 누르면?? value값이 다 날라간다. 근데 저장되어 있을때는?? 로그인한 사용자로 인식한다.
이 모든 거는 httpheader로 왔다 갔다 전달됨
3.request영역(사용자마다 따로 들고있음)
사용자가 10명이 동시접속하면 이 request가 10개가 생긴다.
내 톰켓 서버가 컴퓨터가 좋아서 한버네 100명 처리할수 있다면??? request가 100개 동시에 만들수 있는 컴퓨터 퍼포먼스가 되어야 한다. 이런 메모리 용량을 넘어가면 커버가 안된다.
1,2,3번 사용자가 동시에 요청하면? 3개 request가 생성됨
쓰레드를 만들어서 쓰레드 하나가 request를 관리한다.
1번 request를 관리하는 쓰레드, 2번 request를 관리하는 쓰레드...
cpu가 1초에 4번 그릴수 있다면?? 2개 쓰레드가 0.5초씩 나눠서 그리게 하면 된다. 위에 파랑, 아래 빨강 그리는 두개의 쓰레드. 속도가 빨라지는건 아니고 시간을 분할해서 동시에 그리게 한다. 시간을 엄청 많이 쪼개면, 동시에 그려지고 있는것처럼 느껴진다. 이 방식의 단점은?? 왔다갔다하려면??? context를 알아야한다.
context는??? 흐름을 안다.
책이 2권이 있는데 첫번째 책을 10페이지까지 읽었고 다른 책을 읽었다. 다시 돌아와서 이전에 읽은 책을 10페이지 이후부터 읽는다. 이런 흐름을 알아야한다. 이렇게 context 전환이 일어나야한다.
context전환이 많이 일어날수록 컴퓨터가 느려진다. 자바는 문맥 교환이 일어나는 서버이다.
그렇다면 100명 접속하면??? 문맥교환이 100번씩 일어난다. 그래서 서버 한개로 힘들고 서버를 늘려야한다.
예를 들어,
하루에 동시에 100명씩 들어오는 수영장이라면??? 튜브 주려면 100개에 바람을 한번에 다 불어줘야한다. 그러니 느리다고 한다. 그리고 몇명 나갈때 튜브 바람을 뺀다면? 새로운 사람이 들어올때마다 튜브 바람을 넣어줘야함.
-> 미리 바람 100개 넣어두고 사람 나갈때 바람 안빼는 방식으로 사용한다. 그래야 퍼포먼스가 좋다.
->기본 디폴트로 100개 request를 띄워놓는다.
1번 사용자가 들어온다. 이미 떠있는 request 하나를 점령한다. 그리고 쓰레드도 하나 같이 만든다. 1번 사용자가 더이상 안쓰는 상태가 된다면? 즉, 요청하고 응답이 끝나면 반환한다(request 생명주기). 그렇다고 request가 사라지는건 아니다. 이 request는 데이터를 잠깐 들고 있는거다.
그러니 내 로그인 정보를 request에 저장하지 않고 session에 저장한다..
그렇다면 잠깐 잠깐 필요한 데이터는 뭐가 있을까??
컨트롤러가 모든 요청을 받도록 spring에서 설계
데이터가 필요한 페이지가 있다. 글목록페이지!! 글쓰기 페이지는 db들고올 필요 없다.
데이터 베이스에 들려서 컨트롤러가 응답받는다.
/board 이렇게 요청하면? 컨트롤러가 게시글 목록페이지네? 그래서 db에서 목록을 받고
다시 정리해보자!
1. 최초 요청 "/board"
- 이를 컨트롤러(C)가 받는다.
2. M 데이터베이스에 요청한다.
3. request에 데이터를 저장해놓는다(setattribute로!! board정보를 저장)
4. 그리고 페이지 요청을 위해서 /board.jsp를 다시 요청한다(redirect 300번대)
request가 두번 일어난다. 그러므로 request에 저장된 데이터가 날라간다.
그래서 requestDispatcher를 사용한다. request를 유지해서 요청하는거. forward에 request를 담아간다.
즉, 새로운 request를 받고 기존 request에 덮어쓴다. request는 요청하고 응답하면 날라가니까(생명주기) 이를 막으려면? requestDispatcher를 사용한다.
request에 저장된 데이터를 유지하기 위함이다!!!!
4. Page영역(사용자마다 따로 들고있음)
생성자 만들기
HttpSession session이 IoC에 이미 등록되어있는지 확인하려면??? 다음과 같이 코드를 작성
개발자 모드 보기 (F12) - Network - ctrl+R
분면히 Redirect되어서 상태코드 300번대가 떠야하는데,, 200번이 뜨는 이유는?
requestDispatcher로 덮어씌웠기 때문에 200번대로 인식한다.
그러면 spring 에서 redirect를 해보자
최종 2개의 request가 생성된 것으로 인지
원래는 3개의 request임.
post요청할때 request하나 생성.
->redirect해서 기존request는 날라감
->/home 으로 와서 request생성. 근데 spring안에서 다시 requestDispatcher해서 새로 생성한 request가 기존 생성된 request를 덮어씌운다.
상태코드 302번이 뜬다.
http상태코드 링크:
https://developer.mozilla.org/ko/docs/Web/HTTP/Status
HTTP 상태 코드 - HTTP | MDN
HTTP 응답 상태 코드는 특정 HTTP 요청이 성공적으로 완료되었는지 알려줍니다. 응답은 5개의 그룹으로 나누어집니다: 정보를 제공하는 응답, 성공적인 응답, 리다이렉트, 클라이언트 에러, 그리고
developer.mozilla.org
302 Found이 응답 코드는 요청한 리소스의 URI가 일시적으로 변경되었음(/post요청했는데, /home으로 변경)을 의미합니다. 새롭게 변경된 URI는 나중에 만들어질 수 있습니다. 그러므로, 클라이언트는 향후의 요청도 반드시 동일한 URI로 해야합니다.
◆EL 표현식
메모리 생명주기가 작은 영역부터 해당 데이터가 있는지 찾는다!!
page -> request -> session -> application영역 순서로!
1) 생성자로 DI(Dependency Injection)하는 방법
브라우저에 출력은?
2) 메서드의 매개변수로 DI하는 방법