🚩오늘의 할일
👍오전 : 미션해결
✌️오후 : 나머지 기본객체의 영역
👌남으면 : 데이터 베이스까지
오늘의 핵심 키워드 : JS => 객체지향 언어이다!
자바는 객체지향이라는 패러다임을 지향하는 언어. 100%는 아님. ==> 자바스크립트, 파이썬도 객체지향으로 쓸수있다.
JS => 함수지향언어이다.
자바 1.8버전 => 함수지향이 많이 추가됨.
1. 함수지향이 어떻게 진행되는가
2. this라는 것을 어떻게 사용하는가
오늘 사용 파일 : implicitObject.jsp, sessionDesc.jsp, sessionTimer.js, SessionExtendServlet
applicationDesc.jsp
serverBrowser.jsp, ContextResourceBrowsingServlet
console에서 shift + enter 엔터된다.
아무것도 없는 상태에서 this는? window 자체이다. 그런데 여기서 prop를 선언해주고, 콘솔에 this를 찍어주는 함수 test를 만들어본다. test 함수를 찍으면? 여전히 this는 window이다. 함수 안에서의 this는 함수가 실행되는 곳을 감싸고 있는 것을 말한다. test는 아무도 감싸고 있지않기에 this가 window가 된다.
이번에는 this를 찍는 이름이 없는 함수를 sample객체로 만들어보았다. ( * js는 함수도 하나의 객체로 받을 수 있다.) sample을 콘솔에 찍어보면 아까와 마찬가지로 this가 window가 된다. 함수를 받는 변수의 this는 window이기 때문이다.
prop를 선언하는 함수를 Test 객체로 생성하고 obj에 Test객체를 생성한다. obj에 있는 prop를 찍어보면 아까 생성자에서 생성되었던 this.prop값이 나온다. obj에 func는FUNC를 리턴하는 함수를 받는다. 이것을 찍어보면 값이 잘 나온다. func2에는 콘솔에 this를 찍는 작업을 주었다. func2()를 찍어보면 여전히 this는 window이다. 그런데 여기에 bind를 써서 괄호에 obj를 넣으면 그 주체가 func2의 주체였던 window에서 obj의 주체인 Test 객체가 된다.
bind를 사용하면 this의 대상이 달라져버림. 괄호안에 있는 객체가 주체가 되어버린다.
생성자에서 객체를 생성한것
바인드 객체로 this를 변경한것
동적타입언어로 delete로 지운것
👍미션을 해결해보자!
sessionDesc.jsp에 타이머를 두고 작동하게한다.
- 조건1 : 한 문서에 하나의 타이머 작동하도록
- 조건2 : js와 jsp 분리하도록
- 동작 : 1분 남으면 sweetalert2 > 연장하시겠습니까? > Y > 타이머 연장되고 요청이 한번 비동기로 넘어감 > body가 필요 없으므로 method는 head로.
1. timerArea셀릭팅
2. timeout 확보
3. 초단위 timeout을 2:00 형태로 포맷팅
4. 1초 간격으로 타이머를 디스카운트 할 수 있는 스케즐링 함수
5. 1분 남은 시점이 될때까지 대기(지연)할 수 있는 스케쥴링 함수
6. 1분 남은 시점에 메시지창 디스플레이
7. 해당 메시지창에서 세션 연장을 선택할 경우, 1) 타이머는 리셋 2) 서버를 대상으로 세션을 연장하기 위한 비동기 요청(request method HEAD) 전송
8. 세션 연장을 하지 않는 경우, 메시지창 닫기
순서대로 해나가보자.
<h4>HttpSession</h4>
<h4>세션 타이머 : <span id="timerArea" data-timeout="<%=session.getMaxInactiveInterval() %>"
data-url="<%=request.getContextPath()%>/11/sessionExtend"
></span></h4>
타이머 들어갈 span태그 : timeArea
timeout = session.getMaxInactiveInterval : 세션에 있는 움직이지 않는 인터벌 얻기
js를 코딩해보자
먼저 태그를 받아와서 객체로 만들어주어야하는데 윈도우에 그대로 선언해주는 것은 윈도우 객체 또는 글로벌 변수라고 하는데 좋지 않다. 그러므로 const(상수) timeInfo에 함수를 담아서 그 안에서 선언해줘보자.
/**
*
*/
$.timeFormat = function(seconds){
let minute = Math.trunc(seconds / 60);
let second = seconds % 60;
return `${new String(minute).padStart(2,'0')}:${new String(second).padStart(2,'0')}`;
}
// 윈도우 객체 => 글로벌 변수 : 좋지않아.
const TimerInfo = function(element, speed){
this.milliAmount = speed??1000;
//이제부터 생성자함수
this.timerArea = element;
//모든 데이서 속성은 dataset으로 저장되고 이것이 map이다. 키받아옴
this.timeout = element.dataset.timeout;
this.extendURL = element.dataset.url;
this.init=function(){
if(window.timerInfo) {
this.destroy();
}
window.timerInfo = this;
this.time = this.timeout;
this.timer = setInterval(function(){
if(this.time > 0){
-- this.time;
this.timerArea.innerHTML = $.timeFormat(this.time);
}else{
this.destroy();
}
}. this.milliAmount);
if(!this.extendURL) return;
this.msgId = setTimeout(function(){
let timerObj = this; //다시 윈도우가 this임. 바인드 필요
Swal.fire({
title: '세션 연장할텨?',
showCancelButton: true,
confirmButtonText: 'YES',
}).then((result) => {
/* Read more about isConfirmed, isDenied below */
if (result.isConfirmed) {//여기서 this는 완전히 다른 객체라서 안된다.여기서 this는 window
$.ajax({
url:timerObj.extendURL,
method:"head"
});
timerObj.init();
}
})
}.bind(this), (this.timeout-60)*this.milliAmount);
} //bind(this)의 this는 TimerInfo
this.destroy = function(){
if(this.timer){
clearInterval(this.timer);
}
if(this.msgId){
clearTimeout(this.msgId);
Swal.close();
}
delete window.timerInfo;
}
this.init();
}
$("[data-timeout]").each(function(idx, element){
new TimerInfo(element, 100);
});
전체 코드는 이렇다.
먼저 time이 우리가 원하는 형식으로 나올 수 있도록 함수를 만들어보자. console에서 먼저 해보자.
let seconds = 120으로 선언해두고 우리는 정수형이 필요하므로 Math.trunc로 seconds를 60으로 나눈 것의 실수 부분을 잘라버리자. 그 결과를 min으로 받고 다시 이것을 문자열로 캐스팅해준다. 그다음 sql에서 Lpad처럼 padStart로 글자를 추가하는데 2자리 글자로 하며 남는 부분(Start니까 왼쪽)에 '0'으로 채운다. 그럼 우리가 원하는 '02'문자열이 완성된다!
이런 방식을 이용하여 js에서 함수를 완성해보면!
$.timeFormat = function(seconds){
let minute = Math.trunc(seconds / 60);
let second = seconds % 60;
return `${new String(minute).padStart(2,'0')}:${new String(second).padStart(2,'0')}`;
}
이렇게 된다.
$("[data-timeout]").each(function(idx, element){
new TimerInfo(element, 100);
});
제일 밑에서 속성으로 data-timeout을 가진 태그들을 모두 찾아서 반복문을 돌려 timerInfo를 생성한다. 그 안에는몇번째 태그인지 index와 그 태그 자체를 element로 넣어서 생성한다.
그럼 위의 전체 코드가 실행되면서 엘리먼트를 가지고 필요한 정보들을 가지고 작업 순서대로 처리한다.
speed는 테스트용으로 타이머 속도를 빠르게 해주려는 요소이다. 없어도 된다.
⛑️널변환연산자
《 speed ? speed : 1000 》 이런 삼항 연산자를 《 speed??1000 》 이렇게 단순하게 변형된 구조로 받을 수 있다.
TimerInfo 객체 안에서 init생성자를 만든다. 여기에서 if조건문으로 window에 생성된 timerInfo가 있다면 이것을 먼저 없애고 시작하도록 조건을 넣어준다. 그리고서 init함수의 this인 TimerInfo를 다시 window.TimerInfo에 넣어준다. 그리고 setInterval로 time이 아직 남아있다면 this.time;앞에 감소연산자를 넣어준다. 그리고 그 결과를 위에서 선언한 함수객체 timeFormat으로 만들어 innerHTML로 띄워준다. 만약 타임이 끝나서 0이 되었다면 destroy() 함수를 아래에 만들어서 타임 아웃도 끝나고 인터벌도 끝나는 함수를 실행시켜준다.
this.destroy = function(){
if(this.timer){
clearInterval(this.timer);
}
if(this.msgId){
clearTimeout(this.msgId);
Swal.close();
}
delete this.timerArea.timerInfo;
}
this.init();
destroy함수.
time이 마이너스이면 이상함. ==> setInterval <=> clearInterval
setInterval의 반환값 : interval id ==> timer로 받았음.
if조건문에서 this.timer가 있으면 clear해라.
Timeout도 마찬가지.
그런데 타이머를 1분 남았을때 연장할지 물어봐야하므로 Swal을 띄워줘야한다. ( alert는 이전글에서 설명했듯이 실행되는 순간 화면이 멈춰버려서 타이머가 작동되는 상황에 적절하지 못하다. )
이러면 완성인데....
또다시 요청이 들어왔다..!
클라이언트 : 이번에는 타이머 하나 더 돌려주세요!
조건 : 원래는 문서 하나에 타이머 하나 였다면 이제는 태그 하나에 타이머 하나. 그러니까 타이머 는 한 요소에 하나인 것이다.
==> window 하나에 하나만 타이머가 작동되도록 했던 조건들을 태그의 요소로 바꿔주면 완성이다.
한페이지에 하나의 타이머만 작동하게 하자
한페이지는 window. 여기서는 글로벌객체를 사용해보자.
if(window.timerInfo) return;
한페이지에 타이머 인포가 있으면 생성하는 init함수에서 탈출해라. 를
한 요소에 타이머 인포가 있으면 생성하는 init함수를 탈출해라. 로 변경
<h4 id="timerArea2" data-timeout="360"></h4>
고객의 요구를 반영할 태그를 하나 만들어주고,
1. 노란부분처럼 window를 element를 받아주던 this.timerArea로 바꿔준다.
2. 연두색 부분처럼 .bind(this)로 객체의 주체를 this로 넘겨준다.
setInterval(function(){
console.log(this);
}, 1000)
setInterval(function(){
console.log(this);
}.bind(???), 1000)
bind함수를 잘 사용하면 this를 변경할 수 잇다.
⛑️bind : 함수 하나에 대하여 주인 객체를 변경해주는 것
✌️오후 : 나머지 기본객체의 영역
application 알아보기
applicationDesc.jsp
위에 파람은 전체에서
이닛파람은 그 서블릿에서만 사용가
context는 다른말로 application
getInitParameter서버가 구동이 되면 파라미터를 받겠다.
resourceidentify.jsp : 웹리소스 (자원의 종류) 공부하기
<h4>ServletContext</h4>
<pre>
서블릿이 운영되는 컨텍스트와 서버(컨테이너)에 대한 정보를 가진 싱글턴 객체
1. context parameter 확보 : <%=application.getInitParameter("imageFolder") %>
2. context 정보 확보 : <%=application.getContextPath() %>, <%=request.getContextPath() %>
<%=request.getServletContext().getContextPath() %> <%=session.getServletContext().getContextPath() %>
3. 서버의 정보 확인 : <%=application.getServerInfo() %>
<%=application.getMajorVersion() %>.<%=application.getMinorVersion() %>
4. 로그 기록
<%
application.log(
String.format("%s - %s, %s", request.getRemoteAddr(), request.getMethod(), request.getRequestURI())
);
%>
5. 현재 컨텍스트의 웹리소스 확보에 활용(***)
<%
String imageURL = "/resources/images/cat1.jpg";
String realPath = application.getRealPath(imageURL);
File imageFile = new File(realPath);
String folderURL = "/11";
String folderPath = application.getRealPath(folderURL);
File destFile = new File(folderPath, imageFile.getName());
Files.copy(imageFile.toPath(), destFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
%>
</pre>
1. 어떻게 context parameter를 확보할까
2. 서블릿 스펙에서 사용되는 모든 대부분의 객체는 context정보를 확보할 수 있다.
==> 싱글톤이기때문에 모두 받을 수 잇다.?
3.서버 정보를 확인하는 방법
4. 로그 기록 log4J기능
.log
5.제일 중요!! 현제 헌텍스트의 웹리소스 확보에 활용!!
5번을 가지고 미션을 해보자! 0317로 이동!
2023.03.17 - [Spring] - 웹 : 0317
미션!
io...
파일을 복사해서 11번 폴더에 똑같은 이름으로 복사 해넣기
최종적으로 아래에 img 태그에 나오게 하기
새로운 웹리소스 사용해야하니까 스트림카피.........해야한다.
<%
String imageURL = "/resources/images/cat1.jpg";
String realPath = application.getRealPath(imageURL);
File imageFile = new File(realPath);
String folderURL = "/11";
String folderPath = application.getRealPath(folderURL);
File destFile = new File(folderPath, imageFile.getName());
Files.copy(imageFile.toPath(), destFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
%>
또다시 미션!
비동기로 처리해보기!
'내가 보려고 정리하는 > Spring' 카테고리의 다른 글
웹 : scope : 0317(2) (0) | 2023.03.17 |
---|---|
웹 : fancytree, adapter pattern : 0317 (0) | 2023.03.17 |
웹 : JSP 기본객체, buffer, scope 저장소 Session : 0315 (0) | 2023.03.15 |
웹 : exeption, 예외처리, custom Exception : 0314 보강 (0) | 2023.03.14 |
웹 : SOLID원칙에 맞춰 5Layered Model2 방식 만들기 : 0314 (0) | 2023.03.14 |