👻 현재 JSP 페이지의 특정 영역에 외부 파일의 내용을 포함하는 태그 ➡️ 포함할 수 있는 외부 파일은 HTML, JSP, 텍스트 파일 등 👻 include 디렉티브 태그는 서블릿 프로그램으로 번역될 때 현재 JSP 페이지와 설정된 다른 외부 파일의내용이 병합되어 번역 👻 머리글과 바닥글 같은 공통된 부분을 별도의 JSP 파일로 만들어 웹 페이지를 모듈화 할 수 있다. ➡️ 코드를 재사용하고 중복된 코드를 줄임으로써 유지 보수 측면에서 매우 유용
include 디렉티브 태그를 사용하는 이유
외부파일의 내용(예: header, footer)을 복사하여 현재 JSP 페이지에 붙여넣을 수 있지만 이는 좋은 방법이 아니다. 예를 들어 머리글과 바닥글에 해당하는 외부 파일 2개와 100개의 JSP페이지가 있는 경우 JSP 페이지 100개에 외부 파일 2개의 내용을 복사하여 붙여넣었을 때 이 외부 파일의 내용을 변경해야 한다면JSP 페이지 100개를 모두 수정 편집해야 한다.
하지만 include 디렉티브 태그를 사용하면 모든 외부 파일을 포함하므로 외부 파일의 내용을 변경할 때마다 특정 외부 파일만 수정 편집하면 된다.
예를 들어 하나의 프로젝트에서 다수의 JSP 페이지가 동일한 설정을 사용할 경우에 모든 페이지에 다 코딩을 할 수 있고 하나의 페이지에 설정 코드를 넣고 인클루드 해서 사용할 수 있다. 모든 페이지에 동일한 코드를 넣는 경우 특정 페이지의 오타 or 설정을 변경해야 하는 경우작업이 번거로워 진다. 하나의 페이지에 설정 코드를 넣고 인클루드 해서 사용하면 오타에 자유롭고 + 설정을 변경해야 하는 경우에 간편하다.
<body>
<%@ include file="_header.jsp"%>
<p>방문해 주셔서 감사합니다.</p>
<%@ include file="_footer.jsp"%>
</body>
// _header.jsp 파일
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<h4>헤더 페이지 영역입니다.</h4>
// _footer.jsp 파일
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<footer>Copyright .JSP</footer>
2. taglib 디렉티브 태그
👻 현재 JSP 페이지에 표현 언어, JSTL, 사용자 정의 태그 custom tag 등 태그 라이브러리를 설정하는 태그
<%@ taglib uri="경로" prefix="태그 식별자" %>
⚡️ uri 속성은 사용자가 정의한 태그의 설정 정보를 가진 경로 주소 ⚡️ prefix 속성은 uri에 설정한, 사용자가 정의한 태그를 식별하기 의한 고유 이름 ▶️ 해당 JSP 페이지 내에서 uri속성 값을 그대로 사용하면 복잡하므로 prefix 속성 값이 대신 식별할 수 있게 해주는 것
👻 taglib 디렉티브 태그가 서블릿 프로그램으로 번역될 때 uri 속성 값은 JSP컨테이너에 사용자가 정의한 태그 라이브러리의 위 치를 알려줌. prefix 속성 값은 사용자가 정의한 태그 라이브러리의 접두어 태그가 무엇인지 JSP 컨테이너에 알려주는 역할.
JSTL 태그
유용한 JSP 태그의 모음인 JSTL은 자주 사용되는 핵심 기능을 제공. 반복문, 조건문과 같은 논리적 구조 작업, XML 문서 조작, 국제화 태그 조직, SQL 조작 수행을 위한 태그를 지원. JTSL을 사용하려면 WebContent/WEB-INF/lib 디렉터리의 위치에 jstl.jar 라이브러리 파일이 있어야 함. Apache Standard Taglib 페이지에서 다운로드 가능.
JSP 페이지가 서블릿 프로그램에서 서블릿 클래스로 변환할 때 JSP 페이지와 관련된 정보를 JSP 컨테이너에 지시하는 메시지. 따라서 디렉티브 태그는 JSP 페이지를 수정하여 다시 컴파일하는 경우에만 역할을 수행하기 때문에 개별 HTML 응답에 특별한 영향을 미치지 않음
태그
형식
설명
page
<%@ page ... %>
JSP 페이지에 대한 정보를 설정
include
<%@ include ... %>
JSP 페이지의 특정 영역에 다른 문서를 포함
taglib
<%@ taglib ... %>
JSP 페이지에서 사용할 태그 라이브러리를 설정
1) page 디렉티브 태그
🚀 JSP 페이지가 생성할 콘텐츠 유형의 문서, 사용할 자바 클래스, 오류 페이지 설정, 세션 사용 여부, 출력 버퍼의 존재 유무 등과 같이 JSP 컨테이너가 JSP 페이지를 실행하는데 필요한 정보를 설정
🚀 일반적으로 JSP 페이지의 최상단에 선언하는 것을 권장
🚀 <@ 사이에는 공백을 주지 말것
page 디렉티브 태그의 속성
속성
설명
기본값
language
현재 JSP 페이지에서 사용할 프로그래밍 언어를 설정
java
contentType
현재JSP 페이지의 콘텐츠유형을 설정
text/html
pageEncoding
현재 JSP 페이지의 문자 인코딩 유형을 설정
ISO-8859-1
import
현재 JSP 페이지에서 사용할 자바 클래스를 설정
session
현재 JSP 페이지의 HTTP 세션 사용 여부를 설정
true
buffer
현재 JSP 페이지의 출력 버퍼를 설정
8KB
autoFlush
자동으로 출력 버퍼를 비우는 것을 제어하는데 사용
true
isThreadSafe
현재 JSP 페이지에서 멀티스레드의 동작을 제어하는 데 사용
true
info
현재 JSP 페이 지에 대한 설명 을 설정
errorPage
현재 JSP 페이 지가 실행되는 동안 오류가 발 생하면 특정 오류 페이지로 이동하는 데 사용
isErrorPage
현재 JSP 페이지가 오류 페이지인지 여부를 설정
isELIgnored
현재 JSP 페이지의 표현 언어 Expression Language 사용 여부를 설정
false
isScripting
스크립트 태그 (선언문, 스크립틀릿, 표현문) 사용 여부를 설정
📍 하나의 page 디렉티브 태그에 하나 또는 여러 개의 속성을 설정 또는 여러 개의 속성마다 개별적으로 page 디렉티브 태그를 선언할 수 있음. import 속성을 제외한 속성은 JSP 페이지에 한 번씩만 설정할 수 있음
1) 서블릿 : 자바로 html 표현하는 것 (자바와 html 결합) 처음엔 자바코드에서 html을 출력
📍 단점: html 작업이 힘들다
2) JSP : PHP의 영향으로 html 코드에 자바가 들어감. 서블릿과 반대
📍 단점: 규모가 큰 프로젝트에서는 구조화된 작업이 힘들다. → 유지보수 어려움
3) JSP + 서블릿을 이용한 MVC 패턴 : controller와 model은 servlet으로, view는 jsp로 작업
📍 단점 : 구조화된 프로그래밍은 가능한데, 규모가 더 커지니 코드가 복잡하고 성능 저하
💡 자바 서블릿 (Java Servlet)은 자바를 사용하여 웹페이지를 동적으로 생성하는 서버측 프로그램 혹은 그 사양을 말하며, 흔히 "서블릿"이라 불린다. 자바 서블릿은 웹 서버의 성능을 향상하기 위해 사용되는 자바 클래스의 일종이다. 서블릿은 JSP와 비슷한 점이 있지만, JSP가 HTML 문서 안에 Java 코드를 포함하고 있는 반면, 서블릿은 자바 코드 안에 HTML을 포함하고 있다는 차이점이 있다.
서버 측 실행 언어 : 서버에서 실행되는 언어. JSP, PHP, ASP, 파이썬, node.js
2. 스크립트 태그 Script Tag
태그
형식
설명
선언문declaration
<!% ... %>
자바 변수나 메소드를 작성
스크립틀릿 scriptlet
<% ... %>
자바 로직 코드 작성
표현문expression
<%= ... %>
선언문의 변수, 메소드, 계산식을 호출하여 문자열로 출력
1) 선언문 태그 declaration
<%! 자바 코드; %>
🚀 변수나 메소드 등을 선언하는 태그
🚀 선언문 태그에 선언된 변수와 메서드는 서블릿 프로그램으로 번역될 때 _jspService() 메소드 외부에 배치되므로 JSP 페이지 임의의 위치에서 선언할 수 있음
🚀 스크립틀릿 태그보다 나중에 선언해도 스크립틀릿 태그에서 사용할 수 있음
🚀 선언문 태그로 선언된 변수는 서블릿 프로그램으로 번역될 때 클래스 수준의 멤버 변수가 되므로 전역 변수로 사용
변수 선언
<body>
<%--선언문 태그 사용 예 : 전역변수 선언--%>
<%!
int count = 0; // 전역변수 count를 0으로 초기화
%>
Page Count is
<%
out.println(++count); // 전역변수 1 증가. 새로 고침을 하면 숫자가 증가.
%>
</body>
메소드 선언
<body>
<%-- 선언문 태그에 전역 메서드 사용하기 --%>
<%-- 전역 메서드 sum()을 선언하기 위해 선언문 태그를 작성 --%>
<%!
int sum(int a, int b) {
return a + b;
}
%>
<%-- 결과 값 출력을 위해 스크립틀릿 태그를 작성 --%>
<%
out.println("2 + 3 = " + sum(2, 3)); // 선언문 태그에 선언된 전역 메서드 sum() 호출.
%>
</body>
2) 스크립틀릿 태그 scriptlet
<% 자바 코드; %>
🚀 자바 코드로 이루어진 로직 부분을 표현
🚀 스크립틀릿 태그는 가장 일반적으로 사용되며 변수 또는 메소드 호출, 유효식 등을 포함할 수 있음
🚀 모든 텍스트, HTML 태그, 또는 JSP 요소는 스크립틀릿 태그 외부에 있어야 함
🚀 스크립틀릿 태그에 작성된 자바 코드는 서블릿 프로그램으로 변환될 때 _jspService() 메소드 내부에 복사
➡️ 각 클라이언트의 요청에 대해_jspService() 메소드가 호출되므로 이 메소드의 내부 코드가 클라이언트의 요청마다 실행
➡️ _jspService() 메소드 내부에 복사되므로 지역변수가 되어 이 태그에 선언된 변수는 스크립틀릿 태그 내에서만 사용
지역 변수 선언
<body>
<%
int count = 0; // 지역 변수 선언
%>
Page Count is
<%
out.println(++count); // 지역 변수 1 증가.
%>
</body>
👩🏻💻 맵은 키 Key와 값 Value의 쌍으로 입력되는 컬렉션 👩🏻💻 맵의 키는 리스트의 인덱스와 비슷한데 맵에는 키를 직접 입력하고 중복되지 않도록 해야 함
⚡️ 제네릭으로 키와 값의 데이터 타입을 지정해서 맵을 생성 ⚡️ 맵의 요소는 Pair(A, B)를 사용하는 데 이는 A to B로도 표현할 수 있음
// 읽기 전용 맵
val immutableMap = mapOf("name" to "tom", "age" to 28, "age" to 20, "height" to 170)
println(immutableMap) // {name=tom, age=20, height=170} 중복이 있을 경우 마지막 키값이 저장됨
자바에서 리스트 List, 셋 Set, 맵 Map 등 여러 자료 구조를 사용하는데, 코틀린에서도 이러한 컬렉션을 모두 사용할 수 있을 뿐만 아니라 몇 가지 편리한 함수를 추가로 제공. 또한 코틀린은 컬렉션을 읽기 전용 immutable 컬렉션과 읽기-쓰기 mutable 컬렉션으로 크게 두 가지로 나눔
1) 리스트 List
👻 리스트 List는 저장되는 데이터에 인덱스를 부여한 컬렉션이며 중복된 값을 입력할 수 있음 👻 코틀린에서 동적으로 리스트를 사용하기 위해서는 리스트 자료형 앞에 뮤터블 Mutable 이라는 접두어 prefix가 붙음 💫 접두어가 있는 리스트도 있지만 잘 사용하지 않기 때문에 항상 mutableList, mutableMap, mutableSet을 사용
뮤터블과 이뮤터블
프로그래밍 언어에서 뮤터블은 변할 수 있는 데이터 타입을 가르키는 용어. 변수로는 var이 뮤터블 그리고 반대 개념인 이뮤터블 Immutable이 있는데 이것은 val과 같이 변할 수 없는 데이터 타입을 가르키는 용어.
⚡️ 코틀린은 컬렉션 데이터 타입을 설계할 때 모두 이뮤터블로 설계 ⚡️ 기본 컬렉션인 리스트, 맵, 셋은 모두 한 번 입력된 값을 바꿀 수 없음 ⚡️ 컬렉션의 원래 용도인 동적 배열로 사용하기 위해서는 뮤터블로 만들어진 데이터 타입을 사용해야 함
읽기 전용 리스트는 listOf() 함수를 사용 읽기 쓰기 모두 가능한 리스트는 mutableListOf() 함수를 사용
// 뮤터블
val mutableList = mutableListOf("MON", "TUE", "WED")
// 3개의 값을 가진 크기가 3인 동적 배열 리스트가 생성
2) 리스트에 값 추가하기 : add
👻 mutableList 변수에 add 메서드를 사용해서 값을 추가 👻 값이 추가되면서 동적으로 리스트의 공간이 자동으로 증가
mutableList.add("THU")
// 입력될 위치인 인덱스를 따로 지정해주지 않아도 입력되는 순서대로 인덱스가 지정.
println(mutableList)
// [MON, TUE, WED, THU]
3) 리스트에 입력된 값 사용하기 : get
👻 입력할 때와는 다르게 사용할 때는 인덱스를 지정해서 몇 번째 값을 꺼낼 것인지 명시
var variable = mutableList.get(1) // 두 번째 값을 변수에 저장
variable = mutableList[1]
println(variable) // TUE
4) 리스트 값 수정하기 : set
👻 특정 인덱스 값을 수정
mutableList.set(1, "수정할 값") // 두 번째 값을 수정
println(mutableList) // [MON, 수정할 값, WED, THU]
mutableList[1] = "수정할 값" // 두 번째 값을 수정.
5) 리스트에 입력된 값 제거하기 : removeAt
👻 리스트에 입력된 값의 인덱스를 지정해서 삭제
println(mutableList.get(1)) // 수정할 값
mutableList.removeAt(1) // 두 번째 값을 삭제
// 두 번째 값을 삭제하면 세 번째 값부터 인덱스가 하나씩 감소하면서 빈자리의 인덱스로 이동
println(mutableList.get(1)) // WED
6) 빈 리스트 사용하기
👻 아무것도 없는 빈 리스트를 생성하면 앞으로 데이터 타입을 알 수 없기 때문에 값의 타입을 추론할 수 없음 👻 빈 컬렉션의 경우 앞에서처럼 '데이터타입of'만으로는 생성되지 않고 데이터 타입을 직접적으로 알려주는 방법을 사용해야 함
var 변수명 = mutableListOf<컬렉션에 입력될 값의 타입>() var stringList = mutableLisfOf<String>()
// 생성
val stringList = mutableListOf<String>() // 문자열로 된 빈 컬렉션을 생성
stringList.add("월")
stringList.add("화")
println(stringList[1]) // 화
7) 컬렉션 개수 가져오기 : size
👻 size 프로퍼티를 사용하면 컬렉션의 개수를 가져올 수 있음
println("stringList에는 ${stringList.size}개의 값이 있습니다.")
// stringList에는 2개의 값이 있습니다.
예제
문자열을 저장할 수 있는 List 객체를 생성하고 여기에 "a", "b", "c", "d", "e"를 저장한 후 이것을 출력하는 프로그램을 생성 출력 예: [a, b, c, d, e]