표현 언어(Expression Language) 란?

- 스크립트 요소의 사용 없이 JSP 페이지에 값을 표현할 수 있는 태그 기반의 스크립트 언어이다.

- 표현 언어는 JSP 2.0버전부터 추가되었다.

- JSP 2.2(Tomcat 7.0) 부터는 EL에서 객체의 메소드를 직접 접근 할 수 있는 기능이 추가 되었다.

- 표현 언어는 JSP의 스크립트 요소 (스크립트 릿, 표현식, 선언부)를 제외한 나머지 부분에서 사용될 수 있다.

- EL 2.0은 JSP 2.2(Tomcat 7.0), EL 3.0은 JSP 2.3(Tomcat 8.0)에서 지원한다.

 

기능

- JSP의 네 가지 기본 객체가 제공하는 영역의 속성 사용

page, request, session, application에 binding된 attribute나 그 attribute의 property 값 출력

- collection 객체에 대한 접근 방법 제공

- 수치 연산자, 관계 연산자, 논리 연산자 등의 EL연산자 제공

- 자바 클래스의 메소드 호출 기능 제공

- EL 내장 객체 제공

 

형식

${expression}

- 중괄호에 있는 표현식은 런타임에 평가되고 출력 스트림으로 전송된다. 

 

 

ch10

ex01 - 사칙연산 및 연산

더보기
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ page trimDirectiveWhitespaces="true"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="icon" href="data:;base64,iVBORw0KGgo=">
</head>
<body>

<h3>EL</h3>

<p>사칙연산</p>
<p> ${3+5} <!-- 8 : Long형 --> </p>
<p> ${3+"5"} <!-- 8 : Long형 --> </p>
<p> 3+null의 결과는 0 (null은 0으로 변환되어 연산) : Long형 --> </p>
<p> ${10/5} <!-- 2.0 : Double형 --> </p>
<p> ${13/5} <!-- 2.6 : Double형 --> </p>
<p> ${13 mod 5} <!-- 3 --> </p>
<p> ${13 % 5} <!-- 3 --> </p>
<p> EL에서는 "A"+"B" 처럼 문자열 결합을 하면 에러가 발생한다. </p>
<hr>

<p>비교/논리 연산</p>
<p> 3 == 4 : ${3==4 }, 3 eq 4 : ${3 eq 4 } </p>
<p> 3 != 4 : ${3 !=4 }</p>  <%-- 3 ne 4 : ${3 ne 4 } 이것도 됨 --%> 
<p> 3 lt 4 : ${3 lt 4 }, ${ 3<4 }</p>
<p> 3 gt 4 : ${3 gt 4 }, ${ 3>4 }</p>
<p> 3 le 4 : ${3 le 4 }, ${ 3<=4 }</p>
<p> 3 ge 4 : ${3 ge 4 }, ${ 3>=4 }</p>

<p> empty name : ${empty name}</p> <!-- 속성이름에 name이 없으므로 true -->
<!-- empty는 값이 null, 빈문자열, 길이가 0인 배열은 true -->

<p>  ${10%2==0?"짝수":"홀수" }</p>

<p> 기타 연산 </p>
<p> 문자열 결합 : +=, ${"서울" += "경기"}</p>
<p> 세미콜론연산자 - a;b 에서 a는출력 되지 않고 b만 출력</p>
<p> ${1+2; 2+5 } - 결과 : 7</p>
<p> 할당 연산자 : 할당연산 자체도 출력 </p>
<p> ${a=10 } ${a} - 결과 10 10</p>
<p> ${a=10; a } - 결과 : 10 </p>

</body>
</html>

 

ex02 EL 내장객체

더보기
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ page trimDirectiveWhitespaces="true"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="icon" href="data:;base64,iVBORw0KGgo=">
</head>
<body>

<h3>EL 내장 객체</h3>

<p> pageContext : 현재 페이지의 설정 정보</p>
<p> ContextPath : <%=request.getContextPath() %> </p>
<p> ContextPath : ${pageContext.request.contextPath } </p>
<hr>

<p> header : 요청 헤더 정보 </p>
<p> User-Agent : ${header["user-agent"]} </p>

</body>
</html>

 

ex03 - 객체 EL 로 표현

더보기
<%@ page import="ch10.user.User" %>
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ page trimDirectiveWhitespaces="true"%>
<%
	request.setCharacterEncoding("utf-8");

	User dto = new User("홍길동", 10, "010-1111-1111");
	request.setAttribute("vo", dto);
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="icon" href="data:;base64,iVBORw0KGgo=">
</head>
<body>

<jsp:forward page="ex03_ok.jsp">
	<jsp:param value="서울" name="city"/>
</jsp:forward>


</body>
</html>
<%@page import="ch10.user.User"%>
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ page trimDirectiveWhitespaces="true"%>
<%
	request.setCharacterEncoding("utf-8");
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="icon" href="data:;base64,iVBORw0KGgo=">
</head>
<body>

<!-- 
	EL의 주 사용 목적은 request, pageContext, session 등에서 
	설정한 속성(attribute)을 출력하기 위해 사용한다. 
-->

<h3>EL을 사용하지 않는 경우</h3>
<%
	User vv = (User)request.getAttribute("vo");
	String city = request.getParameter("city");
%>
	<!-- 필드의 값이 null인 경우 null로 출력 된다. -->
<p> <%=vv.getName() %>, <%=vv.getAge() %>, <%=vv.getTel() %>, <%=vv.getSubject() %></p>
<p> <%=city %> </p>

<h3>EL을 사용하는 경우</h3>
	<!-- 필드의 값이 null인 경우 아무것도 출력되지 않는다. -->
<p> ${vo.name}, ${vo.age}, ${vo.tel}, ${vo.subject } </p>

<!-- 파라미터는 param이라는 내장 객체 -->
<p> ${param.city} </p> <!-- request.getParameter("city"); 와 유사 -->

</body>
</html>

 


JSTL(JSP Standard Tag Library) 이란?

- JSP에서는 사용자가 태그를 정의해서 사용하는 것이 가능하며, 이런 사용자 정의 태그를 커스텀 태그라고 하는데 이들 중 자주 사용하는 것을 표준으로 만들어 놓은 것이 JSTL 이다.

- JSTL은 JSP의 공통적인 핵심 기능을 캡슐화한 태그 모음이다.

- JSTL은 반복(iteration) 및 조건문, XML문서 조작을 위한 태그, 국제화 태그 및 SQL 태그와 같은 일반적인 구조 작업을 지원한다.

- JSTL과 커스텀 태그 및 JSP액션태그는 XML 기반에서 작성이 되었기 때문에 모든 태그는 시작 태그와 종료 태그의 쌍으로 이루어져야 한다.

- 시간, 날짜, 숫자의 포맷이나 문자열 가공 등의 처리에서 비즈니스 로직과 프리젠테이션 로직을 분리할 수 있다.

- JSTL은 EL(Expression Language)를 사용하여 표현한다.

- JSTL 1.2버전은 Tomcat 6.0부터 사용 가능하다.

 

JSTL 사용을 위한 jar

- JSTL은 커스텀 태그의 일종으로 자바로 작성된 tag이므로 다음의 라이브러리가 필요하다.

- jstl-1.2.jar의 maven dependency

<!-- https://mvnrepository.com/artifact/javax.servlet/jstl -->

<dependency>

<groupId>javax.servlet</groupId>

<artifactId>jstl</artifactId>

<version>1.2</version>

</dependency>

 

taglib 지시어

- 사용자 정의 태그나 JSTL사용을 위한 태그 라이브러리를 지정한다.

- taglib 지시어는 사용자 정의 태그, JSTL의 라이브러리 위치를 식별하고 JSP 에서 사용자 정의 태그 및 JSTL을 식별하기 위한 방법을 선언한다.

- 형식

<%@taglib uri="uri" prefix = "prefixOfTag">

- 속성

uri : 태그 라이브러리 URI 또는 태그 라이브러리 디스크립터 파일의 URI

prefix : 사용자 정의 태그 접두사(태그를 식별하기 위한 이름)

- 사용 예

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

 

ex04 - core 태그 사용 c:if

더보기
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ page trimDirectiveWhitespaces="true"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%
	request.setCharacterEncoding("utf-8");
%>

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="icon" href="data:;base64,iVBORw0KGgo=">
</head>
<body>

<!-- form 태그에서 action을 생략하면 자신의 주소가 action이 된다. -->
<form method="post" action="ex04.jsp">
<p>
	<input type="text" name="num" placeholder="숫자" required="required" pattern="\d+">
	<button type="submit">확인</button>
</p>
</form>

<!-- c:if 태그는 조건이 참인 경우에 실행하며, else 구문은 존재하지 않는다. -->
<c:if test="${ not empty param.num }">
	<p>
		${param.num} : ${param.num % 2 == 0 ? "짝수":"홀수"}
	</p>
</c:if>

<c:if test="${ not empty param.num }">
	<p>
		<c:if test="${param.num%2==0}">
			짝수
		</c:if>
		<c:if test="${param.num%2==1}">
			홀수
		</c:if>
	</p>
</c:if>

</body>
</html>

 

ex05 - c:choose 다중 선택구문

더보기
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ page trimDirectiveWhitespaces="true"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="icon" href="data:;base64,iVBORw0KGgo=">
</head>
<body>

<h3>c:choose : 다중 선택 구문</h3>

<form action="ex05.jsp" method="post">
<p>
	<input type="text" name="num" placeholder="숫자" required="required" pattern="\d+">
	<button type="submit">확인</button>
</p>
</form>
<hr>

<c:if test="${not empty param.num }">
<p>
	<c:choose>
		<c:when test="${param.num%3==0 && param.num%4==0 and param.num !=0}">
			${param.num} : 3과 4의 배수
		</c:when>
		<c:when test="${param.num%3==0 && param.num !=0}">
			${param.num} : 3의 배수
		</c:when>
		<c:when test="${param.num%4==0 && param.num !=0}">
			${param.num} : 4의 배수
		</c:when>
		<c:otherwise>
			${param.num} : 3 또는 4의 배수가 아님
		</c:otherwise>
	</c:choose>
</p>
</c:if>

</body>
</html>

 

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="icon" href="data:;base64,iVBORw0KGgo=">
<style type="text/css">
*{
	padding: 0; margin: 0;
}

body {
    font-size:14px;
	font-family:"맑은 고딕", 나눔고딕, 돋움, sans-serif;
}

a {
	color: #000;
	text-decoration: none;
}
a:hover, a:active {
	color: tomato;
	text-decoration: underline;
}

.btn {
    color:#333;
    font-weight:500;
    border:1px solid #cccc;
    background-color:#fff;
    text-align:center;
    cursor:pointer;
    padding:3px 10px 5px;
    border-radius:4px;
}
.btn:active, .btn:focus, .btn:hover {
	 background-color:#e6e6e6;
	 border-color: #adadad;
	 color: #333;
}
.boxTF {
    border:1px solid #999;
    padding:4px 5px 5px;
    border-radius:4px;
    background-color:#fff;
}
.boxTA {
    border:1px solid #999;
    height:150px;
    padding:3px 5px;
    border-radius:4px;
    background-color:#fff;
    resize: none;
}

textarea:focus, input:focus {
	outline: none;
}

h3 {
	margin: 10px;
}

.box{
	width: 650px;
	margin: 30px auto;
}

.box table {
	width: 100%;
	border-collapse: collapse;
	border-spacing: 0;
}

.board-title {
	width:100%;
	height:50px;
	line-height:50px;
	text-align:left;
	font-weight: bold;
	font-size:15px;
}

.board-body tr:first-child{
	border-top: 3px solid #777;
}
.board-body tr {
	height: 40px;
	border-bottom: 1px solid #777;
}
.board-body td:first-child{
	text-align: center;
	width: 100px;
	background: #eee;
}

</style>

<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script type="text/javascript">
function sendOk() {
	var f = document.boardForm;
	
	// 유효성 검사
	var returnNow = false;
	var s;
	$("form input, form textarea").each(function() {
		if(! $(this).val().trim()) { // 공백까지 없애서 유효성 검사
			s = $(this).closest("tr").find("td:first-child").text();
			s = s.replace(/\s/g, '');
			
			alert(s + "을(를) 입력하세요 !!!");
			
			$(this).focus();
			returnNow = true;
			
			return false; // return false : each를 빠져나갈 수 있다. (break; 개념)
		}
	});
	
	if(returnNow) return;
	
	alert("보내기 성공...");
}
</script>

</head>
<body>

<h3>each - break 구현</h3>

<div class="box">
	<div class="board-title">
    	<h3><span>|</span> 게시판</h3>
	</div>
	
	<form name="boardForm" method="post">
	  <table class="board-body">
	  <tr> 
		  <td >제 목</td>
		  <td style="padding-left:10px;"> 
			<input type="text" name="subject" maxlength="100" class="boxTF" style="width: 97%;">
		  </td>
	  </tr>

	  <tr> 
		  <td>작성자</td>
		  <td style="padding-left:10px;"> 
			<input type="text" name="name" size="35" maxlength="20" class="boxTF">
		  </td>
	  </tr>

	  <tr> 
		  <td style="padding-top:5px;"  valign="top">내 용</td>
		  <td valign="top" style="padding:5px 0px 5px 10px;"> 
			<textarea name="content" cols="75" rows="12" class="boxTA" style="width: 97%;"></textarea>
		  </td>
	  </tr>

	  <tr>
		  <td>패스워드</td>
		  <td style="padding-left:10px;"> 
			   <input type="password" name="pwd" size="35" maxlength="7" class="boxTF">&nbsp;(게시물 수정 및 삭제시 필요 !!!)
		   </td>
	  </tr> 
	  </table>

	  <table>
		 <tr align="center"> 
		  <td height="45">
			  <button type="button" class="btn" onclick="sendOk();"> 등록하기 </button>
			  <button type="reset" class="btn"> 다시입력 </button>
			  <button type="button" class="btn"> 취소하기 </button>
		  </td>
		</tr>
	  </table>
	</form>
</div>

</body>
</html>

return false를 통해 each를 빠져나갈 수 있다.

1. append/appendTo, prepend/prependTo

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>메소드 연습 예제</title>
<link rel="icon" href="data:;base64,iVBORw0KGgo=">
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script type="text/javascript">
$(function() {
    // 마지막에 새로운 요소 추가
    $(".box1 ul").append("<li>C/C++</li>");
    $("<li>HTML 5</li>").appendTo(".box2 ul");

    // 첫 번째에 새로운 요소 추가
    $(".box3 ul").prepend("<li>JSP/Servlet</li>");
    $("<li>ORACLE</li>").prependTo(".box4 ul");
})

</script>

</head>
<body>

<h3>조작(Manipulation)</h3>

<div class="box box1">
    <ul>
        <li>자바</li>
        <li>스프링</li>
    </ul>
</div>

<div class="box box2">
    <ul>
        <li>javascript</li>
        <li>css</li>
    </ul>
</div>

<div class="box box3">
    <ul>
        <li>ASP.NET</li>
        <li>PHP</li>
    </ul>
</div>

<div class="box box4">
    <ul>
        <li>MariaDB</li>
        <li>MySQL</li>
    </ul>
</div>    

</body>
</html>

2. before, after

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>메소드 연습 예제</title>
<link rel="icon" href="data:;base64,iVBORw0KGgo=">
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script type="text/javascript">
$(function() {
    var a = 0, b = 0;

    $(".btn1").click(function () {
        $("p.p2").before("<p>앞-"+(++a)+"번째 문장 추가</p>");
    });

    $(".btn2").click(function () {
       $("p.p2").after("<p>뒤-"+(++b)+"번째 문장 추가</p>"); 
    });

});

</script>

</head>
<body>

<h3>조작(Manipulation)</h3>

<div style="margin: 20px;">
    <button type="button" class="btn btn1"> Node.js 앞에 추가 </button>
    <button type="button" class="btn btn2"> Node.js 뒤에 추가 </button>
</div>
<hr>

<p class="p1">자바스크립트</p>
<p class="p2">Node.js</p>
<p class="p3">vue.js</p>

</body>
</html>

3. wrap, wrapAll, wrapInner

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>메소드 연습 예제</title>
<link rel="icon" href="data:;base64,iVBORw0KGgo=">
<style type="text/css">
*{
    padding: 0; margin: 0;
}

body {
    font-size:14px;
    font-family:"맑은 고딕", 나눔고딕, 돋움, sans-serif;
}

a {
    color: #000;
    text-decoration: none;
}
a:hover, a:active {
    color: tomato;
    text-decoration: underline;
}

.btn{
    color:#333;
    font-weight:500;
    border:1px solid #ccc;
    background-color:#fff;
    text-align:center;
    cursor:pointer;
    padding:3px 10px 5px;
    border-radius:4px;
}

ul {
    list-style: none;
}
li{
    padding: 0;
}

h3{
    margin: 30px;
}

.box{
    box-sizing: border-box;
    width: 350px;
    min-height: 50px;
    margin: 20px auto;
    border: 3px dotted gray;
    padding: 15px; 
}

label {
    background: yellow;
}
</style>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script type="text/javascript">
$(function() {
   // p태그를 각각 새로운 div로 감싸기
   $(".btn1").click(function () {
       $("p").wrap("<div class='box'></div>");
   });

   // 모든 ul을 하나의 div로 감싸기. ul 사이에 p태그 등이 존재하면 모든 ul은 묶고 p 태그는 아래로 간다.
   $(".btn2").click(function () {
       $("ul").wrapAll("<div class='box'></div>");
   });

   // 선택한 요소 안을 감싸기
   $(".btn3").click(function () {
      $("p").wrapInner("<label></label>"); 
   });
});

</script>

</head>
<body>

<h3>조작(Manipulation)</h3>

<div style="margin: 20px;">
    <button type="button" class="btn btn1"> p 태그를 각 div로 감싸기 </button>
    <button type="button" class="btn btn2"> 모든 ul태그를 하나의 div로 감싸기 </button>
    <button type="button" class="btn btn3"> p 태그 안에 label 태그 추가 </button>
</div>
<hr>

<p>자바스크립트</p>
<p>CSS</p>
<hr>

<ul>
    <li>자바</li>
    <li>스프링</li>
</ul>

<h4>데이터베이스</h4>

<ul>
    <li>오라클</li>
    <li>MYSQL</li>
</ul>

</body>
</html>

4. clone

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>메소드 연습 예제</title>
<link rel="icon" href="data:;base64,iVBORw0KGgo=">

<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script type="text/javascript">
$(function() {
    $("ul li").click(function() {
		alert($(this).text());
	});
	
	$(".btn").click(function() {
		// box1의 ul을 복사하여 box2에 추가. 
		$(".box1 ul").clone().appendTo(".box2"); 
		// 이벤트는 복제되지 않음. 실행순서가 늦어서..
		
		// box3의 ul을 복사하여 box4에 추가. 이벤트도 복제
		$(".box3 ul").clone(true).appendTo(".box4");
	});
});

</script>

</head>
<body>
<h3>조작(Manipulation)</h3>
<div style="margin: 20px;">
    <button type="button" class="btn"> 복사하기 </button>
</div>
<hr>

<div class="box box1">
    <ul>
        <li>자바</li>
        <li>스프링</li>
        <li>파이썬</li>
    </ul>
</div>
<div class="box box2"></div>

<div class="box box3">
    <ul>
        <li>HTML</li>
        <li>javascript</li>
        <li>css</li>
    </ul>
</div>
<div class="box box4"></div>


</body>
</html>

 

Selector

DOM의 요소( element )를 선택.

 

DOM(Document Object Model)

- HTML 문서의 요소를 제어하기 위해 웹 브라우저에서 처음 지원

- DOM은 동적으로 문서의 내용, 구조, 스타일에 접근하고 변경하기 위한 방법

- 브라우저별로 DOM 구현이 호환되지 않음에 따라, W3C에서 DOM 표준 규격을 작성

 

기본 셀렉터

#id : 지정된 아이디를 가지는 엘리먼트와 일치하는 셀렉터.

element : 모든 <element> 엘리먼트와 일치하는 셀럭터(태그 등)

.class : 지정된 클래스명을 가지는 요소를 선택.

* : 모든 엘리먼트를 선택한다.

 

예제

더보기
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ page trimDirectiveWhitespaces="true"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="icon" href="data:;base64,iVBORw0KGgo=">
<style type="text/css">
* {
	padding: 0; margin: 0; box-sizing: border-box;
}
body {
	font-style: 14px;
	font-family: 맑은 고딕, 나눔고딕, 돋움, sans-serif;
}
a {
	color: #000; text-decoration: none;
}
a:hover, a:acrive {
	color: tomato; text-decoration: underline;
}
h3 {
	margin: 10px;
}

span, label {
	display: block;
}
.box {
	width: 350px; min-height: 50px; margin: 20px auto; padding: 15px;
	border: 3px dotted gray; 
}
</style>
<script type="text/javascript" src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script type="text/javascript">

// 실행 안됨. DOM이 준비 되지 않았으므로
// $("p").css("border", "1px solid #777");
	
// DOM이 로딩 되었을 때 실행
$(function() {
	// 모든 요소
	$("*").css({color:"#333", "font-size":"13px"}); 
	// {}는 자바스크립트에서 객체
	
	// 태그 선택자
	$("p").css("border","2px dashed #333");
	
	// id 선택자
	$("#layout1").css({width:'300px', padding:'10px', border:'2px solid green'});
	
	// class 선택자
	$(".red").css("color", "red");
	
	// AND
	$("label.underline").css("text-decoration", "underline");
	
	// 바로 아래 자식 하나
	$("div > label").css("color", "tomato");
	
	// 모든 자식(손자도 포함)
	$("div label").css("background", "#ff0");
	
	// 인접 형제. 바로 다음 형제 하나
	$("label + span").css("border", "1px dashed red")
	
	// 다음에 나오는 일반 형제
	$("label ~ span").attr("title", "과목");
	
});

</script>

</head>
<body>

<h3> selector</h3>

<div class="box">
	<div id="layout1">
		<label>프로그래밍</label>
		<span class="red">자바</span>
		<span>C언어</span>
		<span class="underline">코틀린</span>
		<p>
			<label class="red underline">데이터베이스</label>
			<span>오라클</span>
			<span>MySQL</span>
			<span>빅데이터</span>
		</p>
	</div>
	<div id="layout2">
		<label>웹</label>
		<span>HTML</span>
		<span>CSS</span>
		<span>JavaScript</span>
		<p>
			<label>웹프로그래밍</label>
			<span>JSP</span>
			<span>PHP</span>
			<span>ASP.NET</span>
		</p>
		<p>
			<span>React</span>
			<label>기타</label>
			<span>jQuery</span>
		</p>
	</div>
	
</div>
</body>
</html>
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ page trimDirectiveWhitespaces="true"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="icon" href="data:;base64,iVBORw0KGgo=">
<style type="text/css">
* {
	padding: 0; margin: 0; box-sizing: border-box;
}
body {
	font-style: 14px;
	font-family: 맑은 고딕, 나눔고딕, 돋움, sans-serif;
}
a {
	color: #000; text-decoration: none;
}
a:hover, a:acrive {
	color: tomato; text-decoration: underline;
}
h3 {
	margin: 10px;
}

.box {
	width: 350px; min-height: 50px; margin: 20px auto; padding: 15px;
	border: 3px dotted gray; 
}

.box span, .box label {
	display: block;
}

</style>
<script type="text/javascript" src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script type="text/javascript">

// 실행 안됨. DOM이 준비 되지 않았으므로
// $("p").css("border", "1px solid #777");
	
// DOM이 로딩 되었을 때 실행
$(function() {
	// span 태그의 글자색을 tomato로
	$("span").css("color", "tomato");
	
	// span 태그와 label 태그의 글자에 밑줄
	$("span, label").css("text-decoration", "underline");
	
	// div1 아이디의 글자색을 blue
	$("#div1").css("color", "blue");
	
	// div2 아이디의 글자를 진하게
	$("#div2").css("font-weight", "700");
	
	// c1 클래스의 배경색을 yellow로
	$(".c1").css("background", "yellow");
	
	// input 요소 중 name=subject인 요소
	$("input[name=subject]").css("background", "#eee");
	
	// form의 input 요소 중 name 속성을 가진 요소
	$("form input[name]").css("border", "none");
	
	// form의 input 요소 중 type=text와 type=password인 요소
	$("form input[type=text], form input[type=password]").css("border-bottom", "1px solid blue");
	
	// form의 input 요소 중 name 속성 값이 'a'로 시작하는 요소
	$("form input[name^=a]").css("border-right", "3px solid red");
	
	// form의 input 요소 중 title 속성 값이 '버튼'으로 끝나는 요소
	$("form input[title$='버튼']").css("border-left", "3px solid black");
	
	// form의 input 요소 중 name 속성 값이 'x'가 포함된 요소
	$("form input[name*=x]").css("border-left", "3px solid black");
	
	// form의 input 요소 중 title 속성 값에 '내용'이라는 단어(띄어쓰기 구분)가 들어간 요소
	$("form input[title~='내용']").css("background", "yellow");
	
	
});

</script>

</head>
<body>

<h3> selector</h3>

<div class="box">
	<div id="div1">테스트 1</div>	
	<div id="div2" class="c1">테스트 2</div>
	<span>테스트 3</span>
	<span>테스트 4</span>
	<div id="div3" class="c1">테스트 5</div>
	<span class="c1">테스트 6</span>
	<span class="c2">테스트 7</span>
</div>
<hr>

<div class="box">
	<p> <input type="text" name="subject" title="과목 입력"> </p>
	<form>
		<p> <input type="text" name="subject" title="과목 입력"> </p>
		<p> <input type="text" name="ax1" title="1장 제목 입력"> </p>
		<p> <input type="text" name="as2" title="1장 내용 입력"> </p>
		<p> <input type="text" name="bs1" title="2장 제목 입력"> </p>
		<p> <input type="text" name="bx2" title="2장 내용 입력"> </p>
		<p> <input type="password" name="pwd" title="패스워드 입력"> </p>
		<p> <input type="file" name="selectFile"> </p>
		<p>
			<input type="button" value="입력완료" title="입력 버튼">
			<input type="reset" value="다시입력" title="리셋 버튼">
		</p>
	</form>
</div>

</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="icon" href="data:;base64,iVBORw0KGgo=">
<style type="text/css">
*{
	padding: 0; margin: 0;
}

body {
    font-size:14px;
	font-family:"맑은 고딕", 나눔고딕, 돋움, sans-serif;
}

a {
	color: #000;
	text-decoration: none;
}
a:hover, a:active {
	color: tomato;
	text-decoration: underline;
}

h3 {
	margin: 10px;
}

.btn {
	color:#333;
	font-weight:500;
	border:1px solid #ccc;
	background-color:#fff;
	text-align:center;
	cursor:pointer;
	padding:3px 10px 5px;
	border-radius:4px;
	font-family:"Malgun Gothic", "맑은 고딕", NanumGothic, 나눔고딕, 돋움, sans-serif;
}
.btn:active, .btn:focus, .btn:hover {
	background-color:#e6e6e6;
	border-color: #adadad;
	color: #333;
}

textarea:focus, input:focus{
	outline: none;
}
.boxTF {
	border:1px solid #999;
	padding:3px 5px 5px;
	border-radius:4px;
	background-color:#fff;
	font-family:"Malgun Gothic", "맑은 고딕", NanumGothic, 나눔고딕, 돋움, sans-serif;
}

.box{
	box-sizing: border-box;
	width: 500px;
	min-height: 50px;
	margin: 20px auto;
	border: 3px dotted gray;
	padding: 15px; 
}
</style>

<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script type="text/javascript">
$(function() {
	$("form input + span").hide();
	$("form input[type=text]").css("border", "1px solid #aaa");
	
	// focus 이벤트. button 제외
	$("form input").not($(":button")).focus(function() {
		$(this).css("border", "1px solid #f28011");
		// 이벤트를 발생시킨 바로 다음 형제중 span 태그
		$(this).next("span").show();
	});
	
	// blur 이벤트. button 제외
	$("form input").not($(":button")).blur(function() {
		$(this).css("border", "1px solid #aaa");
		// 이벤트를 발생시킨 바로 다음 형제중 span 태그
		$(this).next("span").hide();
	});
});

</script>

</head>
<body>

<h3>selectors 예제</h3>

<div class="box">
<form>
	<p>
		<input type="text" name="id">
	    <span>아이디 입력.</span>
	    <span>5~10자 이내</span>
	</p>
	<p>
		<input type="text" name="name">
		<span>이름 입력.</span>
	</p>
	<p>
		<input type="text" name="age">
		<span>나이 입력.</span>
	</p>
	<p>
		<input type="text" name="birth">
		<span>생년월일 입력.</span>
	</p>
	<p style="padding: 5px;">
	<!-- 
		<button type="button" class="btn"> 등록하기 </button>
		<button type="button" class="btn"> 등록취소 </button>
	-->
		<input type="button" class="btn" value="등록하기">		
		<input type="button" class="btn" value="등록취소">		
	</p>
</form>
</div>

</body>
</html>

focus 이벤트에서 button을 제외

blur이벤트에서 button을 제외

 

이외 filter 가 여러가지 있음. 

 

선택된 요소 접근 메소드

더보기
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="icon" href="data:;base64,iVBORw0KGgo=">
<style type="text/css">
*{
	padding: 0; margin: 0;
}

body {
    font-size:14px;
	font-family:"맑은 고딕", 나눔고딕, 돋움, sans-serif;
}

a {
	color: #000;
	text-decoration: none;
}
a:hover, a:active {
	color: tomato;
	text-decoration: underline;
}

.btn{
    color:#333;
    font-weight:500;
    border:1px solid #ccc;
    background-color:#fff;
    text-align:center;
    cursor:pointer;
    padding:3px 10px 5px;
    border-radius:4px;
}

ul {
	list-style: none;
}
li{
	padding: 0;
}

h3{
	margin: 30px;
}

.box{
	box-sizing: border-box;
	width: 350px;
	min-height: 50px;
	margin: 20px auto;
	border: 3px dotted gray;
	padding: 15px; 
}
</style>

<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script type="text/javascript">
$(function() {
	$(".btnOk").click(function() {
		// var name = $(".std").html(); // html 소스 반환(innerHTML 속성)
		var name = $(".std").text(); // 텍스트만 반환
		
		// 속성값 가져오기
		var num = $(".std").attr("data-num");
		
		// document.getElementById("score").value = 90;
		$("#score").val(90); // value 속성에 값 설정
		
		// value 속성 값 가져오기
		var subject = $("#subject").val();
		var score = $("#score").val();
		
		var s = "<p>학번 : <b>" + num + "</b></p>";
		s +="<p>이름 : <b>" + name + "</b></p>";
		s +="<p>과목 : <b>" + subject + "</b></p>";
		s +="<p>점수 : <b>" + score + "</b></p>";
		
		// 텍스트 설정
		// $("#layout").text(s);
		
		// html 콘텐츠 설정
		$("#layout").html(s);
		
	});
	
})

/*
-- 선택된 요소 접근 
  .html() : 해당 요소의 HTML 콘텐츠를 반환하거나 설정한다.
  .text() : 해당 요소의 텍스트 콘텐츠를 반환하거나 설정한다.
  .val() : <form>요소의 값을 반환하거나 설정한다
  .attr() : 해당 요소의 명시된 속성의 속성값을 반환하거나 설정한다.
  .width() : 선택한 요소 중에서 첫 번째 요소의 너비를 픽셀 단위의 정수로 반환하거나 설정한다.
  .height() : 선택한 요소 중에서 첫 번째 요소의 높이를 픽셀 단위의 정수로 반환하거나 설정한다.
  .position() : 선택한 요소 중에서 첫 번째 요소에 대해 특정 위치에 존재하는 객체를 반환한다.(getter 메소드)

-- 메소드 체이닝(method chaining)
  여러 개의 메소드가 연속으로 호출되는 것
  예 : $("ul").find("li").eq(1).append("자바");
*/
</script>

</head>
<body>

<h3>선택된 요소 접근</h3>
<div style="margin: 20px;">
	<button type="button" class="btn btnOk"> 확인 </button>
</div>
<hr>

<div class="box">
	<p>
		<!-- data-* : 개발자에 의해 만들어진 속성 -->
	    <span class="std" data-num="1"><b>홍길동</b></span>
	</p>
	<p> <input type="text" id="subject" value="자바"> </p>
	<p> <input type="text" id="score"> </p>
</div>

<div class="box">
	<p>결과</p>
	<div id="layout"></div>
</div>

</body>
</html>

jQeury 개요

- jQuery는 빠르고 간결한 JavaScript Library 이다.

- HTML document traversing(탐색), 이벤트 처리, 애니메이션, AJAX를 단순화하여 빠른 웹 개발을 가능하게 한다.

- 다양한 브라우저 지원

- 경량 파일(90kb 수준의 파일크기)

- CSS3 규격 지원

- 존 레식에 의해 개발

 

jQuery를 사용하기 위한 라이브러리 포함

<script type="text/javascript" src="jquery-1.12.4.min.js"></script> 

 

CDN(Content Delivery Network)을 이용 jQuery 라이브러리 포함

<script src="http://code.jquery.com/jquery-3.6.0.min.js"></script>

 

core 예제

더보기
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ page trimDirectiveWhitespaces="true"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="icon" href="data:;base64,iVBORw0KGgo=">

<script type="text/javascript" src="https://code.jquery.com/jquery-3.6.0.min.js"></script>

<script type="text/javascript">
// DOM이 로드 될 때 실행
/*
// 이벤트 핸들러 프로퍼티 방식
// 테스트-2 만 실행
window.onload = function() {
	console.log("테스트-1");
};

window.onload = function() {
	console.log("테스트-2");
};
*/

/*
// addEventListener
// 둘 다 실행
window.addEventListener("load", function() {
	console.log("테스트-1");
});
window.addEventListener("load", function() {
	console.log("테스트-2");
});
*/
/*
// jquery를 이용한 실행
// 둘 다 실행
jQuery(document).ready(function() {
	console.log("테스트-1")
});
jQuery(document).ready(function() {
	console.log("테스트-2")
});
*/
/*
// jQuery(document).ready(function(){}); 의 짧은 표현
jQuery(function(){
	console.log("테스트-1");
});
jQuery(function(){
	console.log("테스트-2");
});
*/
/*
// jQuery === $
$(function(){
	console.log("테스트-1");
});
$(function(){
	console.log("테스트-2");
});
*/
/*
$(document).ready(function() {
	// DOM 객체만 로드 되면 바로 실행
	console.log("테스트-1");
});
$(window).on("load", function() {
	// 해당 페이지의 모든 외부 리소스(이미지, css 등)가 로드 된 후 실행
	// $(function(){}); 보다 느림
	console.log("테스트-2");
})
*/

$(function() {
	$(document.body).css("background", "#eee");
});
</script>

</head>
<body>

<h3> jQuery Core 예제</h3>
<p>
  jQuery( elements ), $( elements )
</p>

<p>
  $() = $(document).ready() = jQuery() = jQuery(document).ready()
</p>

</body>
</html>

 

 

파일업로드를 위한 <form> 태그

<form> 태그의 enctype 속성

- <form> 태그 안에 정의된 요청 파라미터를 클라이언트에서 서버로 전송할 때 인코딩 방법을 지정한다.

- HTTP 헤더의 Content-Type 을 지정하여 서버에 어떤 종류의 데이터가 전송되는지를 전달한다.

- method="post"인 경우에만 이 속성은 유효하다.

- 속성 값

1) application/x-www-form-urlencoded

기본 enctype 속성으로 요청 파라미터는 key1=value1&key2=value2 형태로 나열된다.

공백은 +, 영숫자가 아닌 문자는 %HH(문자코드의 16진수 2자리)로 인코딩하여 전송한다.

이 content type은 바이너리 데이터(파일 등) 전송에서는 사용할 수 없다.

2) multipart/form-data

문자 인코딩을 하지 않고 전송되며, 파일을 전송할 때 사용한다.

여러 형태의 데이터 (파일 내용, 텍스트 입력 값 등)가 동시에 전달되며 각 데이터는 boumdary=...(경계정보) 뒤에 붙은 문자열을 이용하여 구분한다.

3) text/plain 

공백이 +문자로 변환되며 특수 문자를 인코딩 하지 않는다.

 

예제 (ch09)

더보기

ex01

<%@ page contentType="text/html; charset=UTF-8"%>
<%@ page trimDirectiveWhitespaces="true"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="icon" href="data:;base64,iVBORw0KGgo=">
</head>
<body>

<h3>파일 업로드</h3>
<%--
  - form 태그에서 enctype을 생략하면 기본이 application/x-www-form-urlencoded
  - application/x-www-form-urlencoded 속성 값은 파라미터를 주소형식으로 인코딩하여 전송
    파라미터는 "이름1=값1&이름=값2" 형태로 body영역에 실어서 전송된다.
  - application/x-www-form-urlencoded 속성 값에서 파일을 서버로 전송하면 파일 이름만 전송 된다.
  - enctype 속성은 method가 post인 경우만 유효
 --%>

<form action="ex01_ok.jsp" method="post" >
<p> 제목 : <input type="text" name="subject"> </p>
<p> 파일 : <input type="file" name="selectFile"> </p>
<p>
	<button type="submit">등록하기</button>
</p>

</form>

</body>
</html>

ex01_ok

<%@ page contentType="text/html; charset=UTF-8"%>
<%@ page trimDirectiveWhitespaces="true"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%
	request.setCharacterEncoding("utf-8");
	
	// request.getParameter()는 문자열만 전달 받는다.
	String subject = request.getParameter("subject");
	// 파일은 enctype="application/x-www-form-urlencoded" 에서는 이름만 전송 받는다.
	String selectFile = request.getParameter("selectFile");
%>

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="icon" href="data:;base64,iVBORw0KGgo=">
</head>
<body>

<h3>요청 받은 정보</h3>

<p>제목 : <%= subject %> </p>
<p>파일 : <%=selectFile %> </p>

</body>
</html>

 위 예제를 통해서 파일을 전달 받지 못하는 것을 알 수 있다. 파일의 이름만을 받았음.

 

ex02

<%@ page contentType="text/html; charset=UTF-8"%>
<%@ page trimDirectiveWhitespaces="true"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="icon" href="data:;base64,iVBORw0KGgo=">
</head>
<body>

<h3>파일 업로드</h3>
<%--
  * form 태그에서 enctype이 multipart/form-data인 경우
    - 문자 인코딩을 하지 않고 전송하며, 파일을 전송할 때 사용
    - 피일의 내용도 전송된다.
  * enctype 속성은 method가 post인 경우만 유효
  
 --%>

<form action="ex02_ok.jsp" method="post" enctype="multipart/form-data">
<p> 제목 : <input type="text" name="subject"> </p>
<p> 파일 : <input type="file" name="selectFile"> </p>
<p>
	<button type="submit">등록하기</button>
</p>

</form>

</body>
</html>

ex02_ok

<%@page import="java.net.URLDecoder"%>
<%@page import="java.io.InputStream"%>
<%@page import="java.util.Enumeration"%>
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ page trimDirectiveWhitespaces="true"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%
	request.setCharacterEncoding("utf-8");
	
	// enctype="multipart/form-data"로 넘어온 파라미터는 request.getParameter()로 받을 수 없다.
	// String subject = request.getParameter("subject");
	// String selectFile = request.getParameter("selectFile");
	
	
%>

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="icon" href="data:;base64,iVBORw0KGgo=">
</head>
<body>

<h3>요청 받은 정보</h3>

<%
	String contentType = request.getContentType();
	out.print("<p>contentType : " + contentType + "</p>");
	out.print("<hr>");
	
	out.print("<h3>[[헤더 정보들]]....</h3>");
	Enumeration<String> e = request.getHeaderNames();
	while(e.hasMoreElements()) {
		String name = e.nextElement();
		String value = request.getHeader(name);
		out.print("<p>" + name + " : " + value + "</p>");
	}
	out.print("<hr>");
	
	out.print("<h3>[[request Body 영역으로 넘어온 데이터]]</h3>");
	
	InputStream is = request.getInputStream();
	byte[] buf = new byte[2048];
	int size;
	String str;
	while( (size = is.read(buf)) != -1) {
		// enctype = "application/x-www-form-urlencoded" 인 경우
		// str = new String(buf, 0, size);
		// str = URLDecoder.decode(str, "utf-8");
		
		// enctype = "nultipart/form-data" 인 경우
		str = new String(buf, 0, size, "utf-8");
				
		out.print("<p>" + str + "</p>");
	}
	out.print("<hr>");
	
%>

</body>
</html>

파일이 넘어왔음을 알 수 있다.

 

cos.jar을 이용한 업로드 (권장하지 않음)

<%@ page contentType="text/html; charset=UTF-8"%>
<%@ page trimDirectiveWhitespaces="true"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="icon" href="data:;base64,iVBORw0KGgo=">
</head>
<body>

<h3>파일 업로드</h3>
<%--
  * cos.jar를 이용한 업로드
    http://servlets.com 
 --%>

<form action="ex03_ok.jsp" method="post" enctype="multipart/form-data">
<p> 제목 : <input type="text" name="subject"> </p>
<p> 파일 : <input type="file" name="selectFile"> </p>
<p>
	<button type="submit">등록하기</button>
</p>

</form>

</body>
</html>
<%@page import="com.oreilly.servlet.multipart.DefaultFileRenamePolicy"%>
<%@page import="com.oreilly.servlet.MultipartRequest"%>
<%@page import="java.io.File"%>
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ page trimDirectiveWhitespaces="true"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%
	request.setCharacterEncoding("utf-8");

	// String root = pageContext.getServletContext().getRealPath("/"); 도 가능
	String root = session.getServletContext().getRealPath("/");
	String pathname = root + "uploads" + File.separator + "pds";
	File f= new File(pathname);
	if(! f.exists() ) {
		f.mkdirs();	
	}
	
	String encType = "utf-8"; // 클라이언트가 보낸 정보의 인코딩
	int maxFileSize = 5*1024*1024; // 최대 업로드 용량(5MB)
	
	MultipartRequest mreq = null;
				// request, 파일저장경로, 파일최대크기, 인코딩, 중복파일명보호
	mreq = new MultipartRequest(request, pathname, maxFileSize, encType, 
			new DefaultFileRenamePolicy() );
	
	// 제목 
	String subject = mreq.getParameter("subject");
	
	// 서버에 저장된 파일 이름
	String saveFilename = mreq.getFilesystemName("selectFile");
	
	// 클라이언트가 올린 파일 이름
	String originalFilename = mreq.getOriginalFileName("selectFile");
	
	// 파일 크기
	long fileSize = 0;
	File file = mreq.getFile("selectFile"); // 업로드된 파일에 대한 File 객체
	if(file != null) {
		fileSize = file.length();
	}
	

%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="icon" href="data:;base64,iVBORw0KGgo=">
</head>
<body>

<h3>파일 업로드 결과 : cos.jar</h3>

<p> 제목 : <%=subject%> </p>
<p> 클라이언트가 올린 파일 이름 : <%=originalFilename %></p>
<p> 서버에 저장된 파일 이름 : <%=saveFilename %></p>
<p> 파일 크기 : <%=fileSize %>byte.</p>


</body>
</html>

 

세션이란 ? 

- 둘 이상의 page request에서 사용자를 식별하거나, 웹 사이트를 방문하고 해당 사용자에 대한 정보를 저장하는 방법을 제공한다.

- Servlet container는 HttpSession을 사용하여 Http client - HTTP server간의 세션을 생성한다.

- 세션은 한 명의 사용자에 해당한다. (브라우저 당 하나의 세션 객체가 생성된다.)

- 서버는 Cookie, rewriting URL과 같은 방법으로 세션을 유지하면서 관리할 수 있다.

- 객체를 세션에 바인딩하여 사용자 정보를 유지할 수 있다.

 

톰캣의 세션 동작 원리

- session.isNew() 메소드는 세션이 생성된 곳에서 아직 클라이언트가 세션 ID를 모르는 상태(최초 접속 상태)의 경우 "true"를 반환한다.

- 이 경우 아직 클라이언트 정보가 서버에 유지되지 않기 때문에, 서버는 Response Headers에 JSESSIONID 이라는 이름으로 쿠키 정보를 client로 전달한다.

- session.isNew() 메소드는 "false"를 반환하면 이미 세션이 설정되어있는 경우이며, 이 경우 client브라우저는 로컬에 저장되어 있는 JSESSIONID 쿠키 값을 request header에 담아 서버로 전송한다.

- 서버는 client로 부터 JSESSJIONID 쿠키 값을 전달 받으면 response로 JSESSIONIS 쿠키 값을 client로 보내지 않는다.

더보기
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ page trimDirectiveWhitespaces="true"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="icon" href="data:;base64,iVBORw0KGgo=">
</head>
<body>

<h3> 세션 동작 원리 </h3>

<!-- isNew() :  클라이언트가 세션 ID를 모르는 상태(최초 접속)인 경우 true를 반환 --%>
<!-- isNew()가 true를 반환하면 클라이언트 정보가 서버에 저장되지 않은 상태이다. -->
<p> isNew() : <%= session.isNew() %></p>
<hr>

<h4>쿠키 내용</h4>
<%
	Cookie[] cc = request.getCookies();
	if(cc != null) {
		for(Cookie c : cc) {
			String name = c.getName();
			String value = c.getValue();
			out.print("<p>"+name+" : "+ value + "</p>");
		}
	}
%>

</body>
</html>

 

쿠키를 사용하지 않는 세션 ID의 관리

- 휴대 기기 등 모든 단말이 쿠키를 사용할 수 있는 것은 아니다.

- 쿠키를 사용할 수 없는 경우 URL에 직접 세션 ID를 작성하여 세션 ID를 클라이언트 측에 유지시킨다.

구체적으로는 HttpServletResponse의 encodeURL (String url) 메소드를 사용한다.

PrintWriter writer = response.getWriter();

String link = "/main";

link = response.encodeURL(link);

writer.println("<a href = '"+link+"'>메인</a>");

encodeURL() 메소드를 사용하면 지정된 인수에 대해 다음의 값을 추가하며, 쿠키를 사용 못해도 클라이언트측에서 세션 ID를 보유할 수 있다.

jsessionid = 세션id

 

예제

더보기

sessionEx2

<%@ page contentType="text/html; charset=UTF-8"%>
<%@ page trimDirectiveWhitespaces="true"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="icon" href="data:;base64,iVBORw0KGgo=">
</head>
<body>

<h3>session : 클라이언트의 정보를 서버에 저장</h3>
<!-- 세션은 일반적으로 로그인 처리 등에서 이용된다. -->

<p>
  <a href="sessionSet.jsp">세션 설정</a> |
  <a href="sessionInfo.jsp">세션 확인</a> |
  <a href="sessionRemove.jsp">세션 제거</a>
</p>
</body>
</html>

sessionSet

<%@ page contentType="text/html; charset=UTF-8"%>
<%@ page trimDirectiveWhitespaces="true"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%
	// session : 세션을 나타내는 JSP 내장 객체(HttpSession)
	// 서블릿에서 세션 객체 구하기 : HttpSession sess = request.getSession();
	// EL에서의 세션 객체 : sessionScope
	
	// 세션 유지시간 설정(톰캣 기본 세션 유지시간 : 30분)
	session.setMaxInactiveInterval(60*20); // 단위 : 초
	
	session.setAttribute("name", "홍자바");
	session.setAttribute("age", 20);
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="icon" href="data:;base64,iVBORw0KGgo=">
</head>
<body>

<h3>session 설정</h3>

<p>
	<a href="sessionEx2.jsp">돌아가기</a>
</p>

</body>
</html>

sessionInfo

<%@page import="java.util.Date"%>
<%@page import="java.text.SimpleDateFormat"%>
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ page trimDirectiveWhitespaces="true"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%
	String name = "";
	int age = 0;
	
	try {
		// 세션에 설정한 값 가져오기
		name = (String)session.getAttribute("name");
		age = (Integer)session.getAttribute("age");
	} catch(Exception e) {
	}
	
	// 세션 유지시간
	int interval = session.getMaxInactiveInterval();
	
	// 세션 아이디
	String id = session.getId();
	
	SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
	
	// 세션 생성 시간
	Date date1 = new Date(session.getCreationTime());
	String create_date = sdf.format(date1);
	
	// 세션 마지막 접속 시간
	Date date2 = new Date(session.getLastAccessedTime());
	String last_date = sdf.format(date2);
	
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="icon" href="data:;base64,iVBORw0KGgo=">
</head>
<body>

<h3>session 정보</h3>

<p> 이름과 나이 : <%=name%>, <%=age%> </p>
<p> EL을 이용하여 세션 값 가져오기 : ${sessionScope.name}, ${sessionScope.age}</p>
<p> 세션 최대 유지시간 : <%=interval / 60 %>분 </p>
<p> 세션 아이디 : <%=id%></p>
<p> 세션 생성 시간 : <%=create_date %></p>
<p> 세션 마지막 접속 시간 : <%=last_date %></p>
<hr>

<p>
	<a href="sessionEx2.jsp">돌아가기</a>
</p>

</body>
</html>

sessionRemove

<%@ page contentType="text/html; charset=UTF-8"%>
<%@ page trimDirectiveWhitespaces="true"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%
	// 세션에 저장된 속성값 지우기
	session.removeAttribute("name");
	session.removeAttribute("age");
	
	// 세션에 저장된 모든 속성값을 지우고 세션을 초기화
	session.invalidate();
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="icon" href="data:;base64,iVBORw0KGgo=">
</head>
<body>

<h3> session 지우기</h3>

<p>
	<a href="sessionEx2.jsp">돌아가기</a>
</p>

</body>
</html>

 

 

 

쿠키란?

- 쿠키는 클라이언트에 대한 정보를 클라이언트의 하드디스크에 저장한 text파일

- 쿠키는 텍스트 형태로 저장되기 때문에 변조, 복사 가능하여 보안성이 없다.

- 쿠키는 서버에서 사용자에게 편리한 기능을 제공하기 위해 많이 사용되고, 웹 브라우저에 의해 관리된다.

- 일반적으로 브라우저는 각 웹 서버 당 20개의 쿠키와 총 300개의 쿠키를 지원하며 쿠키 크기는 각각 4kb로 제한될 수 있다.

- 쿠키 정보는 javax.servlet.http.Cookie클래에 의해 관리 된다.

 

쿠키 설정하기

1) Cookie 객체를 생성한다. 생성자에 문자열로 쿠키이름과 값을 설정한다.

- 형식

 Cookie cookie = ew Cookie("key", "value");

- 이름과 값은 영수자와. 공백이나 다음 문자를 포함할 수 있다.

[] () = , " / ? @ : ;

2) setMaxAge(초) 메소드를 이용하여 쿠키 유효 기간을 초단위로 설정한다.

- 유료 기간을 설정하지 않으면 브라우저가 종료될 때까지 쿠키가 지속됨을 나타내는 -1 이다.

- 다음은 쿠키 유효시간을 24시간으로 설정한 예이다.

cookie.setMaxAge(60*60*24);

3) HTTP응답 헤더에 쿠키를 보낸다.

- HttpServletResponse 인터페이스의 addCookie() 메소드에 의해 HTTP 응답 헤더에 쿠키를 보낸다.

- JSP에서 쿠키를 설정하는 방법은 다음과 같다.

response.addCookie(cookie);

 

Cookie 유효 시간 설정

- setMaxAge(int expiry)메소드를 이요하여 유효시간 초 단위로 설정한다.

- expiry

음수 : 브라우저가 종료되면 쿠키가 제거된다.

0: 생성과 동시에 제거

양수 : 초 단위로 해당 시간만큼 유지된다.

설정하지 않은 경우 : 디폴트로 -1이 설정되어 브라우저가 종료할 때 까지 유효하다.

 

Cookie 설정 시 주의 사항

- 쿠키의 이름이나 값에 한글 등이 포함되는 경우 다음과 같이 java.net 패키지의 URLEncoder.encode()메소드를 이용하여 주소 형식으로 인코딩해야한다.

Cookie cookie = new Cookie("key", URLEncoder.encode("값", "utf-8");

- Cookie의 유효범위를 설정하지 않는 경우. 쿠키를 설정하는 페이지의 경로와 하위 경로에서만 접근가능하다. 

따라서 모든 경로에서 쿠키의 값을 반환 받을 경우에는 다음과 같이 유효 범위를 "/"로 설정한다.

cookie.setPath("/");

 

Cookie 가져오기 및 제거

- Cookie 가져오기

1) 쿠키를 가져오기 위해서는 HttpServletRequest 인터페이스의 getCookies()메소드를 이용해서 가져온다.

- getCookies() 메소드는 javax.servlet.http.Cookie객체의 배열을 반환한다.

- JSP 에서 쿠키 가져오기

Cookie []ck = request.getCookies();

2) 반환 받은 Cookie객체의 getName() 과 getValue() 메소드를 이용하여 쿠키를 가져 온다.

String name, value;
	if( ck!=null) {
		for(Cookie c : ck) {
			name = c.getName();
			value = c.getValue();
            			:
		}
	}

 

- Cookie 제거하기

쿠키 값을 제거하기 위해서는 쿠키에 대한 값을 지우고 유효기간을 만료시킨다.

JSP 에서 쿠키 제거 방법

Cookie cookie = new Cookie("제거할쿠키이름",null) // 쿠키 값 지우기

cookie.setMaxAge(0); // 유효시간 만료

response.addCookie(cookie): // HTTP 응답 헤더에 제거할 쿠키를 보낸다.

 

확인용 예제

더보기

cookieEx

<%@ page contentType="text/html; charset=UTF-8"%>
<%@ page trimDirectiveWhitespaces="true"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="icon" href="data:;base64,iVBORw0KGgo=">
</head>
<body>

<h3>cookie 예제</h3>

<p>
	<a href="setCookie.jsp">쿠키설정</a>
	<a href="getCookie.jsp">쿠키확인</a>
	<a href="removeCookie.jsp">쿠키제거</a>
</p>

</body>
</html>

setCookie

<%@page import="java.net.URLEncoder"%>
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ page trimDirectiveWhitespaces="true"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%
	// 쿠키 설정 : 서버가 클라이언트 컴퓨터에 정보를 저장
	// 쿠키의 유효시간을 설정하지 않으면(life cycle), 브라우저가 종료되면 쿠키도 제거된다.
	Cookie c1 = new Cookie("subject", "java"); // 쿠키이름, 쿠키값 생성자를 이용해서 객체생성. 쿠키는 String만 가능
	response.addCookie(c1);
	
	Cookie c2 = new Cookie("subject2", "spring");
	c2.setMaxAge(60 * 60); // 1시간 : 쿠키 유효시간(단위 : 초)
	response.addCookie(c2);
	
	// 한글을 쿠키로 설정할 경우에는 반드시 인코딩
	Cookie c3 = new Cookie("subject3", URLEncoder.encode("오라클", "utf-8") );
	c3.setMaxAge(-1); // -1 : 브라우저가 종료되면 쿠키도 제거
	response.addCookie(c3);
	
	// 쿠키는 기본적으로 쿠키를 설정한 경로에서만 접근할 수 있다.
	Cookie c4 = new Cookie("tel", "010-1111-1111");
	c4.setPath("/"); // 모든 경로에서 쿠키를 접근 할 수 있도록 설정
	response.addCookie(c4);
	
	Cookie c5 = new Cookie("age", "20"); // 쿠키는 문자열만 가능하다. 숫자도 따옴표형식으로 넣어야함.
	c5.setMaxAge(0); // 쿠키 생성과 동시에 제거(일반적으로 쿠키를 제거할 때 사용)
	response.addCookie(c5);
	
	
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="icon" href="data:;base64,iVBORw0KGgo=">
</head>
<body>

<h3> 쿠키 설정 </h3>
<p>
	<a href="cookieEx.jsp">돌아가기</a>
</p>

</body>
</html>

getCookie

<%@page import="java.net.URLDecoder"%>
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ page trimDirectiveWhitespaces="true"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="icon" href="data:;base64,iVBORw0KGgo=">
</head>
<body>

<h3>쿠키 가져오기 : 클라이언트 컴퓨터에 저장된 쿠키를 서버로 가져오기</h3>
<%
	Cookie[] cc = request.getCookies(); // 쿠키는 배열로 가져올 수 있따.
	if( cc != null ) {
		for(Cookie c:cc){
			String name = c.getName(); // 쿠키 이름
			String value = c.getValue(); // 쿠키 값
			if(name.equals("subject3")) {
				value = URLDecoder.decode(value, "utf-8");
			}
			
			out.print("<p>" + name + " : " + value + "</p>");
		}
	}
%>
<hr>

<p>
	<a href="cookieEx.jsp">돌아가기</a>
</p>

</body>
</html>

 

p1

<%@page import="java.net.URLEncoder"%>
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ page trimDirectiveWhitespaces="true"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%
	Cookie c = new Cookie("sname1", URLEncoder.encode("컴퓨터", "utf-8") );
	response.addCookie(c);
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="icon" href="data:;base64,iVBORw0KGgo=">
</head>
<body>

<h3>컴퓨터</h3>
<p> 컴퓨터중 최고의 성능</p>
<p> 제조사 : 삼성 </p>
<p> 가격 : 1,000,000 </p>
<hr>
<p><a href="shop.jsp">돌아가기</a></p>
</body>
</html>

p2

<%@page import="java.net.URLEncoder"%>
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ page trimDirectiveWhitespaces="true"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%
	Cookie c = new Cookie("sname2", URLEncoder.encode("핸드폰", "utf-8") );
	response.addCookie(c);
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="icon" href="data:;base64,iVBORw0KGgo=">
</head>
<body>

<h3>핸드폰</h3>
<p> 핸드폰중 최고의 성능</p>
<p> 제조사 : 삼성 </p>
<p> 가격 : 1,200,000 </p>
<hr>
<p><a href="shop.jsp">돌아가기</a></p>
</body>
</html>

p3

<%@page import="java.net.URLEncoder"%>
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ page trimDirectiveWhitespaces="true"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%
	Cookie c = new Cookie("sname3", URLEncoder.encode("노트북", "utf-8") );
	response.addCookie(c);
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="icon" href="data:;base64,iVBORw0KGgo=">
</head>
<body>

<h3>노트북</h3>
<p> 노트북중 최고의 성능</p>
<p> 제조사 : 삼성 </p>
<p> 가격 : 1,500,000 </p>
<hr>
<p><a href="shop.jsp">돌아가기</a></p>
</body>
</html>

+ Recent posts