2022년 11월 7일 월요일

깃허브 5강(협업)

 1. 여러 컴퓨터에서 원격 저장소 함께 사용하기

(1) git clone 원격 저장소 주소 : 현재 폴더에 소스 코드를 다운 받아서 동기화

(2) git remote -v : 원격 저장소와 연결 확인

(3) git push : 자신의 컴에서 작업한 것을 원격 저장소에 올리기

(4) git pull : 원격 저장소의 최신 커밋 가져오기


2. 원격 브랜치 정보 가져오기

(1) git fetch : 원격 저장소의 정보를 가져오기

(2) git status : 현재 내 컴퓨터와 원격 저장소의 커밋 상태를 확인

(3) git checkout FETCH_HEAD : fetch 에서 가져온 최신 커밋을 확인


3. 여러 명이 협업 하기

(1) 깃허브 저장소 -> Settings -> Collaborators -> Add people -> 협업자 이메일  -> 등록

(2) git init : 등록자 컴퓨터 폴더 초기화

(3) git config user.name "협업자 이름" : 협업자 이름 등록

(4) git config user.email "협업자 메일 주소" : 협업자 이메일 등록

(5) git clone 원격 저장소 주소 : 현재 프로젝트 최신 커밋 다운받기

(6) git push -u origin master : 협업자가 작업한 내용 처음 원격 저장소에 넣기

(7) git push : (6) 이후에는 이 명령어로 넣음


깃허브 4강(백업)

1. 깃 허브란? 

3강까지는 자신의 컴퓨터에 버전 관리를 했다면 깃 허브는 외부 서버에 백업하는 것이다.

먼저 깃 허브에 가입하고, 주소를 획득하여 올리는 것이 시작이다.


2. 내 컴에 있는 깃을 깃허브에 연결하는 법

(1) 깃으로 관리 하고 있는 폴더로 이동

(2) git remote add origin 깃허브에서 복사한 주소

(3) git remote -v : 깃허브에 제대로 연결되었는지 확인


3. 깃 허브에 올리기, 내려받기

(1) git push -u origin master : 컴 저장소의 브랜치를 원격 저장소의 master에 연결하기 위한 것으로 한번만 사용

(2) git push : (1) 이후에는 이 명령어로 원격 저장소에 올림.

(3) git pull origin master : 원격 저장소의 최신 버전을 가져옴


4. 깃 허브에 SSH 원격 접속하는 법

(1) 홈 디렉토리에서 ssh-keygen : 홈디렉토리/ .ssh에 공개키, 비공개키 생성 명령어

(2) cat id_rsa.pub : 공개키 미리 보기로 공개키 문자열 복사

(3) 깃허브 로그인 -> 사용자 -> settings ->  SSH and GPG keys -> New SSH key 클릭 후 이름 + 공개키 문자열 붙이기 -> 저장

(4) 깃허브 -> Code -> SSH 주소 복사

(5) git remote add origin SSH 주소 붙이기

2022년 11월 6일 일요일

깃허브 3강(깃, 브랜치)

 1. 브랜치란? 

개발을 하다 보면 따로 분리 되어 개발을 진행해야 하는 경우가 생기는데 

그때 메인 개발과 별도로 서브 개발은 따로 분리 하였다가 

완성 후 병합하는 것을 의미 한다.


2. 브랜치, 병합 관련 명령어

git branch : 현재 브랜치를 확인

git branch 브랜치명 : 브랜치를 새로 생성

git checkout 브랜치명 : 해당 브린치로 이동

git log : 커밋 확인 

--oneline : 커밋 간단 확인

--branches : 각 브랜치의 커밋 확인

--graph : 브랜치와 커밋의 관계를 간단한 그래픽으로 표시


git reset 브랜치 해시값 : 현재 커밋을 다른 브랜치에 있는 해시값의 위치로 되돌림

git checkout master : 마스터로 이동

git merge 병합할 브랜치 명 : 마스터와 브랜치를 병합(마스터로 이동 후 사용해야 함)

git branch -d 삭제할 브랜치명 : 병합이 끝난 브랜치를 삭제(-D는 병합 전 강제 삭제)

git stash : 작업 트리의 수정 내용을 따로 보관해서 감춤

git stash pop : 따로 보관 했던 수정 내용을 꺼냄





2022년 11월 5일 토요일

깃허브 1~2강(명령어)

1. git으로 할 수 있는 것?

버전 관리, 백업, 협업


2. 깃 프로그램 종류

깃허브 데스크톱(깃허브에서 제공하는 GUI) : https://desktop.github.com/

토터스 깃(윈도우 전용) : https://tortoisegit.org/

깃(윈도우, 맥, 리눅스) : https://git-scm.com/


3. 깃 환경 설정

git config --global user.name "사용자이름(영문)"

git config --global user.email "깃허브 가입 이메일"


4. 자주 쓰는 리눅스 명령어

pwd : 현재 위치의 경로

ls : 디렉터리와 파일 표시

-ls 옵션 -

-a : 숨긴 파일과 디렉터리도 함께 표시

-l : 파일이나 디렉터리 상세 정보를 함께 표시

-r : 파일의 정렬 순서를 거꾸로 표시

-t : 파일 작성 시간 순으로 내림차순 표시

cd : 디렉터리 이동

cd .. : 상위 디렉터리로 이동

cd ~ : 홈 디렉터리로 이동

mkdir  : 디렉터리 생성

rm : 디렉터리 삭제 (-r 옵션 시 하위 디렉터리와 파일까지 함께 삭제)


5. 자주 쓰는 깃 명령어

git init : 현재 디렉토리에 후 깃 저장소 생성

git status : 깃 상태 확인

git add 파일명 : 수정한 파일 스테이징 (git add . : 전체 파일 스테이징)

git commit : 커밋

-m : 커밋 + 변경사항 메세지 기록

--amend : 커밋 메세지 수정 


git log : 저장소에 저장된 커밋 기록 확인(--stat 옵션시 : 커밋 관련 파일까지 출력)

git diff :  작업 트리에 있는 파일과 스테이지에 있는 파일 비교

git checkout --파일명 : 작업 트리에서 수정한 파일 되돌리기

git reset HEAD 파일이름 : 스테이징 되돌리기

--soft HEAD^ : 최근 커밋 전 상태로 작업 트리 되돌린다.

--mixed HEAD^ : 최근 커밋 + 스테이징 전 상태로 되돌리기(기본)

--hard HEAD^ : 최근 커밋 + 스테이징 + 파일 수정 전 상태로 되돌리기

--hard 해시 값 : 특정 커밋으로 돌아가고 그 이후 버전 삭제


git revert 해시 값 : 커밋은 되돌리되 해시값 이후의 커밋 삭제는 안함.








2022년 11월 4일 금요일

자바스크립트 10강(브라우저 객체 모델)

 1. 브라우저 객체 모델이란? 

브라우저 전체를 객체로 관리하는 것. 최상위 객체는 window 객체다.


2. 자주 사용하는 브라우저 내장 객체

window : 브라우저 창이 열릴 때마다 하나씩 만들어지는 객체. 브라우저 창 안에 존재하는 모든 요소의 최상위 객체

Document : 웹 문서에서 <body> 태그가 만나면 만들어지는 객체. HTML 문서 정보를 가지고 있다.

History : 현재 창에서 사용자의 방문 기록을 저장하고 있는 객체

Location : 현재 페이지에 대한 URL 정보를 가지고 있는 객체

Navigator : 현재 사용 중인 웹 브라우저 정보를 가지고 있는 객체

Screen : 현재 사용 중인 화면 정보를 다루는 객체


3. Window 객체에서 자주 사용하는 함수

alert() - 알림 창을 표시한다.

blur() - 창에 포커스를 제거 한다.

close() - 현재 열려 있는 창을 닫는다.

confirm() - 확인, 취소가 있는 확인 창을 표시한다.

focus() - 현재 창에 포커스를 부여한다.

moveBy() - 현재 창을 지정한 크기 만큼 이동한다.

moveTo() - 현재 창을 지정한 좌표로 이동한다.

open() - 새로운 창을 연다.

postMessage() - 다른 창으로 메세지를 전달한다.

print() - 현재 문서를 인쇄 한다.

prompt() - 프롬프트 창에 입력한 텍스트를 반환한다.

resizeBy() - 지정한 크기만큼 현재 창 크기를 조절한다.

resizeTo() - 동적으로 브라우저 창의 크기를 조절한다.

scroll() - 문서에서 특정 위치로 스크롤 한다.

scrollBy() - 지정한 크기만큼씩 스크롤 한다.

scrollTo() - 지정한 위치까지 스크롤 한다.

showModalDialog() - 모달 창을 표시 한다.

sizeToContent() - 내용에 맞게 창 크기를 맞춘다.

stop() - 로딩을 중지한다.


4. Navigator 객체 속성

appCodeName - 브라우저 이름을 문자열로 반환한다.

appName - 브라우저 공식 이름을 문자열로 반환한다.

appVersion - 브라우저 버전을 문자열로 반환한다.

battery - 배터리 충전 상태를 알려주는 정보가 담긴 객체를 반환한다.

connection - 브라우저 장치의 네트워크 정보가 담긴 객체를 반환한다.

cookieEnabled - 쿠기 정보를 무시한다면 false, 그렇지 않으면 true를 반환한다.

geoloction - 모바일 기기를 사용한 위치 정보가 담긴 객체를 반환한다.

maxTouchPoints - 장치에서 동시에 터치 가능한 포인트가 몇 개인지 반환한다.

platform - 브라우저 플랫폼 정보를 가지고 있는 문자열을 반환한다.

userAgent - 현재 브라우저 정보가 있는 사용자 에이전트 문자열을 반환 한다.


5. History 객체 속성과 함수

length - 현재 브라우저 창의 History 목록에 있는 항목의 개수를 반환한다.

back() - 이전 페이지를 현재 화면에 불러온다.

forward() - 다음 페이지를 현재 화면에 불러온다.

go() - 현재 페이지를 기준으로 상대 위치에 있는 페이지를 현재 화면에 불러온다. 

        go(1)은 다음 페이지를 가져오고, go(-1)은 이전 페이지를 가져온다.


6. Location 객체 속성과 함수

hash - URL 중 #으로 시작하는 해시 부분을 나타낸다.

host - URL의 호스트 이름과 포트 번호를 나타낸다.

hostname - URL의 호스트 이름을 나타낸다.

href - 전체 URL을 표시한다.

pathname - URL 경로를 나타낸다.

port - URL의 포트 번호를 나타낸다.

protocol - URL의 프로토콜을 나타낸다.

password - password 정보를 저장한다.

search - URL 중 ?로 시작하는 검색 내용 부분을 나타낸다.

username - username 정보를 저장한다.

assign() - 현재 문서에 새 문서 주소를 할당해 새 문서를 가져온다.

reload() - 현재 문서를 다시 불러온다.

replace() - 현재 문서의 URL을 지우고 다른 URL의 문서로 교체 한다.

toString() - 현재 문서의 URL을 문자열로 반환한다.

자바스크립트 9강(폼과 자바스크립트)

 1. 폼 요소에 접근하는 여러가지 방법

- id 값은 폼 요소 1개에 접근하여 사용

<input type="text" class="input-box" id="billingName" name="billingName">

document.querySelector("#billingName").value;

- class 값은 여러 요소를 한번에 가져와 배열 형태로 저장하고 사용

<input type="text" class="input-box" id="billingName" name="billingName">

document.querySelectorAll(".input-box").value;


2. 폼 검증 하기

<input> 태그 유형으로 폼 검증

<input type="email"> : 이메일 주소 필드, 이메일 주소 형식에 맞지 않으면 오류 메세지 표시

<input type="tel"> : 전화번호 필드, 숫자가 아닌 값이 입력되면 오류 메세지 표시

<input type="url"> : 사이트 주소 필드, http: 로 시작하지 않으면 오류 메세지 표시


3. <input> 태그의 속성

autocomplete : 자동 완성 기능을 켜고 끄는 속성

autofocus : 해당 필드에 마우스 커서를 자동으로 표시

placeholder :  필드 안에 힌트가 표시되고 사용자에게 어떤 내용을 입력해야 하는지 알려줌.

required : 필수 입력 항목으로 지정. 필드가 작성되지 않으면 오류 메시지 표시

2022년 11월 3일 목요일

자바스크립트 8강(DOM)

 1. 문서 객체 모델(DOM)이란?

웹 문서의 모든 요소를 자바스크립트를 이용하여 조작할 수 있도록 객체를 사용해 문서를 해석하는 방법.


2. DOM 트리

DOM을 조작하기 위해서는 웹문서 요소의 구조를 알아야 한다. 

DOM의 구조는 부모 요소, 자식 요소로 되어 있다. 

예)

<body>

    <h1>제목</h1>

    <p>본문</p>

</body>

위의 소스 코드는 아래와 같은 연결 관계가 있다.

            <body>   //부모 요소

<h1>                        <p> //자식 요소

-웹 문서의 태그는 요소 노드로 표현한다.

-태그가 품고 있는 텍스트는 해동 요소 노드(태그)의 자식 노드인 텍스트(Text) 노드로 표현

-태그의 속성은 모두 해당 요소 노드(태그)의 자식 노드인 속성(Attribute) 노드로 표현

-주석은 주석 노드로 표현


3. DOM 요소에 접근하기

<body>
<div id="container">
    <h1 id="heading">에디오피아 게뎁</h1>
    <div id="prod-img">
        <img src="images/coffee-pink.jpg" alt="에디오피아 게뎁">
    </div>
    <div id="desc">
        <h2 class="bright">Information</h2>
        <p>2차 세계대전 이후 설립된
            <span class="accent">게뎁농장</span>은  
            <span class="accent">SCAA 인증</span>을 받은 커피
        </p>
        <h2>Flavor Note</h2>
        <p class="bright">은은하고 다채로운 꽃향, 망고, 다크 체리, 달달함이 입안 가득.</p>
    </div>
</div>
</body>

위와 같은 구조가 있다면~

(1) id 선택자로 접근하는 함수 : getElemenById()

document.getElementById("heading"); //결과 : <h1 id="heading">에티오피아 게뎁</h1>

이렇게 접근하고, 이벤트를 연결해 해당 요소에 함수를 적용할 수 있다.

//해당 요소를 클릭하면 폰트 사이즈가 변한다.

document.getElementById("heading").onclick = function() {

    this.style.fontSize = "5em"; 

}

(2) class 값으로 접근하는 함수 : getElementsByClassName()

class 선택자는 id와 다르게 2개 이상의 웹 요소에 접근이 가능하다. 배열과 비슷하다.

document.getElementsByClassName("accent"); //결과 [span.accent, span.accent]

1개만 접근하고 싶으면 배열의 인덱스처럼 해야 한다.

document.getElementsByClassName("accent")[0]; //결과 : <span class="accent">게뎁농장</span>

document.getElementByClassName("accent")[0].style.textDecoration="underline"//결과:게뎁농장에 밑줄 생김

(3) 태그 이름으로 찾아내는 함수 : getElementsByTagName()

id, class가 없는 DOM 요소에 접근 할 때 태그 이름으로 접근한다. 태그 이름은 중복이 많기에 배열로 저장하고 접근할 수 있다.

document.getElementsByTagName("h2"); //결과 [h2, h2] 

//h2 요소 중 첫번째 요소의 배경색을 바꾼다.

document.getElementsByTagName("h2")[0].style.backgroundColor='#eee';

(4) id, class, 태그이름 다 사용할 수 있는 querySelector(), querySelectorAll() 함수

document.querySelector(".클래스명"); //클래스로 접근할 때는 마침표(.)을 앞에 붙인다.

document.querySelector("#id"); //id로 접근할 때는 샵(#)을 앞에 붙인다.

document.querySelector("태그이름"); //태그 이름으로 접근할 때는 이름만 쓴다.

document.querySelectorAll(); //배열 형식으로 접근할 때 사용


4. DOM에서 이벤트 처리 하기

var pic=document.querySelector('#pic');

pic.onclick= changPic; //pic 요소를 누르면 changPic()함수 실행

function changPic() {

    pic.src="images/boy.png";

}

addEventListener() 함수로 여러 이벤트 한번에 처리하기

var pic = document.querySelector('#pic'); 

pic.addEventListener("mouseover", changePic, false); //마우스 올리면 남자 그림으로 변경

pic.addEventListener("mouseout", originPic, false);  //마우스 벗어나면 여자 그림으로 변경

function changePic() {

  pic.src = "images/boy.png";

}

function originPic() {

  pic.src = "images/girl.png";

}


5. DOM에 요소 추가하기

(1) createElement() : 새 요소 노드를 만든다.

(2) createTextNode() : 텍스트 내용이 있을 경우 텍스트 노드를 만든다.

(3) appendChild() : 텍스트 노드를 요소 노드에 자식 노드로 추가

(4) createAttribute() : 요소에 속성이 있을 경우 속성 노드를 만든다.

(5) setAttributeNode() : 속성 노드를 요소 노드에 연결한다.

(6) appendChild() : 새로 만든 요소 노드를 부모 노드에 추가 한다.

(예제)

function newRegister() {            
  var newP = document.createElement("p");  // 새 p 요소 만들기
  var userName = document.querySelector("#userName");        
  var newText = document.createTextNode(userName.value);  // 새 텍스트 노드 만들기
  newP.appendChild(newText);  // 텍스트 노드를 p 요소의 자식 요소로 연결하기
   
  var delBttn = document.createElement("span");   // 새 button 요소 만들기
  var delText = document.createTextNode("X");  // 새 텍스트 노드 만들기
  delBttn.setAttribute("class", "del");  // 버튼에 class 속성 설정하기
  delBttn.appendChild(delText);  // 텍스트 노드를 button 요소의 자식 요소로 연결하기              
  newP.appendChild(delBttn);  //  del 버튼을 p 요소의 자식 요소로    

  var nameList = document.querySelector("#nameList");  
// p 요소를 #nameList 맨 앞에 추가하기
  nameList.insertBefore(newP, nameList.childNodes[0]);  
  userName.value = "";  // 텍스트 필드 지우기
 
  var removeBttns = document.querySelectorAll(".del");
 
  // removeBttns에 있는 요소 전체를 반복
  for (var i=0; i<removeBttns.length; i++) {  
    // i번째 버튼을 클릭했을 때 실행할 함수 선언
    removeBttns[i].addEventListener("click", function() {  
      //현재 부모 노드의 부모 노드가 있을 경우 실행
      if (this.parentNode.parentNode)  
      //현재 부모 노드의 부모 노드를 찾아 현재 노드(this)의 부모 노드(p 노드) 삭제
        this.parentNode.parentNode.removeChild(this.parentNode);  
    });
  }
}  

2022년 11월 2일 수요일

자바스크립트 7강(Array 객체)

 1. Array 객체란?

한 자료형인 항목을 하나의 변수에 여러 개 저장할 때 Array 객체를 사용한다.


2. Array 객체로 배열 만드는 법

var myArray = new Array(); //myArray 이름의 Array객체 인스턴스를 생성했다.

var numbers = new Array("one", "two", "three", "four"); //배열 객체를 만들면서 값도 넣어줬다. 


3. 배열에서 for문 사용하기

for(var i=0; i < numbers.length; i++) { 

    console.log(numbers[i]); 

}


4. Array 객체의 함수 종류

(1) 둘 이상의 배열을 연결하는 concat() 함수

var nums = ["1", "2", "3"];

var chars = ["a", "b", "c", "d"];

nums.concat(chars); //결과 :  "1", "2", "3", "a", "b", "c", "d"

chars.concat(nums); //결과 :  "a", "b", "c", "d",  "1", "2", "3" 


(2) 배열 요소를 연결하는 join()함수 

nums.join() //결과(기본 값은 ,) : 1,2,3 

nums.join("-") //결과 : 1-2-3


(3) 새로운 요소를 추가하는 push()함수와 unshift()함수

var nums = ["1", "2", "3"];

-기존 배열 맨 끝에 요소 추가: push() 함수

nums.push("4", "5"); //결과 ["1", "2", "3", "4", "5"]

-기존 배열 맨 앞에 요소 추가: unshfit() 함수

nums.unshift("-1", "0");  //결과 ["-1", "0", "1", "2", "3", "4", "5"]


(4) 배열에서 요소 추출하는 pop() 함수, shift() 함수

var nums = ["-1", "0", "1", "2", "3", "4", "5"];

- 기존 배열에서 맨 뒤에 있는 요소 추출할 때 

nums.pop(); //결과: 5

- 기존 배열에서 맨 앞에 있는 요소 추출할 때

nums.shift(); //결과: -1


(5) 원하는 위치의 요소를 삭제하거나 추가하는 splice() 함수

-인수가 1개일 경우 : 인수부터 ~ 끝까지 요소 모두 삭제

var nums = ["-1", "0", "1", "2", "3", "4", "5"];

nums.splice(2); //결과 : ["-1", "0"] 만 남음

- 인수가 2개일 경우 : 인덱스 값, 삭제할 갯 수 

var nums = ["-1", "0", "1", "2", "3", "4", "5"];

nums.splice(2, 2); //결과 :  ["-1", "0", "3", "4", "5"]

- 인수가 3개 이상일 경우 : 인덱스 값, 삭제할 갯 수, 삭제한 위치에 추가할 요소

var nums = ["-1", "0", "1", "2", "3", "4", "5"];

nums.splice(2, 3, "js"); //결과:  ["-1", "0", "js", "4", "5"] //인덱스 2부터 3개 요소 지우고 js삽입

- 기존 배열 요소를 삭제하지 않고 새로운 요소를 삽입 하려면 두 번째 인수에 0 입력

nums.splice(2, 0, "js"); //결과 : ["-1", "0", "js", "1", "2", "3", "4", "5"];


(6) 원하는 위치와 요소들을 추출하는 slice() 함수

- 시작 인덱스와 끝 인덱스를 지정해 그 사이의 요소를 추출

var nums = ["-1", "0", "1", "2", "3", "4", "5"];

nums.slice(1,4); //결과 [ "0", "1", "2", "3"] 인덱스 1~4까지 추출

* 주의점 : slice() 함수를 통해 요소를 추출해도 원래 배열은 변경되지 않는다.


자바스크립트 6강(객체)

 1. 객체란? 

복합 자료형, 객체 안에 숫자,문자열 등 여러가지 자료형이 포함, 객체 자체도 ㅈㅏ료형이기에 자료를 저장하고 처리하는 기본 단위


2. 객체의 종류

-내장 객체 : 미리 만들어져 내장되어 있는 객체(Number, Boolean, Array, Math 등)

-문서 객체 모델(DOM): 웹 문서, 이미지, 링크, 텍스트필드, 등등

-브라우저 객체 모델 : 웹 브라우저의 주소 표시줄, 창 크기 등 웹 브라우저의 정보를 객체로 다룸

-사용자 정의 객체 : 사용자가 필요할 때 마다 자신의 객체를 정의하고 사용하는 것


3. 객체의 속성과 메서드

-속성: 객체의 값을 담고 있는 정보, 속성 값을 가져올 때는 객체이름.속성이름

-메서드: 객체의 동작을 선언해 놓은 함수. 객체이름.매서드함수명(인수지정)

-객체의 인스턴스 만드는 법 : new 객체이름();

(예) var now = new Date();

     now.toLocaleString();


4. 사용자 정의 객체 만드는 법

//객체 설정

var book = {

    title: "자바스크립트",    //속성은 속성이름 : 값 으로 지정

    author: "김",

    info : function() {  //매소드는 함수이름 : 함수(인자값){} 으로 지정

        alert(this.title + " 책은 " + this.author + "이 썼다.");

    }

}

//객체 실행

book.title; //결과값 : 자바스크립트

book.info(); //결과값 : 자바스크립트 책은 김이 썼다.


5. 생성자 함수를 사용해 객체 만드는 법

-생성자 함수란? 객체를 만들어 내는 함수.

(예)

//생성자 함수를 이용해 book 함수 설정

function Book(author, pages, price, title) {

    this.author = author;

    this.pages = pages;

    this.price = price;

    this.title = title;

}

// book 객체 사용법

kimBook = new Book("김", 400, 30000, "자바스크립트");

kimBook에 들어 있는 값 : author: "김", pages:400, price:30000, title:"자바스크립트"

kimBook.title; //결과값 : 자바스크립트

2022년 11월 1일 화요일

자바스크립트 5강(함수와 이벤트)

 1. 함수란?

자주 사용하는 프로그램을 하나로 묶어서 재사용 하는 기술

함수가 어떤 명령을 처리 해야 할지 미리 알려주는 것 : 함수 선언

선언한 함수를 가져와 사용하는 것 : 함수 실행


2. 함수 선언

function 함수명(인자1, 인자2) { //인자가 없다면 ()만 입력
    //내부 프로그램

    return ; // 출력할 것이 있다면 표시

}

예) function addNumber(a, b) {

    var sum = a + b; //인자 2개를 받아서 합한 뒤 sum에 저장

    return sum; //sum 출력

}

ES6부터는 => 표기법으로 함수 선언 가능

const hi = function() { return "하여~"; } //function 선언법

const hi = () => { return "하여~"; } //화살표 표기법으로 함수 선언


3. 함수 실행

함수명(인자1, 인자2); //인자가 없다면 ()로 생략 가능


4. let, constant 로 변수 선언

- 함수 안에서만 사용되는 변수 : 지역변수, 로컬 변수

- 스크립트 전체에서 사용되는 변수 : 전역변수, 글로벌 변수

- var : 변수를 선언하기 전에 사용해도 오류 발생 안하고, 재선언이 가능함, 같은 이름을 사용할 경우 덮어쓰기도 함(유연한 변수 선언), 함수 영역의 범위를 가짐.

- let : 블록 영역의 범위를 가짐, 지역 변수에 사용하기 좋음. 재할당은 가능, 재선언은 불가능, 변수를 초기화 하기 전까지는 사용할 수 없음.

- const : 상수로 선언함. 변하지 않음, 블록 레벨의 범위에 사용

- 전역 변수 선언 : 변수이름 = 초기값; //변수 이름 앞에 아무것도 적지 않음


5. 변수 선언 시 가이드

- 전역 변수는 최소한으로 사용

- var 변수는 함수의 시작 부분에 선언

- for문에서 카운터 변수를 사용할 때는 let를 사용하기

- ES6 버전을 사용하면 var보다 let를 사용하는 것 권장


6. 이벤트 다루기

이벤트란? 웹 브라우저나 사용자가 행하는 어떤 동작을 뜻함.

주로 마우스, 키보드를 사용할 때, 웹 문서를 불러올 때, Form에서 내용을 입력할 때 발생

이벤트와 이벤트 처리 함수를 연결해주는 것 : 이벤트 처리기 또는 이벤트 핸들러

이벤트 핸들러는 이벤트 이름 앞에 on을 붙여서 사용.(예) click 이벤트 - onclick

(예) 클릭 이벤트가 발생하면 상세 설명 내용은 화면에 표시하고 버튼은 감춤 

<button class="over" id="open" onclick="showDetail()">상세설명보기</button>

function showDetail() {

    document.querySelector('#desc').style.display = "block"; //상세 설명 내용을 화면에 표시

    document.querySelector('#desc').style.display = "none"; //상세 설명 보기 버튼 감춤

}


7. 여러 이벤트 다루기

<script src="js/event-dom-result.js"></script> //js경로에 있는 event-dom-result.js 파일 연결

//event-dom-result.js 파일 내용
var coverImage = document.querySelector("#cover");
        coverImage.onclick = function() {
            alert('눌렀습니다');
        };
        coverImage.onmouseover = function() {
            coverImage.style.border = "5px black solid";
        };
        coverImage.onmouseout = function() {
            coverImage.style.border = "";
        };

자바스크립트 4강(제어문)

1. if문 

if(조건1) {

//조건1이 참일 때 실행

} else if(조건2) {

//조건1은 거짓이면서 조건2가 참일 때 실행(위부터 체크 하며 내려옴)

else {

//모든 조건이 거짓일 때 실행

}

2. 조건 연산자

조건 ? true : false;

예제) var score = 75;

(score >= 60) ? alert("통과") : alert("실패");

3. switch 문

한꺼번에 여러 개의 조건을 처리할 때 쓰임

var session = prompt("관심 세션을 선택해 주세요. 1-마케팅, 2-개발, 3-디자인","1");
       
switch(session) {
   case "1" : document.write("마케팅 세션은 <strong>201호</strong>에서 진행됩니다.");
      break;
  case "2" : document.write("개발 세션은 <strong>203호</strong>에서 진행됩니다.");
       break;
   case "3" : document.write("디자인 세션은 <strong>205호</strong>에서 진행됩니다.");
       break;
   default: alert("잘못 입력했습니다.");
}

4. for 문

for(카운터 변수; 조건식; 카운터 변수 조절){

    조건식이 만족할 때까지 반복

}

예제) 구구단 구현 2중 for문 

<h1>구구단</h1>
    <script>
//1. 맨 처음 외부 for문 부터 시작
        for(var i = 2; i <= 9; i++) { //3.내부 for문이 끝나면 1 회전
            document.write("<div>");
            document.write("<h3>" + i + "단</h3>");
            for (var j = 1; j <= 9; j++) { //2.내부 for문이 끝나면 외부 for문 1회전
                document.write(i +" X " + j + " = " + i * j + "<br>");
            }
            document.write("</div>");
        }
    </script>

5. for ~ of문
주어진 값을 다 읽을 때까지 반복하는 반복문
let seasons = ["봄","여름","가을","겨울"];
for(let value of seasons) { //seasons 배열 처음부터 끝까지 반복
    console.log(value);
}

6. while문, do~while 문
var i = 0;
while(i < 10) { //조건이 false가 될 때까지 반복
    document.write("반복 조건이 true이면 반복한다<br>");
    i += 1; //이 부분이 없으면 무한 반복을 하게 된다.
}

var i = 0;
do { //반복 조건에 상관 없이 1회는 무조건 실행한다.
    document.write("반복 조건이 true이면 반복한다<br>"); //명령 실행
    i += 1; //이 부분이 없으면 무한 반복을 하게 된다.
}
while(i < 10); // 조건이 false가 되면 반복 종료

7. break문, continue문

for(i=0; i<10; i++) { //원래는 10번 반복해야 하지만~     document.write("*");
    break; //break문을 만나면 바로 반복문을 종료한다.
}

for(i=0; i<10; i++) { //원래는 10번 반복해야 하지만~     document.write("*");
    continue; //continue 문을 만나면 건너 뛰고 다시 반복한다.
    document.write("continue문 때문에 이 문장은 건너뛴다.");
}

자바스크립트 3강(변수,자료형,연산자)

1. 변수를 선언하는 규칙 3가지

(1) 이름은 의미 있게 짓는다.

(2) 여러 단어를 연결한 변수 이름은 낙타 모양으로 만들어준다.(예- birthYear)

(3) 첫 글자는 문자, 밑줄(_), 달러 기호($)로 시작해야 한다. 예약어도 사용 불가


2. 자료형의 종류

(1)기본형

- number(숫자)

- string(문자열)

- boolean(논리형)

- undefined(자료형을 지장하지 않았을 때의 유형)

- null(값이 유효하지 않을 때의 유형)

(2)복합형

- array(배열)

- object(객체)


3.자료형 특징

(1) 자바스크립트는 정수, 실수 모두 number로 취급함.

(2) 단, 실수끼리 계산할 때는 2진수로 변환하여 계산하기에 오차가 난다.

(3) 문자형은 '' 이나, ""로 묶을 수 있다. ""로 묶는 것을 권장한다.

(4) 논리형은 true/false로 표현한다.

(5) undefined 가 아직 변수에 값이 없다는 뜻이다.(타 언어의 null과 다르다)

(6) null 이 처음에 할당한 값이 더는 유효하지 않다는 뜻이다.


4. 배열

-기본 형식- 

var 배열이름 = ["값1", "값2", "값3", "값4"];  

or 

var 배열이름 = [];


-배열 출력-

배열이름[0]; 

>"값1"


5. 객체

-기본 형식-

var 객체이름 = {

    firstName: "kim",

    lastName: "goo",

    age: 35,

    address: "Seoul"

}

객체는 중괄호{} 로 묶고, 키와 값을 :을 사용하여 한 쌍으로 묶는다.


6. 연산자

사칙 연산자 : +, -, *, /

나머지 연산자 : %

증감 연산자 : ++, --


증감 연산자 주의점

(예) 

var a = 10;  //a에 10

var b= a++ + 5; //b = 15를 먼저 계산 후 , a를 1증가 시켜 a = 11 이 저장

b는? 15


var c= 10;  //c에 10 저장

var d = ++c + 5; //c를 먼저 1증가 시키고, +5 하여 d에는 16이 저장

d는? 16


7. == 연산자, === 연산자 차이

10 == "10"은 true //==연산자는 문자형과 숫자형이 있으면 자동으로 변환하여 비교

10 === "10" 은 false //=== 연산자는 다른 자료형을 변환하지 않고 비교


8. 논리 연산자

- OR 연산자: ||  

- AND 연산자: && 

- NOT 연산자: !



자바스크립트 1~2강

 Doit! 자바스크립트 입문 요약 정리 

1. 자바스크립트란? 

-웹 사이트를 동적으로 개발 가능

-웹 브라우저에 실행되는 프로그램 개발 가능

-서버를 구성하고 서버용 프로그램 개발  가능

-모든 웹 브라우저에서 동작 가능

2. 작성법

<script>태그는 HTML  문서 어디에든 사용가능

<script>태그는 한  문서 안에 여러 개  사용 가능

<script>태그가 삽입된 위치에서 소스 실행

예)

<script>
        var heading = document.querySelector('#heading');
        heading.onclick = function() {
            heading.style.color = "red";
        }
 </script>

위와 같은 방식으로 하면 해당 HTML 문서에서 밖에 사용을 못하기에
js/change.js 파일에 아래와 같이 작성하고 (확장자 명을 js로 해야한다.)

var heading = document.querySelector('#heading');
heading.onclick = function() {
heading.style.color = "red";
}

아래와 같이 파일을 연결하여 사용한다.
<script src="js/change.js"></script>

3. 자바스크립트의 입력과 출력
-사용자 입력 값 받기
prompt(); - prompt("창 내용"); - prompt("창 내용", "기본값");

- 알림창으로 출력하기
alert("알림창 내용");

-웹 브라우저 화면에 출력
document.write(변수명);

-콘솔에 출력하기
console.log(변수명);

4. 자바스크립트 작성 규칙
- 대소문자를 구별하여 소스 작성
- 읽기 쉽게 들여쓰기
- 세미콜론(;)으로 문장을 구분하기
- 한 줄 주석 : //내용
- 여러 줄 주석 : /* 내용 */
- 이름의 첫 글자는 반드시 영문자, 밑줄(_), 달러 기호($)로만 시작 가능
- 단어 사이에 공백은 안됨
- 예약어는 식별자로 사용 불가능

2022년 7월 23일 토요일

JSP 11강 - 서블릿(Servlet)

1. 서블릿이란?

JSP가 나오기 전 자바로 웹 애플리케이션을 개발할 수 있도록 만든 기술.

서버 단에서 클라이언트의 요청을 받아 처리한 후 응답하는 역할.

-서블릿의 특징-

  • 클라이언트의 요청에 대해 동적으로 작동하는 웹 애플리케이션 컴포넌트.
  • MVC 모델에서 컨트롤러 역할
  • 모든 메서드는 쓰레드로 동작
  • javax.servlet.http 패키지의 HttpServlet 클래스를 상속받음
2. 서블릿 컨테이너
서블릿의 수명주기를 관리하고, 요청이 오면 스레드를 생성해 처리 해주고, 클라이언트의 요청을 받아서 응답을 보낼 수 있도록 통신 지원
  • 통신 지원 : 클라이언트와 통신하려면 서버는 특정 포트로 소켓을 열고 I/O 스트림을 생성 해주는 과정을 API 제공으로 간단히 해결
  • 수명주기 관리 : 서블릿을 인스턴스화한 후 초기화 하고, 요청에 맞는 적절한 메서드를 호출한다. 응답한 후에는 가비지 컬렉션을 통해 객체를 소멸시킨다.
  • 멀티스레딩 관리 : 서블릿 요청들은 스레드를 생성해 처리합니다. 즉, 멀티스레드 방식으로 여러 요청을 동시에 처리
  • 선언적인 보안 관리 및 JSP 지원 : 서블릿 컨테이너는 보안 기능을 지원한다.
3. 서블릿의 동작 방식
  1. 클라이언트의 요청을 받는다.
  2. 분석 후 요청을 처리할 서블릿을 찾는다.
  3. 비즈니스 서비스 로직을 호출한다.
  4. model 로부터 그 결과 값을 받는다
  5. request 나 session 영역에 저장한 후 결과 값을 출력할 view를 선택한다.
  6. view(JSP 페이지)에 결과 값을 출력한 후 요청한 클라이언트에 응답한다.
4. 서블릿 작성 규칙
  1. javax.servlet, javax.servlet.http, java.io 패키지를 임포트 한다.
  2. 서블릿 클래스는 반드시 public로 선언해야 하고, HttpServlet를 상속해야 한다.
  3. 사용자 요청을 처리하기 위해 doGet() 메서드나 doPost() 메서드를 반드시 오버라이딩 해야 한다.
  4. doGet() 또는 doPost() 메서드는 ServletException 과 IOException 예외를 던지도록 (throws) 선언한다.
  5. doGet() 또는 doPost() 메서드를 호출할 때의 매개변수는 HttpServletRequest 와 HttpServletResponse 를 사용한다.
5. 서블릿 작성
1)  web.xml 에서 매핑

  <servlet>  <!-- 서블릿 등록 -->
    <servlet-name>서블릿명</servlet-name>
    <servlet-class>패키지를 포함한 서블릿 클래스명</servlet-class>
  </servlet>
  <servlet-mapping>  <!-- 서블릿과 요청명 매핑 -->
    <servlet-name>서블릿명</servlet-name>
    <url-pattern>클라이언트 요청 URL</url-pattern>
  </servlet-mapping>
예제) 요청을 처리할 서블릿 클래스
package servlet;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class HelloServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        req.setAttribute("message", "서블릿은 web-inf에 등록하고 해야하네.");
        req.getRequestDispatcher("/13Servlet/HelloServlet.jsp").forward(req, resp);
    }
}
2) @WebServlet 애너테이션으로 매핑
package servlet;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/13Servlet/AnnoMapping.do")
public class AnnoMapping extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    req.setAttribute("message", "@WebServlet으로 매핑");
    req.getRequestDispatcher("/13Servlet/AnnoMapping.jsp").forward(req, resp);
    }
}
6. 서블릿의 수명주기 메서드
  • @Postconstruct : 객체 생성 직후 호출, 애너테이션을 사용하므로 메서드명은 개발자가 정함
  • init() : 서블릿의 초기화 작업을 수행하기 위해 호출, 최초 요청시 딱 한번만 호출
  • service() : 클라이언트의 요청을 처리 하기 위해 호출
  • destroy() : 서블릿이 새롭게 컴파일 되거나, 서버가 종료될 때 호출
  • @PreDestroy : 서블릿 객체를 제거하는 과정에서 호출
예제) 수명 주기 메서드 동작 확인
<%@ page language="java" contentType="text/html; charset=UTF-8"pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>LifeCycle.jsp</title>
</head>
<body>
    <script>
    function requestAction(frm, met) {
        if (met == 1) {
            frm.method = 'get';
        }
        else {
            frm.method = 'post';
        }
        frm.submit();
    }
    </script>

    <h2>서블릿 수명주기(Life Cycle) 메서드</h2>
    <form action="./LifeCycle.do">
        <input type="button" value="Get 방식 요청하기" onclick="requestAction(this.form, 1);" />
        <input type="button" value="Post 방식 요청하기" onclick="requestAction(this.form, 2);" />
    </form>
</body>
</html>

예제) 수명주기 메서드 동작 확인용 서블릿
package servlet;

import java.io.IOException;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/13Servlet/LifeCycle.do")
public class LifeCycle extends HttpServlet {

    @PostConstruct
    public void myPostConstruct() {
        System.out.println("myPostConstruct() 호출");
    }

    @Override
    public void init() throws ServletException {
        System.out.println("init() 호출");
    }

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        System.out.println("service() 호출");
        super.service(req, resp);
    }        

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) 
            throws ServletException, IOException {
        System.out.println("doGet() 호출");
        req.getRequestDispatcher("/13Servlet/LifeCycle.jsp").forward(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) 
            throws ServletException, IOException {
        System.out.println("doPost() 호출");
        req.getRequestDispatcher("/13Servlet/LifeCycle.jsp").forward(req, resp);
    }

    @Override
    public void destroy() {
        System.out.println("destroy() 호출");
    }

    @PreDestroy
    public void myPreDestroy() {
        System.out.println("myPreDestroy() 호출");
    }
}

JSP 10강 - 파일 업로드 및 다운로드

 파일 첨부가 가능한 자료실 형 게시판을 만들기 위해서는 파일을 업로드, 다운로드 기능을 구현해야 한다. 

1. 라이브러리 추가하기

http://servlets.com/cos/

에서 cos 를 다운 받고, WebContent/WEB-INF/lib에 추가 한다.

2. 화면(폼) 작성

enctype 속성은 서버로 전송할 때 인코딩 방식을 지정하는 속성으로 3가지가 있다.

appliction/x-www-form-urlencoded : 모든 문자를 서버로 전송하기 전에 인코딩 한다. 기본값

multipart/form-data : 모든 문자를 인코딩하지 않는다.<form>태그를 통해 파일을 서버로 전송할 때 주로 사용

text/plain : 공백 문자만 + 기호로 변환하고, 나머지는 인코딩하지 않는다.


<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>

<html>

<head><title>FileUpload</title></head>

<script>

//입력값 검증용 자바스크립트

    function validateForm(form) { 

        if (form.name.value == "") {

            alert("작성자를 입력하세요.");

            form.name.focus();

            return false;

        }

        if (form.title.value == "") {

            alert("제목을 입력하세요.");

            form.title.focus();

            return false;

        }

        if (form.attachedFile.value == "") {

            alert("첨부파일은 필수 입력입니다.");

            return false;

        }

    }

</script>

<body>

    <h3>파일 업로드</h3>

    <span style="color: red;">${errorMessage }</span>

//method 속성은 post로, enctype 속성은 multipart/form-data로 지정해야 한다.

    <form name="fileForm" method="post" enctype="multipart/form-data"

          action="UploadProcess.jsp" onsubmit="return validateForm(this);">

        작성자 : <input type="text" name="name" value="머스트해브" /><br />

        제목 : <input type="text" name="title" /><br /> 

        카테고리(선택사항) : 

            <input type="checkbox" name="cate" value="사진" checked />사진 

            <input type="checkbox" name="cate" value="과제" />과제 

            <input type="checkbox" name="cate" value="워드" />워드 

            <input type="checkbox" name="cate" value="음원" />음원 <br /> 

//<input> 태그의 type 속성은 file로 지정한다.

        첨부파일 : <input type="file" name="attachedFile" /> <br />

        <input type="submit" value="전송하기" />

    </form>

</body>

</html>

3. 파일 업로드 및 폼값 처리

폼값을 받을 때는 확장 라이브러리에서 제공하는 MultipartRequest 클래스를 사용한다.

//import 생략

String saveDirectory = application.getRealPath("/Uploads");  // 저장할 디렉터리

int maxPostSize = 1024 * 1000;  // 파일 최대 크기(1MB)

String encoding = "UTF-8";  // 인코딩 방식

try {

    // 1. MultipartRequest 객체 생성

    MultipartRequest mr = new MultipartRequest(request, saveDirectory, maxPostSize, encoding);


    // 2. 새로운 파일명 생성

    String fileName = mr.getFilesystemName("attachedFile");  // 현재 파일 이름

    String ext = fileName.substring(fileName.lastIndexOf("."));  // 파일 확장자

    String now = new SimpleDateFormat("yyyyMMdd_HmsS").format(new Date());

    String newFileName = now + ext;  // 새로운 파일 이름("업로드일시.확장자")


    // 3. 파일명 변경(서버의 운영체제에 따라 경로 표현이 다르기에 이렇게 설정)

    File oldFile = new File(saveDirectory + File.separator + fileName); 

    File newFile = new File(saveDirectory + File.separator + newFileName);

    oldFile.renameTo(newFile);


    // 4. 다른 폼값 받기

    String name = mr.getParameter("name");

    String title = mr.getParameter("title");

    String[] cateArray = mr.getParameterValues("cate");

    StringBuffer cateBuf = new StringBuffer();

    if (cateArray == null) {

        cateBuf.append("선택 없음");

    }

    else {

        for (String s : cateArray) {

            cateBuf.append(s + ", ");

        }

    }


    // 5. DTO 생성

    MyfileDTO dto = new MyfileDTO();

    dto.setName(name);

    dto.setTitle(title);

    dto.setCate(cateBuf.toString());

    dto.setOfile(fileName);

    dto.setSfile(newFileName);


    // 6. DAO를 통해 데이터베이스에 반영

    MyfileDAO dao = new MyfileDAO();

    dao.insertFile(dto);

    dao.close();


    // 7. 파일 목록 JSP로 리디렉션

    response.sendRedirect("FileList.jsp");

}

catch (Exception e) {

    e.printStackTrace();

    request.setAttribute("errorMessage", "파일 업로드 오류");

    request.getRequestDispatcher("FileUploadMain.jsp").forward(request, response);

}

%>

4. 파일 다운로드
//import 생략
String saveDirectory = application.getRealPath("/Uploads"); //다운로드 파일 위치
String saveFilename = request.getParameter("sName"); //저장된 파일명
String originalFilename = request.getParameter("oName"); //원본 파일명

try {
    // 파일을 찾아 입력 스트림 생성
    File file = new File(saveDirectory, saveFilename);  
    InputStream inStream = new FileInputStream(file);
    
    // 한글 파일명 깨짐 방지
    String client = request.getHeader("User-Agent");
    if (client.indexOf("WOW64") == -1) {
        originalFilename = new String(originalFilename.getBytes("UTF-8"), "ISO-8859-1");
    }
    else {
        originalFilename = new String(originalFilename.getBytes("KSC5601"), "ISO-8859-1");
    }
   
// 파일 다운로드용 응답 헤더 설정 
    response.reset(); 
//다운로드 창을 위한 콘텐츠 타입 지정 (octet-stream 은 8비트 단위의 바이너리 데이터)
    response.setContentType("application/octet-stream"); 
//파일 다운로드 창이 뜰 때 원본 파일명이 기본으로 입력 되도록 설정
    response.setHeader("Content-Disposition", "attachment; filename=\"" +originalFilename + "\""); 
    response.setHeader("Content-Length", "" + file.length() );
    
    // 출력 스트림 초기화
    out.clear();  //출력 스트림 중복을 막기 위해 현재 것을 초기화
    
    // response 내장 객체로부터 새로운 출력 스트림 생성
    OutputStream outStream = response.getOutputStream();   

    // 출력 스트림에 파일 내용 출력
    byte b[] = new byte[(int)file.length()];
    int readBuffer = 0;    
    while ( (readBuffer = inStream.read(b)) > 0 ) {
        outStream.write(b, 0, readBuffer);
    }

    // 입/출력 스트림 닫음
    inStream.close(); 
    outStream.close();
}
catch (FileNotFoundException e) {
    JSFunction.alertBack("파일을 찾을 수 없습니다.", out);
}
catch (Exception e) {
    JSFunction.alertBack("예외가 발생하였습니다.", out);
}
%>

2022년 7월 18일 월요일

JSP 9강 - JSP 표준 태그 라이브러리(JSTL)

 JSTL 이란? 

스크립틀릿을 사용하지 않고도 제어문, 반복문 등을 처리해주는 태그를 모아 표준으로 만든 라이브러리.

JSTL을 사용하면 스크립트릿 없이 태그만으로 작성할 수 있다.

JSTL 형식

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<%@ taglib prefix="JSTL사용시 태그 앞에 붙일 접두어" uri="태그 라이브러리 URI 식별자"%>

1. 코어(Core) 태그 - 변수 선언, 조건문, 반복문 등 기본이 되는 태그

set - EL 에서 사용할 변수를 설정 

<c:set var="변수명" value="값" scope="영역" />

<c:set target="var로 설정한 변수명" property="객체의 속성명" value="속성값" />


remove - 설정한 변수를 제거

<c:remove  var="변수명" scope="영역" />


if - 단일 조건문을 주로 처리. else 문은 없음

<c:if test="조건" var="변수명" scope="영역">

    조건이 true 일 때 출력할 문장

</c:if>


choose - 다중 조건을 처리할 때 사용. 하위에 when~otherwise 태그가 있음

<c:choose>

    <c:when test="조건1">조건1을 만족하는 경우</c:when>

    <c:when test="조건2">조건2을 만족하는 경우</c:when>

    <c:otherwise>아무 조건도 만족하지 않는 경우</c:otherwise>

</c:choose>


forEach - 반복문을 처리할 때 사용

<c:forEach var="변수명" begin="시작값" end="마지막값" step="증가값" />

<c:forEach var="변수명" items="컬렉션 혹은 배열" />


forTokens - 구분자로 분리된 각각의 토큰을 처리할 때 사용

<c:forTokens items="문자열" delims="문자열 구분자" var="변수명" />


import - 외부 페이지를 삽입할 때 사용

<c:import url="페이지 경로, URL" scope="영역" />

<c:import url="페이지 경로, URL" var="변수명" scope="영역" />

${ 변수명 }

<c:import url="페이지 경로, URL?매개변수1=값1" >

    <c:param name="매개변수2" value="값2" />

</c:import>


redirect - 지정한 경로로 이동

<c:redirect url="이동할 경로 및 URL" />


url - 경로를 설정할 때 사용

<c:url value="설정한 경로" scope="영역" var="변수명" />

${ 변수명 } //원하는 위치에 URL 삽입


out - 내용을 출력할 때 사용

<c:out value="출력할 변수" default="기본값" escapeXml="특수문자 처리 유무" />


catch - 예외 처리에 사용

<c:catch var="변수명">

    실행코드

</c:catch>

2. 국제화(Formatting) 태그 - 국가별로 다양한 언어, 날짜, 시간, 숫자 형식을 설정할 때 사용

formatNumber - 숫자 포맷을 설정

parseNumber - 문자열을 숫자 포맷으로 변환

formatDate - 날짜나 시간의 포맷을 설정

parseDate - 문자열을 날짜 포맷으로 변환

setTimeZone - 시간대 설정 정보를 변수에 저장

timeZone - 시간대를 설정

setLocale - 통화 기호나 시간대를 설정한 지역에 맞게 표시

requestEncoding - 요청 매개변수의 문자 셋을 설정

예제) 숫자 포멧팅 및 파싱 태그 사용하기

<%@ page language="java" contentType="text/html; charset=UTF-8"

    pageEncoding="UTF-8"%>

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>       

<html>

<head><title>JSTL - fmt 1</title></head>

<body>

    <h4>숫자 포맷 설정</h4>

    <c:set var="number1" value="12345" />

    콤마 O : <fmt:formatNumber value="${ number1 }" /><br />

    콤마 X : <fmt:formatNumber value="${ number1 }" groupingUsed="false" /><br />

    <fmt:formatNumber value="${number1 }" type="currency" var="printNum1" />

    통화기호 : ${ printNum1 } <br />

    <fmt:formatNumber value="0.03" type="percent" var="printNum2" />

    퍼센트 : ${ printNum2 }

    

    <h4>문자열을 숫자로 변경</h4>

    <c:set var="number2" value="6,789.01"  /> 

    <fmt:parseNumber value="${ number2 }" pattern="00,000.00" var="printNum3" /> 

    소수점까지 : ${ printNum3 } <br />

    <fmt:parseNumber value="${ number2 }" integerOnly="true" var="printNum4" /> 

    정수 부분만 : ${ printNum4 }


    <c:set var="today" value="<%= new java.util.Date() %>" />

    

    <h4>날짜 포맷</h4>

    full : <fmt:formatDate value="${ today }" type="date" dateStyle="full"/> <br /> 

    short : <fmt:formatDate value="${ today }" type="date" dateStyle="short"/> <br />

    long : <fmt:formatDate value="${ today }" type="date" dateStyle="long"/> <br />

    default : <fmt:formatDate value="${ today }" type="date" dateStyle="default"/>


    <h4>시간 포맷</h4> 

    full : <fmt:formatDate value="${ today }" type="time" timeStyle="full"/> <br /> 

    short : <fmt:formatDate value="${ today }" type="time" timeStyle="short"/> <br />

    long : <fmt:formatDate value="${ today }" type="time" timeStyle="long"/> <br />

    default : <fmt:formatDate value="${ today }" type="time" timeStyle="default"/>

    

    <h4>날짜/시간 표시</h4>    

    <fmt:formatDate value="${ today }" type="both" dateStyle="full" timeStyle="full"/> 

    <br />

    <fmt:formatDate value="${ today }" type="both" pattern="yyyy-MM-dd hh:mm:ss"/> 

    

    <h4>타임존 설정</h4>

    <fmt:timeZone value="GMT"> 

        <fmt:formatDate value="${ today }" type="both" dateStyle="full" timeStyle="full"/>

        <br />    

    </fmt:timeZone>

    <fmt:timeZone value="America/Chicago">

        <fmt:formatDate value="${ today }" type="both" dateStyle="full" timeStyle="full"/>

    </fmt:timeZone>

    

    <h4>로케일 설정</h4>    

    <c:set var="today" value="<%=  new java.util.Date() %>"/>

    

    한글로 설정 : <fmt:setLocale value="ko_kr" />

    <fmt:formatNumber value="10000" type="currency" /> /

    <fmt:formatDate value="${ today }" /><br />


    일어로 설정 : <fmt:setLocale value="ja_JP" />

    <fmt:formatNumber value="10000" type="currency" /> /

    <fmt:formatDate value="${ today }" /><br />

    

    영어로 설정 : <fmt:setLocale value="en_US" />

    <fmt:formatNumber value="10000" type="currency" /> /

    <fmt:formatDate value="${ today }" /><br />   

</body>

</html>

결과



JSP 8강 - 표현 언어(EL)

표현 언어란? 변수의 값을 출력할 때 사용하는 스크립트 언어

1. 표현 언어가 제공하는 기능

  • JSP 내장 객체의 영역에 담긴 속성을 사용할 수 있음
  • 산술 연산, 비교 연산, 논리 연산이 가능
  • 자바 클래스에 정의된 메서드를 호출 가능
  • 표현 언어만의 객체를 통해 JSP와 동일한 기능을 수행 가능
2. EL의 기본 사용법

${ 영역에 저장된 속성 }

JSP에서 생성한 변수를 접근하려면, 반드시 영역에 저장 후 사용해야 한다.
JSP 스크립트 요소(선언부, 표현식, 스크립틀릿)에서는 사용할 수 없다.

EL에서 객체를 표현할 때는 . 이나 []를 사용한다. []를 사용할 때 속성명은 ""와 '' 모두 사용 가능
(예) ${ param.name }
     ${ param["name"] }
     ${ param['name'] }

3. EL에서 4가지 영역에 접근하기 위한 내장 객체
  • pageScope : page 영역에 저장된 속성값 읽어옴.
  • requestScope : request영역에 저장된 속성값 읽어옴.
  • sessionScope : session 영역에 저장된 속성값 읽어옴.
  • aplicationScope : application 영역에 저장된 속성값 읽어옴.

4. 폼 값 처리하기

param : request.getParmeter("매개변수명")과 동일하게 요청 매개변수의 값을 받아온다.

paramValues : request.getParameterValues("매개변수명")와 동일하게 요청 매개변수의 값을 문자열 배열로 받아온다. 주로 다중 선택이 가능한 checkbox를 통해 전달된 폼 값을 받을 때 사용.

5. 객체 전달하기

폼으로는 객체를 전달 할 수 없기에 영역을 사용한다.

예제) 객체 전달 부분

<%@ page import="common.Person"%>

<%@ page language="java" contentType="text/html; charset=UTF-8"

    pageEncoding="UTF-8"%>

<html>

<meta charset="UTF-8">

<head><title>표현 언어(EL) - 객체 매개변수</title></head>

<body>

    <%

    request.setAttribute("personObj", new Person("홍길동", 33));

    request.setAttribute("stringObj", "나는 문자열");

    request.setAttribute("integerObj", new Integer(99));

    %>

    <jsp:forward page="ObjectResult.jsp">

        <jsp:param value="10" name="firstNum" />

        <jsp:param value="20" name="secondNum" />

    </jsp:forward>

</body>

</html>


예제) 전달 받은 객체 확인 부분

<%@ page import="common.Person"%>

<%@ page language="java" contentType="text/html; charset=UTF-8"

    pageEncoding="UTF-8"%>

<html>

<meta charset="UTF-8">

<head><title>표현 언어(EL) - 객체 매개변수</title></head>

<body>  

    <h2>영역을 통해 전달된 객체 읽기</h2>

    <ul>

        <li>Person 객체 => 이름 : ${ personObj.name }, 나이 : ${ personObj.age }</li>

        <li>String 객체 => ${ requestScope.stringObj }</li>

        <li>Integer 객체 => ${ integerObj }</li> 

    </ul>

    <h2>매개변수로 전달된 값 읽기</h2>

    <ul>

        <li>${ param.firstNum + param['secondNum'] }</li>  

        <li>${ param.firstNum } + ${param["secondNum"] }</li> 

    </ul>

</body>

</html>

영역에서는 모든 객체가 Object 타입으로 저장되기에 읽어올 때는 반드시 형 변환 후 사용하고, 게터로 멤버 변수의 값을 가져온다. 

한편 EL 사용하면 형 변환이 필요 없고, 게터 호출 대신 멤버 변수 이름만 쓰면 값을 출력 할 수 있다.

6. 쿠키, HTTP 헤더, 컨텍스트 초기화 매개변수 출력하기

EL은 쿠키나 헤더 값을 읽을 수 있도록 다음의 내장 객체를 제공한다.

  • cookie : 쿠키를 읽을 때 사용
  • header : request.getHeader(헤더명)와 동일하게 헤더값을 읽을 때 사용
  • headerValues : request.getHeaders(헤더명)와 동일하게 헤더값을 배영 형태로 읽을 때 사용
  • initParam : web.xml 에 설정한 컨텍스트 초기화 매개변수를 읽을 때 사용
  • pageContext : JSP의 pageContext 내장 객체와 동일한 역할
예제) 쿠키, HTTP 헤더, 컨텍스트 초기화 매개변수 출력하기

<%@ page import="utils.CookieManager"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
CookieManager.makeCookie(response, "ELCookie", "EL좋아요", 10);
%>    
<html>
<meta charset="UTF-8">
<head><title>표현 언어(EL) - 그 외 내장 객체</title></head>
<body>
    <h3>쿠키값 읽기</h3>
    <li>ELCookie값 : ${ cookie.ELCookie.value }</li>
    
    <h3>HTTP 헤더 읽기</h3>
    <ul>
        <li>host : ${ header.host }</li>
        <li>user-agent : ${ header['user-agent'] }</li>
        <li>cookie : ${ header.cookie }</li>
    </ul>
    
    <h3>컨텍스트 초기화 매개변수 읽기</h3>
    <li>OracleDriver : ${ initParam.OracleDriver }</li>

    <h3>컨텍스트 루트 경로 읽기</h3>
    <li>${ pageContext.request.contextPath }</li>
</body>
</html>

7. 컬렉션 사용하기

예제) EL로 컬렉션 이용하기
<%@ page import="java.util.HashMap"%>
<%@ page import="java.util.Map"%>
<%@ page import="java.util.List"%>
<%@ page import="java.util.ArrayList"%>
<%@ page import="common.Person"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<html>
<meta charset="UTF-8">
<head><title>표현 언어(EL) - 컬렉션</title></head>
<body>
<h2>List 컬렉션</h2>
<%
List<Object> aList = new ArrayList<Object>();
aList.add("청해진");
aList.add(new Person("장보고", 28));
pageContext.setAttribute("Ocean", aList);
%>
<ul>
    <li>0번째 요소 : ${ Ocean[0] }</li>
    <li>1번째 요소 : ${ Ocean[1].name }, ${ Ocean[1].age }</li>
    <li>2번째 요소 : ${ Ocean[2] }<!--출력되지 않음--></li>
</ul>
<h2>Map 컬렉션</h2>
<%
Map<String, String> map = new HashMap<String, String>();
map.put("한글", "훈민정음");
map.put("Eng", "English");
pageContext.setAttribute("King", map);
%>
<ul>
    <li>영문 Key : ${ King["Eng"] }, ${ King['Eng'] }, ${ King.Eng }</li>
    <li>한글 Key : ${ King["한글"] }, ${ King['한글'] }, \${King.한글 }<!--에러--></li>
</ul>
</body>
</html>

8. EL의 연산자들

1) 할당 연산자(EL 3.0 부터는 = 연산자로 변수에 값을 할당 가능)
  • ${ number = 10 } //할당과 동시에 출력
  • ${ number = 10; '' } //할달만 되고 출력은 되지 않음
2) 비교 연산자
  • > 또는 gt : ~보다 크다
  • >= 또는 ge : ~보다 크거나 같다
  • < 또는 lt : ~보다 작다
  • <= 또는 le : ~보다 작거나 같다
  • == 또는 eq : 같다
  • != 또는 ne : 같지 않다.
3) 논리 연산자
  • && 또는 and : 논리 and
  • || 또는 or : 논리 or
  • | 또는 not : 논리 not
4) empty 연산자
  • null
  • 빈 문자열
  • 길이가 0인 배열
  • size가 0인 컬렉션
5) 삼항 연산자(자바의 삼항 연산자와 사용법이 동일)
  • ${ 조건 ? "true일 때 선택" : "fales일 때 선택" }

    2022년 6월 21일 화요일

    JSP 7강 - 액션 태그(Action Tag)

     1. 액션 태그란?

    JSP 코드를 HTML 태그와 같은 형태로 간단히 사용할 수 있는 태그.

    액션 태그는 일반 JSP 코드 보다 HTML에 더 조화롭게 스며들고 간결함.

    액션 태그의 특징

    • XML 문법을 따름
    • 반드시 종료 태그를 사용해야 함
    • 액션 태그 사이에 주석을 사용하면 에러가 발생함
    • 액션 태그에 속성 값을 부여할 때는 표현식 <%= %>을 사용할 수 있음

    액션 태그는 용도에 따르게 4가지로 나눔
    • <jsp:include> : 외부 파일을 현재 파일에 포함 시킨다.
    • <jsp:forward> : 다른 페이지로 요청을 넘긴다.
    • <jsp:useBean>,<jsp:setProperty>,<jsp:getProperty> : 자바 빈즈를 생성, 값을 설정/추출한다.
    • <jsp:param> : 인클루드나 포워드시 매개변수를 전달한다.

    2. <jsp:include> : 외부 JSP 파일을 현재 JSP 파일로 포함시키는 기능

    ---include 지시어와 <jsp:include> 액션 태그 비교---

    include 지시어
    형식 : <%@include file="포함할 파일의 경로"%>
    표현식 : 표현식 사용 불가
    포함 방식 : 페이지 자체를 현재 페이지로 포함시킨 후 컴파일 진행
    변수 : 포함시킨 파일에서 생성한 변수 사용 진행
    page 영역 : 공유됨
    request 영역 : 공유됨

    <jsp:include> 액션 태그

    형식 : <jsp:include page="포함할 파일의 경로" />
    표현식 : 표현식 사용 가능
    포함 방식 : 실행의 흐름을 포함시킬 페이지로 이동 후 실행한 결과를 현재 페이지에 포함
    변수 : 포함시킨 파일에서 생성한 변수 사용 불가
    page 영역 : 공유되지 않음
    request 영역 : 공유됨
    --예제 코드--
    <html>
    <head><title>지시어와 액션 태그 동작 방식 비교</title></head>
    <body>
        <h2>지시어와 액션 태그 동작 방식 비교</h2>
        <!-- 지시어 방식 -->
        <h3>지시어로 페이지 포함하기</h3>
        <%@ include file="./inc/OuterPage1.jsp"%>
        <%--@ include file="<%=outerPath1OuterPage1%>" --%>
        <p>외부 파일에 선언한 변수 : <%=newVar1%></p>

        <!-- 액션 태그 방식 -->
        <h3>액션 태그로 페이지 포함하기</h3>
        <jsp:include page="./inc/OuterPage2.jsp" />
        <jsp:include page="<%=outerPath2%>" />
        <p>외부 파일에 선언한 변수 : <%--=newVar2 --%></p>
    </body>
    </html>


    3. <jsp:forward> : 현재 페이지에 들어온 요청을 다음 페이지로 보내는 기능

    <jsp:forward> 액션 태그를 만나기까지의 모든 출력을 제거하고 포워드할 페이지로 요청을 전달한다. 
    포워드는 버퍼와 밀접하며, 버퍼를 사용하지 않으면 포워드는 사용할 수 없다.
    포워드는 요청 전달이 목적이므로 이동 된 페이지와 request 영역을 공유 한다. 
    그리고 URL이 변경되지 않는다.
    --예제 코드( 포워드 하는 페이지) --
    <%
    pageContext.setAttribute("pAttr", "김유신"); 
    request.setAttribute("rAttr", "계백"); 
    %>
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>액션 태그 - forward</title>
    </head>
    <body>
        <h2>액션 태그를 이용한 포워딩</h2> 
        <jsp:forward page="/07ActionTag/ForwardSub.jsp" /> 
    </body>
    </html>
    --예제 코드( 포워드 되는 페이지 ForwardSub.jsp) --
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>액션 태그 - forward</title>
    </head>
    <body>
        <h2>포워드 결과</h2>
        <ul>
            <li>
                page 영역 : <%= pageContext.getAttribute("pAttr") %>
            </li>
            <li>
                request 영역 : <%= request.getAttribute("rAttr") %> 
            </li>
        </ul>
    </body>
    </html>

    4. <jsp:useBean>,<jsp:setProperty>,<jsp:getProperty>: 자바빈즈는 데이터를 저장하기 위한 멤버 변수(속성)과 세터/게터 메스드로만 이루어진 클래스

    ---자바빈즈의 개발 규약---
    • 자바빈즈는 기본 패키지 이외의 패키지에 속해 있어야 한다.
    • 멤버 변수(속성, 프로퍼티)의 접근 지정자는 private 으로 선언한다.
    • 기본 생성자가 있어야 한다.
    • 멤버 변수에 접근할 수 있는 게터/세터 메서드가 있어야 한다.
    • 게터/세터 메서드의 접근 지정자는 public 으로 선언한다.
    1) 자바빈즈 생성
    <jsp:useBean id="자바빈즈 이름" class="사용할 패키지와 클래스명" scope="저장될 영역" />
    • id: 자바빈지 객체의 이름을 지정한다. 같은 id로 이미 생성된 객체가 있다면 해당 객체를 사용하고, 아직 없다면 새로 생성한다.
    • class: 사용하려는 자바빈즈 객체의 실제 패키지명과 클래스명을 지정한다. 
    • scope: 자바빈즈가 저장될 내장 객체 영역을 지정한다. 생략하면 기본값인 page 영역이 지정된다. 
    2) 멤버 변수 값 설정
    <jsp:setProperty name="자바빈즈 이름" property="속성명(멤버 변수) value="설정할 값"/>
    • name: <jsp:uesBean>의 id 속성에 지정한 자바빈즈의 이름을 지정한다.
    • property: 자바빈즈의 멤버 변수명을 지정한다. 이름을 명시하는 대신 property="*" 라고 쓰면 form의 하위 요소와 일치하는 자바빈즈의 모든 속성에 전송한 값이 설정된다.
    • value: 멤버 변수에 설정할 값을 지정한다.
    3) 멤버 변수 값 추출
    <jsp:getProperty name="자바빈즈 이름" property="속성명(멤버 변수) />
    각 속성의 의미는 위와 같다.
    --예제코드--
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>액션 태그 - UseBean</title>
    </head>
    <body>
        <h2>useBean 액션 태그</h2>
        <h3>자바빈즈 생성하기</h3>
        <jsp:useBean id="person" class="common.Person" scope="request" />

        <h3>setProperty 액션 태그로 자바빈즈 속성 지정하기</h3>
        <jsp:setProperty name="person" property="name" value="임꺽정" /> 
        <jsp:setProperty name="person" property="age" value="41" /> 

        <h3>getProperty 액션 태그로 자바빈즈 속성 읽기</h3>
        <ul>
            <li>이름 : <jsp:getProperty name="person" property="name" /></li> 
            <li>나이 : <jsp:getProperty name="person" property="age" /></li> 
        </ul>
    </body>
    </html>

    5. <jsp:param> : 다른 페이지에 값을 전달해주는 액션 태그. 전달할 수 있는 값은 String 뿐. 다른 타입의 객체를 전달 할 때는 내장 객체의 영역을 이용해야 한다.

    1) 포워드 되는 페이지로 매개변수 전달하기
    <%
    request.setCharacterEncoding("UTF-8"); //한글 전달을 위해 UTF-8로 설정
    String pValue = "방랑시인";
    %>
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>액션 태그 - param</title>
    </head>
    <body>
        //request 영역에 저장할 자바빈즈 생성
        <jsp:useBean id="person" class="common.Person" scope="request" />

        //멤버 변수 name, age 값의 설정
        <jsp:setProperty name="person" property="name" value="김삿갓" /> 
        <jsp:setProperty name="person" property="age" value="56" /> 

        //ParamForward.jsp 으로 포워딩 하면서 쿼리 스트링으로 param1 매개변수 함께 전달
        <jsp:forward page="ParamForward.jsp?param1=김병연"> 
              //jsp:param 속성으로 param2와 param2 매개변수 전달
            <jsp:param name="param2" value="경기도 양주" />
            <jsp:param name="param3" value="<%=pValue%>" />
        </jsp:forward> 
    </body>
    </html>

    2) 포워드 되는 페이지 
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>액션 태그 - param</title>
    </head>
    <body>
         //이전 페이지에서 request 영역에 저장한 자바빈즈를 가져온다.
        <jsp:useBean id="person" class="common.Person" scope="request" /> 
        <h2>포워드된 페이지에서 매개변수 확인</h2>
        <ul>
            //멤버 변수 값을 가져와 출력한다.
            <li><jsp:getProperty name="person" property="name" /></li> 
            <li>나이 : <jsp:getProperty name="person" property="age" /></li>
            
            // 쿼리 스트링으로 전달된 매개 변수 출력
            <li>본명 : <%= request.getParameter("param1") %></li> 

            //<jsp:param> 액션 태그로 전달된 매개 변수 출력
            <li>출생 : <%= request.getParameter("param2") %></li>
            <li>특징 : <%= request.getParameter("param3") %></li>
        </ul>
    </body>
    </html>



    JSP 6강 - 세션(Session)

     1. 세션이란?

    클라이언트가 웹 브라우저를 통해 서버에 접속한 후, 용무를 처리하고, 웹 브라우저를 닫아 서버와의 접속을 종료하는 하나의 단위를 세션이라고 한다.

    세션은 웹 브라우저를 실행할 때마다 새롭게 생성된다. 설정된 유지 시간 동안 유지되며, 유지 시간이 만료되기 전에 새로운 요청이 들어오면 수명이 계속 연장된다.

    (예 - 은행 사이트는 보통 10분의 로그인을 유지하며 활동이 없으면 자동 로그아웃)

    유지 시간 이전이라도 웹 브라우저를 닫으면 세션는 종료 된다.(탭 종료는 유지 됨)


    2. 세션 설정, 확인, 삭제

    1) 유지 시간 설정 방법 2가지

    - /WEB-INF/web.xml 에서 설정법 

      <!-- 세션 유지 시간 설정(20분으로 설정) -->

      <session-config>

        <session-timeout>20</session-timeout>

      </session-config>

    -JSP 파일에서 session 내장 객체가 제공하는 setMaxInactiveInterval()을 사용

    <%

    session.setMaxInactiveInterval(1800); //1800초로 설정, 30분

    %>

    2) 세션 확인법

    <%@ page import="java.util.Date"%>

    <%@ page import="java.text.SimpleDateFormat"%>

    <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>

    <%

    SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");  // 날짜 표시 형식


    long creationTime = session.getCreationTime();  // 최초 요청(세션 생성) 시각

    String creationTimeStr = dateFormat.format(new Date(creationTime));


    long lastTime = session.getLastAccessedTime();  // 마지막 요청 시각

    String lastTimeStr = dateFormat.format(new Date(lastTime));

    %>

    <html>

    <head><title>Session</title></head>

    <body>

        <h2>Session 설정 확인</h2>

        <ul>

            <li>세션 유지 시간 : <%= session.getMaxInactiveInterval() %></li>

            <li>세션 아이디 : <%= session.getId() %></li>

            <li>최초 요청 시각 : <%= creationTimeStr %></li>

            <li>마지막 요청 시각 : <%= lastTimeStr %></li>

        </ul>

    </body>

    </html>

    3) 세션 삭제

    세션은 웹 브라우저를 닫으면 종료되지만, 웹 브라우저 설정에서 모든 쿠키를 삭제해 세션을 삭제할 수도 있다.


    3. 세션과 DB를 이용한 로그인 구현

    1) 로그인 페이지 구현

    <%@ page language="java" contentType="text/html; charset=UTF-8"

        pageEncoding="UTF-8"%>

    <html>

    <head><title>Session</title></head>

    <body>

    <jsp:include page="../Common/Link.jsp" />

        <h2>로그인 페이지</h2>

        <span style="color: red; font-size: 1.2em;"> 

            <%= request.getAttribute("LoginErrMsg") == null ?

                    "" : request.getAttribute("LoginErrMsg") %>

        </span>

        <%

        if (session.getAttribute("UserId") == null) {  // 로그인 상태 확인

            // 로그아웃 상태

        %>

        <script>

        function validateForm(form) {

            if (!form.user_id.value) {

                alert("아이디를 입력하세요.");

                return false;

            }

            if (form.user_pw.value == "") {

                alert("패스워드를 입력하세요.");

                return false;

            }

        }

        </script>

        <form action="LoginProcess.jsp" method="post" name="loginFrm"

            onsubmit="return validateForm(this);">

            아이디 : <input type="text" name="user_id" /><br />

            패스워드 : <input type="password" name="user_pw" /><br />

            <input type="submit" value="로그인하기" />

        </form>

        <%

        } else { // 로그인된 상태

        %>

            <%= session.getAttribute("UserName") %> 회원님, 로그인하셨습니다.<br />

            <a href="Logout.jsp">[로그아웃]</a>

        <%

        }

        %>

    </body>

    </html>

    2) DB 연동

    데이터를 주고 받기 위해서는 DTO 클래스와 테이블에 접근하기 위한 DAO 클래스를 만들어야 한다.

       - DTO(Data Transfer Object) 

    계층 사이에서 데이터를 교환하기 위해 생성하는 객체.

    별도의 로직 없이 속성(멤버 변수)와 그 속성을 접근하기 위한 게터/세터 메서드만 갖춘 객체.

       - DAO(Data Access Object) 

    데이터베이스의 데이터를 접근하기 위한 객체. 보통 JDBC를 통해 구현하며, 하나의 테이블에서 수행할 수 있는 CRUD를 전담. (CRUD - 생성, 읽기, 갱신, 삭제)

    --DTO 클래스 (DB와 동일하게 생성) --

    package membership;


    public class MemberDTO {

        // 멤버 변수 선언

        private String id;

        private String pass;

        private String name;

        private String regidate;


        // 멤버 변수별 게터와 세터

        public String getId() {

            return id;

        }

        public void setId(String id) {

            this.id = id;

        }

        public String getPass() {

            return pass;

        }

        public void setPass(String pass) {

            this.pass = pass;

        }

        public String getName() {

            return name;

        }

        public void setName(String name) {

            this.name = name;

        }

        public String getRegidate() {

            return regidate;

        }

        public void setRegidate(String regidate) {

            this.regidate = regidate;

        }

    }

    --DAO 클래스  --

    package membership;

    import common.JDBConnect;


    public class MemberDAO extends JDBConnect {

        // 명시한 데이터베이스로의 연결이 완료된 MemberDAO 객체를 생성합니다.

        public MemberDAO(String drv, String url, String id, String pw) {

            super(drv, url, id, pw);

        }


        // 명시한 아이디/패스워드와 일치하는 회원 정보를 반환합니다.

        public MemberDTO getMemberDTO(String uid, String upass) {

            MemberDTO dto = new MemberDTO();  // 회원 정보 DTO 객체 생성

            String query = "SELECT * FROM member WHERE id=? AND pass=?";  // 쿼리문 템플릿

            try {

                // 쿼리 실행

                psmt = con.prepareStatement(query); // 동적 쿼리문 준비

                psmt.setString(1, uid);    // 쿼리문의 첫 번째 인파라미터에 값 설정

                psmt.setString(2, upass);  // 쿼리문의 두 번째 인파라미터에 값 설정

                rs = psmt.executeQuery();  // 쿼리문 실행

                // 결과 처리

                if (rs.next()) {

                    // 쿼리 결과로 얻은 회원 정보를 DTO 객체에 저장

                    dto.setId(rs.getString("id"));

                    dto.setPass(rs.getString("pass"));

                    dto.setName(rs.getString(3));

                    dto.setRegidate(rs.getString(4));

                }

            }

            catch (Exception e) {

                e.printStackTrace();

            }

            return dto;  // DTO 객체 반환

        }

    }

    3) 로그인 처리 JSP 구현
    <%@ page import="membership.MemberDTO"%>
    <%@ page import="membership.MemberDAO"%>
    <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
    <%
    // 로그인 폼으로부터 받은 아이디와 패스워드
    String userId = request.getParameter("user_id"); 
    String userPwd = request.getParameter("user_pw");  

    // web.xml에서 가져온 데이터베이스 연결 정보
    String oracleDriver = application.getInitParameter("OracleDriver");
    String oracleURL = application.getInitParameter("OracleURL");
    String oracleId = application.getInitParameter("OracleId");
    String oraclePwd = application.getInitParameter("OraclePwd");

    // 회원 테이블 DAO를 통해 회원 정보 DTO 획득
    MemberDAO dao = new MemberDAO(oracleDriver, oracleURL, oracleId, oraclePwd);
    MemberDTO memberDTO = dao.getMemberDTO(userId, userPwd);
    dao.close();

    // 로그인 성공 여부에 따른 처리
    if (memberDTO.getId() != null) {
        // 로그인 성공
        session.setAttribute("UserId", memberDTO.getId()); 
        session.setAttribute("UserName", memberDTO.getName()); 
        response.sendRedirect("LoginForm.jsp");
    }
    else {
        // 로그인 실패
        request.setAttribute("LoginErrMsg", "로그인 오류입니다."); 
        request.getRequestDispatcher("LoginForm.jsp").forward(request, response);
    }
    %>

    4. 로그아웃 처리
    로그 아웃은 세션 영역에 저장된 로그인 관련 속성을 모두 지워주기만 하면 된다.
    속성을 지우는 방법은 두 가지다.

    <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
    <%
    // 방법 1: 회원 인증 정보 속성 삭제 
    session.removeAttribute("UserId");
    session.removeAttribute("UserName");

    // 방법 2: 모든 속성 한꺼번에 삭제 
    session.invalidate();

    // 속성 삭제 후 페이지 이동 
    response.sendRedirect("LoginForm.jsp");
    %>

    5. 쿠키 vs 세션

    ---쿠키---
    저장 위치/형식 : 클라이언트 PC에 text로 저장
    보안 : 클라이언트에 저장하여 보안에 취약
    자원 속도 : 서버 자원을 사용하지 않으므로 세션보다 빠름
    용량 : 용량의 제한이 있음
    유지 시간 : 쿠키 생성 시 설정함, 설정된 시간이 경과 되면 삭제

    ---세션---
    저장 위치/형식 : 웹 서버에 Object 타입으로 저장
    보안 : 서버에 저장되기에 보안에 안전
    자원 속도 : 서버 자원을 사용하여 쿠키보다 느림
    용량 : 서버가 허용하는 한 제한이 없음.
    유지 시간 : 서버의 web.xml에서 설정, 설정된 시간 내라도 동작이 있으면 삭제 되지 않고 유지