3. JSP 프로그래밍
JSP는HTML안에 필요한 동적 처리를 함께 적어서 화면을 만들 수 있게 해 주는 서버 기술이다.
겉으로 보면 화면 파일처럼 보이지만, 실제로는 서버에서 실행된 뒤 그 결과를 브라우저에 보내는 프로그램이다.
즉,JSP는 화면을 더 쉽게 작성할 수 있게 만든 서버 쪽 표현 기술이라고 이해하면 된다.
이 단원에서는JSP가 무엇인지부터 먼저 잡고, 왜Servlet과 함께 배워야 하는지, 서버 안에서 어떤 흐름으로 처리되는지를 차례대로 정리한다.
그다음JSP태그를 큰 분류로 나누어 보고,page지시자,include지시자, 선언문 태그, 표현식 태그, 스크립트릿 태그, 액션 태그, 내장 객체까지 자연스럽게 이어서 본다.
초보자 기준에서는 태그 문법만 외우는 것보다, 화면처럼 보이는 코드가 서버 안에서 실제로 어떤 프로그램 흐름으로 바뀌는지 이해하는 것이 더 중요하다.
특히JSP는Servlet과 완전히 다른 기술이 아니다.
작성 방식이 다를 뿐, 요청을 받아 서버에서 실행되고 응답을 만든다는 큰 원리는 같다.
이 기준이 잡혀야 뒤에서 나오는request,session,out,errorPage,include,forward같은 개념도 덜 헷갈린다.
3-1. JSP란 무엇인가
JSP는HTML문서 안에Java코드와JSP태그를 넣어서 동적인 화면을 만드는 기술이다.
즉, 화면 파일처럼 보이지만 실제로는 서버에서 실행되는 페이지다.
JSP를 처음 보면HTML과 비슷해서 그냥 화면 파일처럼 느껴질 수 있다.
하지만 실제로는 브라우저가JSP파일 자체를 실행하는 것이 아니라, 서버가JSP를 처리한 뒤 만들어 낸 결과만 브라우저에 보내 준다.
그래서JSP는 화면처럼 작성하지만 서버 프로그램처럼 동작하는 기술이라고 이해해야 한다.
JSP는 어떤 기술인가
JSP는 정적인 문서처럼 보이는HTML안에, 실행할 때마다 달라질 수 있는 부분만 서버 쪽 코드로 넣는 방식이다.
예를 들어 현재 시간, 요청값, 계산 결과처럼 실행 시점에 따라 달라지는 내용을 화면에 보여 줄 수 있다.
즉,JSP의 핵심은 화면과 동적 처리를 한 파일 안에서 함께 다룰 수 있다는 점이다.
- 화면의 기본 구조는
HTML처럼 작성한다.- 바뀌어야 하는 부분만
Java코드나JSP태그로 처리한다.- 서버가 그 결과를 만든 뒤 브라우저에 최종 화면만 보낸다.
중요한 점은 브라우저가
JSP소스 자체를 받는 것이 아니라, 서버가 실행해서 만든 결과만 받는다는 점이다.
이 기준이 먼저 잡혀야JSP를 단순한 화면 파일로 오해하지 않게 된다.
정적인 페이지와동적인 페이지의 차이정적인 페이지는 미리 만들어 둔 내용을 그대로 보여 주는 페이지다.
누가 접속하든 거의 같은 내용을 보여 주는 안내문, 소개 페이지가 여기에 가깝다.
반대로 동적인 페이지는 요청한 시점이나 사용자 상황에 따라 내용이 달라진다.
현재 날짜와 시간, 로그인한 사용자 이름, 전달된 입력값, 계산 결과 같은 내용이 대표적이다.
즉, 차이는 이렇게 이해하면 쉽다.
- 정적인 페이지는 미리 만든 내용을 그대로 전달한다.
- 동적인 페이지는 서버가 실행 시점에 결과를 만들어 전달한다.
그래서
JSP는 단순히 문서를 보여 주는 기술이 아니라, 서버가 그때그때 화면을 만들어 주는 기술이라고 이해해야 한다.
왜
HTML만으로는 부족한가
HTML만으로는 고정된 화면을 만드는 데는 충분하다.
하지만 사용자 입력에 따라 결과가 달라져야 하거나, 서버에서 계산한 값을 화면에 넣어야 하면HTML만으로는 처리할 수 없다.
예를 들어 사용자가 입력한 이름을 다시 보여 주거나, 현재 시간을 출력하거나, 전달된 숫자로 계산 결과를 보여 주는 것은 서버 쪽 처리가 필요하다.
이때 사용하는 기술이JSP다.
즉,JSP는HTML을 대체하는 기술이 아니라,HTML만으로 처리할 수 없는 동적인 부분을 서버에서 채워 넣는 기술이다.
왜 화면 작성에 유리한가
Servlet도 동적인 화면을 만들 수 있다.
하지만Servlet은 자바 코드 안에서HTML을 문자열로 출력하는 방식이 많아서, 화면이 길어질수록 읽기가 불편해진다.
반면JSP는 기본 틀을HTML처럼 그대로 작성할 수 있다.
그래서 어떤 화면이 나올지 코드만 봐도 더 쉽게 읽힌다.
즉,JSP의 장점은 기능이 많다는 데 있지 않고, 화면 구조와 동적 처리를 비교적 읽기 쉽게 함께 작성할 수 있다는 점에 있다.
- 화면 구조가 눈에 잘 보인다.
- 필요한 곳에만 동적 처리를 넣으면 된다.
- 처리 코드와 화면 구조의 연결을 따라가기 쉽다.
그래서 초보자 입장에서는 같은 서버 처리라도
JSP가 화면 중심으로 더 읽기 쉬운 방식이라고 이해하면 된다.
예제로 보면 어떤 느낌인가
아래 예제는
JSP가 어떤 식으로 사용되는지 가장 단순하게 보여 준다.
화면 구조는HTML로 만들고, 현재 시간처럼 실행할 때마다 달라지는 값은 표현식 태그로 출력하고 있다.<!-- exam1.jsp --> <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" import="java.time.LocalDateTime" %> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>JSP 학습 예제 1</title> </head> <body> <h1>JSP 맛보기</h1> <hr> <h3>현재 시간 정보 : <%= LocalDateTime.now() %></h3> <!-- 현재 시간을 화면에 출력 --> </body> </html>이 예제에서 바뀌지 않는 화면 틀은
HTML이 맡고 있다.
반대로 현재 시간처럼 실행할 때마다 달라질 수 있는 값은<%= %>안에서 출력한다.
즉,JSP는 정적인 문서 안에 동적인 값을 자연스럽게 끼워 넣는 구조다.
출력 결과는 아래와 같다.
현재 시간을 표현식 태그로 출력하면 실행 시점의 값이 화면에 표시된다.
여기서 먼저 잡아야 할 핵심
이 구간에서 먼저 기억해야 할 것은 아래 세 가지다.
JSP는HTML처럼 보여도 서버에서 실행되는 기술이다.JSP는 동적인 화면을 만들기 위한 기술이다.- 화면은
HTML처럼 작성하고, 바뀌는 부분만 서버 쪽 코드로 처리한다.이 기준이 잡혀야 뒤에서
Servlet과의 관계, 처리 구조, 태그 종류도 자연스럽게 이어진다.
3-2. 왜 JSP가 필요했는가
JSP가 왜 필요한지 이해하려면 먼저Servlet과 비교해서 보는 것이 가장 쉽다.
Servlet도 동적인 화면을 만들 수 있다.
하지만 화면을 만드는 방식이 불편했기 때문에, 화면 작성에 더 적합한 형태로 나온 기술이JSP다.
즉,JSP는Servlet이 못 하는 일을 새로 만드는 기술이라기보다, 같은 서버 처리 흐름을 화면 중심으로 더 읽기 쉽게 작성하도록 만든 기술이라고 이해하면 된다.
왜
Servlet만으로는 불편했는가
Servlet에서는 보통 자바 코드 안에서HTML을 문자열로 직접 출력한다.
즉, 제목 하나를 보여 주는 것도, 문단 하나를 보여 주는 것도, 표나 목록을 만드는 것도 전부 출력문 안에서 처리해야 한다.
처음에는 간단해 보여도 화면이 조금만 길어지면 바로 복잡해진다.
어디까지가 자바 코드인지, 어디부터가 실제 화면 구조인지 한눈에 보기 어려워진다.
큰따옴표, 줄바꿈, 태그 출력이 계속 섞이기 때문에 초보자 입장에서는 화면을 만드는 느낌보다 문자열을 조립하는 느낌이 더 강해진다.
- 화면 구조가 코드에서 바로 보이지 않는다.
HTML태그를 문자열처럼 출력해야 해서 읽기가 불편하다.- 처리 로직과 화면 출력이 한곳에 섞여서 가독성이 떨어진다.
즉,
Servlet은 서버 처리에는 강하지만, 화면을 길게 작성할수록 불편함이 커지는 구조라고 볼 수 있다.
JSP는 무엇을 해결해 주는가
JSP는 이 불편함을 줄이기 위해 나온 기술이다.
기본 틀은HTML처럼 작성하고, 꼭 필요한 부분에만Java코드와JSP태그를 넣어서 동적인 처리를 하도록 만든 방식이다.
그래서 코드를 보면 브라우저에 어떤 화면이 나올지가 더 잘 보인다.
즉,JSP는 서버에서 실행되는 기술이지만, 작성할 때는 화면 문서를 다루는 감각으로 접근할 수 있다.
- 화면의 뼈대는
HTML처럼 그대로 작성할 수 있다.- 바뀌는 값만 따로 끼워 넣으면 된다.
- 처리 코드와 화면 구조를 비교적 쉽게 연결해서 볼 수 있다.
그래서 초보자 기준에서는
Servlet보다JSP가 화면 작성 흐름을 따라가기가 훨씬 쉽다.
JSP가 필요했던 핵심 이유결국
JSP가 필요했던 가장 큰 이유는 화면을 더 자연스럽게 만들기 위해서다.
Servlet도 결과적으로는 같은 화면을 만들 수 있다.
하지만 화면 전체를 자바 출력문으로 작성하면, 코드가 길어질수록 관리도 어렵고 읽기도 어려워진다.
반면JSP는 화면 구조가 먼저 보이고, 동적인 부분만 따로 표시할 수 있다.
그래서 “이 코드는 어떤 화면을 만들고 있는가”가 훨씬 잘 드러난다.
이 점이JSP가 나온 가장 중요한 이유다.
- 동적인 화면이 필요했다.
- 화면을 자바 출력문으로만 만드는 방식은 불편했다.
- 화면 중심으로 더 읽기 쉬운 서버 기술이 필요했다.
즉,
JSP는 동적 화면을 더 쉽게 작성하기 위해 나온 표현 중심 기술이다.
그렇다고
Servlet이 필요 없는 것은 아니다여기서 주의할 점도 있다.
JSP가 나왔다고 해서Servlet이 필요 없어지는 것은 아니다.
둘은 서로 경쟁하는 기술이라기보다 역할이 다른 기술에 가깝다.
보통 요청을 받고, 입력값을 읽고, 분기하고, 데이터를 준비하는 쪽은Servlet이 더 잘 어울린다.
반대로 최종 화면을 보여 주는 쪽은JSP가 더 잘 어울린다.
즉, 처리 중심은Servlet, 표현 중심은JSP라고 이해하면 흐름이 잘 잡힌다.
Servlet은 요청 처리와 흐름 제어에 강하다.JSP는 결과 화면 표현에 강하다.- 실제 웹 프로그램에서는 둘을 함께 사용하는 경우가 많다.
이 기준이 잡혀야 다음에 나오는
JSP와Servlet의 관계도 자연스럽게 이해할 수 있다.
여기서 먼저 잡아야 할 핵심
이 구간에서 가장 중요하게 기억해야 하는 것은 아래 내용이다.
JSP는Servlet을 완전히 대체하려고 나온 기술이 아니다.JSP는 화면을 더 읽기 쉽게 작성하기 위해 나온 기술이다.- 같은 서버 처리라도
Servlet은 처리 중심이고,JSP는 표현 중심이다.이 흐름이 잡히면 다음 단계에서
JSP와Servlet이 왜 함께 설명되는지도 훨씬 쉽게 이어진다.
3-3. JSP와 Servlet의 관계
JSP와Servlet은 완전히 다른 기술처럼 보이지만, 실제로는 같은 웹 처리 흐름 안에 있는 기술이다.
둘 다 브라우저의 요청을 받아 서버에서 실행되고, 처리 결과를 브라우저에 응답으로 보내는 서버 프로그램이다.
즉, 겉모습은 달라도 큰 원리는 같다.
초보자 입장에서는 둘을 서로 다른 과목처럼 따로 떼어 생각하기 쉽다.
하지만 이 둘은 경쟁 관계라기보다 역할이 나뉜 관계에 가깝다.
그래서JSP를 제대로 이해하려면Servlet과 연결해서 보는 것이 중요하다.
공통점부터 먼저 보면
JSP와Servlet은 둘 다 서버에서 실행된다.
둘 다 요청이 들어와야 동작하고, 둘 다 최종적으로는 브라우저에 응답을 만들어 보낸다.
즉, 웹 프로그램의 큰 흐름으로 보면 둘은 같은 줄 위에 있다.
- 브라우저가 요청을 보낸다.
- 서버가 요청을 받아 실행한다.
- 실행 결과를 응답으로 돌려준다.
이 원리는
Servlet이든JSP든 같다.
그래서JSP를 배울 때도 요청과 응답이라는 기본 흐름이 계속 따라온다.
차이는 작성 방식에 있다둘의 가장 큰 차이는 작성 방식이다.
Servlet은 자바 클래스 형태로 작성한다.
그래서 기본 모습부터Java코드다.
요청을 처리하는 메서드 안에서 필요한 화면까지 직접 만들어 응답하는 경우가 많다.
반면JSP는 문서 형태로 작성한다.
기본 모습이HTML이고, 필요한 부분에만Java코드와JSP태그를 넣는다.
즉, 같은 서버 처리라도 어디를 중심으로 쓰느냐가 다르다.
Servlet은 자바 코드 중심이다.JSP는 화면 구조 중심이다.그래서
Servlet은 처리 흐름을 읽기에 좋고,JSP는 화면 결과를 읽기에 좋다.
이 차이를 먼저 분명하게 잡아야 두 기술이 헷갈리지 않는다.
왜 함께 설명되는가
이 둘은 따로 존재하는 기술이 아니라 실제로 같이 쓰는 경우가 많다.
사용자가 폼을 전송하면 먼저Servlet이 요청을 받는다.
그다음 필요한 값을 읽고, 조건을 검사하고, 데이터를 준비한다.
그리고 최종 화면은JSP로 넘겨서 보여 줄 수 있다.
즉, 흐름은 이렇게 이해하면 쉽다.
Servlet이 요청을 처리한다.Servlet이 화면에 필요한 데이터를 준비한다.JSP가 그 데이터를 받아 최종 화면으로 표현한다.이 구조를 한마디로 정리하면
Servlet이 준비하고JSP가 보여 준다가 된다.
이 기준이 잡히면 뒤에서forward,request공유,scope같은 개념도 훨씬 쉽게 이어진다.
왜
JSP안에서도request같은 객체를 쓰는가이 관계를 이해하면
JSP안에서request,response,session,application,out같은 객체가 왜 나오는지도 자연스럽게 보인다.
이 객체들은JSP전용으로 갑자기 생긴 낯선 도구가 아니다.
서버 프로그램이 실행되는 흐름 안에서 함께 사용하는 객체들이다.
특히 중요한 점은JSP가 실행될 때 결국Servlet과 연결된 형태로 동작한다는 점이다.
그래서Servlet에서 보던 요청과 응답 개념이JSP에서도 그대로 이어진다.
- 사용자가 보낸 값은
request로 읽는다.- 응답 결과는 결국 브라우저로 보내야 한다.
- 필요한 상태 정보는
session이나application으로 다룬다.즉,
JSP는 화면처럼 보여도 서버 프로그램 흐름 바깥에 있는 것이 아니다.
오히려 같은 실행 흐름 안에서 화면 쪽을 더 편하게 다루도록 만든 기술이다.
한 단계 더 보면
MVC로도 이어진다이 관계는 나중에
MVC패턴으로도 자연스럽게 이어진다.
아직은 구조를 깊게 외울 단계는 아니지만, 방향 정도는 알고 있으면 좋다.
보통MVC에서는 처리와 흐름 제어를 맡는 쪽을Servlet이 담당하고, 최종 화면을 보여 주는 쪽을JSP가 담당한다.
여기서 중요한 것은 이름을 외우는 것보다 역할을 이해하는 것이다.
JSP안에 처리 코드를 너무 많이 넣기 시작하면, 결국 다시 읽기 어려워진다.
그래서 처리와 표현을 나누는 관점이 중요해진다.
- 처리와 분기는
Servlet쪽이 더 어울린다.- 화면 출력과 표현은
JSP쪽이 더 어울린다.- 역할을 나눌수록 코드의 흐름이 더 잘 보인다.
이 관점이 잡히면
JSP를 단순한 화면 파일로만 보지 않게 되고,Servlet도 단순한 자바 클래스가 아니라 웹 흐름을 제어하는 중심으로 보이기 시작한다.
관계를 그림으로 보면
JSP와Servlet의 관계를 그림으로 보면 아래와 같다.
그림으로 보면
Servlet은Java프로그램 쪽에 더 가깝고,JSP는HTML문서 쪽에 더 가깝다.
하지만 둘 다 완전히 따로 떨어진 기술이 아니라, 웹 애플리케이션 안에서 함께 동작하는 구성 요소다.
즉, 이 그림은 코드 중심의 처리와 화면 중심의 표현이 서로 연결되어 있다는 점을 보여 준다.
여기서 먼저 잡아야 할 핵심
이 구간에서 가장 중요하게 기억해야 할 것은 아래 내용이다.
JSP와Servlet은 둘 다 서버에서 실행되는 웹 기술이다.- 차이는 실행 원리보다 작성 방식과 역할에 있다.
Servlet은 처리 중심이고,JSP는 화면 중심이다.- 실제 웹 프로그램에서는 둘을 함께 사용하는 경우가 많다.
정리하면
JSP는 화면처럼 작성하지만, 실행은 결국Servlet과 연결된 서버 프로그램 흐름 안에서 이루어진다.
이 기준이 잡혀야 다음에 나오는JSP처리 구조도 자연스럽게 이해할 수 있다.
3-4. JSP 처리 구조
JSP를 요청하면 서버는 그 파일을 그대로 브라우저에 보내지 않는다.
먼저JSP파일을 읽고, 그것을Servlet소스 코드 형태로 바꾼 다음, 컴파일해서 실행 가능한 클래스로 만든 뒤 실행 결과를 브라우저에 응답한다.
즉,JSP는 겉으로는 화면 파일처럼 보여도 실제로는 서버 안에서 실행 가능한 프로그램으로 바뀐 뒤 동작한다.
이 흐름을 알아야JSP를 단순한 문서 파일로 오해하지 않게 된다.
처리 순서를 단계로 보면
JSP의 처리 구조는 순서대로 따라가면 어렵지 않다.
브라우저가JSP를 요청하면, 서버 안의JSP컨테이너가 그 파일을 확인하고Servlet소스 코드로 변환한다.
그다음 그 코드를 컴파일해서 실행 가능한 클래스로 만들고, 그 클래스를 실행해서 응답 결과를 만든다.
- 브라우저가
JSP를 요청한다.- 서버가
JSP파일을 읽는다.JSP를Servlet소스 코드 형태로 변환한다.- 변환된 코드를 컴파일한다.
- 실행 가능한 클래스를 실행해서 응답을 만든다.
- 브라우저는 그 최종 결과만 받는다.
즉,
JSP는 직접 실행되는 문서가 아니라, 서버가 실행 가능한 형태로 바꾼 뒤 동작시키는 파일이다.
왜
Servlet으로 바뀌는가이 부분이 처음에는 가장 낯설다.
JSP는 분명HTML처럼 생겼는데 왜 갑자기Servlet으로 바뀐다고 하는지 헷갈릴 수 있다.
핵심은JSP가 사람이 화면을 더 쉽게 작성하도록 만든 형식이라는 점이다.
서버 입장에서는 결국 실행 가능한 자바 프로그램이 필요하다.
그래서JSP를 그대로 실행하는 것이 아니라, 서버가 이해하고 실행할 수 있는Servlet형태로 바꿔서 처리하는 것이다.
- 사람은
HTML중심으로JSP를 작성한다.- 서버는 그 내용을 실행 가능한 프로그램 형태로 바꾼다.
- 그 결과
JSP는 내부적으로Servlet처럼 동작하게 된다.즉, 작성은
JSP스타일로 하지만 실행은Servlet흐름으로 이루어진다고 보면 된다.
매번 변환되고 컴파일되는 것은 아니다
초보자가 여기서 자주 오해하는 부분이 있다.
요청할 때마다 매번 변환하고 컴파일하면 너무 비효율적일 것처럼 느껴진다.
실제로는 그렇지 않다.
보통은 처음 요청될 때, 또는 파일을 수정한 뒤 다시 처음 요청될 때 변환과 컴파일이 일어난다.
한 번 준비가 끝나면 그다음에는 이미 만들어진 결과를 사용한다.
- 처음 요청될 때 변환과 컴파일이 일어날 수 있다.
- 파일을 수정한 뒤 다시 처음 요청하면 다시 변환될 수 있다.
- 그 외의 요청에서는 준비된 결과를 재사용한다.
그래서 처음 한 번은 약간 느리게 느껴질 수 있지만, 이후에는 이미 준비된 결과를 바탕으로 처리된다고 이해하면 된다.
정적인
HTML도 그대로 남아 있는 것은 아니다
JSP안에 있는 정적인HTML은 그냥 문서처럼 남아 있는 것이 아니다.
서버 안에서는 그것도 결국 응답 본문에 써 주기 위한 출력 코드 흐름으로 바뀐다.
표현식 태그도 마찬가지다.
겉으로는 값 하나를 적어 둔 것처럼 보이지만, 실제로는 그 값을 응답에 출력하는 코드로 바뀐다.
즉,JSP안에 있는 내용은 정적인 부분이든 동적인 부분이든 결국 모두 브라우저에 보낼 응답을 만드는 쪽으로 흘러간다.
이 관점이 잡혀야 나중에out객체나 표현식 태그의 역할도 자연스럽게 이해된다.
- 정적인
HTML도 응답 출력 흐름으로 바뀐다.- 표현식 태그도 결과를 출력하는 코드 흐름으로 이어진다.
- 결국
JSP전체는 응답 화면을 만들기 위한 구조다.겉으로는 문서처럼 보여도, 서버 안에서는 결국 응답을 만드는 프로그램 흐름으로 처리된다는 점이 핵심이다.
그림으로 보면 처리 흐름은 이렇다
처리 구조를 그림으로 보면 아래와 같다.
출력 결과는 위 그림처럼
JSP가 바로 실행되는 것이 아니라, 먼저Servlet소스로 바뀌고 컴파일된 다음 실행되어 브라우저에 전달되는 구조다.
즉, 사용자는JSP원본을 보는 것이 아니라, 서버가 처리해서 만든 최종 결과 화면만 보게 된다.
여기서 먼저 잡아야 할 핵심
이 구간에서 가장 중요하게 기억해야 할 것은 아래 내용이다.
JSP는 서버가 그대로 실행하는 문서가 아니다.JSP는 내부적으로Servlet소스 코드로 변환되고 컴파일된 뒤 실행된다.- 이 변환은 보통 처음 요청될 때나 수정 후 첫 요청 때 일어난다.
- 브라우저는
JSP원본이 아니라 서버가 만든 최종 결과만 받는다.이 흐름이 잡혀야 뒤에서 나오는
JSP태그 분류와 내장 객체 설명도 훨씬 자연스럽게 이어진다.
3-5. JSP 태그의 큰 분류
JSP는HTML안에 아무 코드나 막 섞어 쓰는 방식이 아니다.
필요한 역할에 따라 태그 종류가 나뉘어 있고, 각 태그는 맡은 역할이 다르다.
그래서JSP를 읽을 때는 태그 하나하나를 따로 외우기보다, 먼저 큰 분류부터 잡는 것이 훨씬 중요하다.
초보자가JSP에서 가장 많이 헷갈리는 부분도 여기다.
기호가 비슷하게 생겨서 전부 비슷한 태그처럼 보이지만, 실제 역할은 전혀 다르다.
즉,JSP태그는 모양이 아니라 무슨 일을 하는 태그인지로 구분해서 봐야 한다.
왜 태그를 분류해서 봐야 하는가
JSP를 처음 보면<%@ %>,<% %>,<%= %>,<%! %>,<jsp:...>처럼 비슷해 보이는 문법이 한꺼번에 나온다.
겉모습만 보면 전부 같은 계열처럼 느껴질 수 있다.
하지만 어떤 태그는 설정을 위한 것이고, 어떤 태그는 자바 코드를 실행하기 위한 것이고, 어떤 태그는 값을 출력하기 위한 것이다.
즉, 생김새는 비슷해 보여도 역할은 다르다.
이 차이를 모르고 보면JSP코드가 전부 복잡하게 느껴진다.
반대로 큰 분류를 먼저 알고 보면, 지금 보고 있는 태그가 어떤 용도인지 바로 판단할 수 있어서 읽기가 훨씬 쉬워진다.
- 어떤 태그는 페이지의 실행 환경을 정한다.
- 어떤 태그는
Java코드를 직접 넣는다.- 어떤 태그는 값을 출력한다.
- 어떤 태그는 이미 정해진 기능을 수행한다.
그래서
JSP는 문법 하나하나를 따로 외우기보다, 먼저 역할별로 나누어 보는 것이 더 중요하다.
크게 보면 어떤 종류가 있는가
JSP태그는 크게 보면주석문 태그,지시자 태그,스크립팅 태그,액션 태그로 나눌 수 있다.
이 네 가지가JSP태그의 큰 뼈대다.
먼저주석문 태그는 설명을 남기는 태그다.
HTML주석과 비슷해 보여도,JSP처리 과정에서 사용되는 주석이라는 점이 다르다.
지시자 태그는 이 페이지를 서버가 어떤 조건으로 처리해야 하는지 알려주는 설정 태그다.
즉, 화면에 바로 무언가를 출력하기 위한 것이 아니라, 처리 환경을 정하는 역할을 한다.
스크립팅 태그는Java코드를 직접 넣는 태그다.
여기에는 선언문 태그, 표현식 태그, 스크립트릿 태그가 포함된다.
즉, 준비할 것인지, 출력할 것인지, 처리할 것인지에 따라 다시 나뉜다.
액션 태그는JSP가 제공하는 기능성 태그다.
즉, 다른 자원을 포함하거나, 다른 페이지로 넘기거나, 객체를 다루는 기능을 태그 형태로 사용할 수 있게 만든 것이다.
주석문 태그는 설명을 남긴다.지시자 태그는 페이지의 처리 조건을 정한다.스크립팅 태그는Java코드를 직접 작성한다.액션 태그는 정해진 기능을 수행한다.이 큰 분류만 먼저 잡아도 뒤에서 세부 태그를 볼 때 훨씬 덜 헷갈린다.
지시자 태그는 어떤 역할인가
지시자 태그는<%@ %>형태로 작성한다.
이 태그는 화면에 직접 값을 보여 주는 것이 아니라, 현재JSP페이지를 어떤 방식으로 처리할지 서버에 알려 주는 설정 태그다.
예를 들어 문서 형식, 문자 인코딩, 세션 사용 여부, 다른 파일을 미리 포함할지 같은 내용을 설정할 때 사용한다.
즉, 실행 전에 필요한 환경을 정하는 태그라고 보면 된다.
초보자 입장에서는 이 태그도 출력 태그처럼 보일 수 있다.
하지만 지시자 태그는 결과를 보여 주는 태그가 아니라, 결과가 어떤 환경에서 만들어질지를 정하는 태그다.
page지시자는 현재 페이지의 설정을 담당한다.include지시자는 다른 파일 내용을 미리 합쳐 넣는다.그래서 지시자 태그는 화면 내용보다 먼저, 처리 조건을 정하는 태그라고 이해하면 된다.
스크립팅 태그는 어떤 역할인가
스크립팅 태그는JSP안에Java코드를 직접 넣는 태그다.
여기서 중요한 것은 전부 같은 코드 태그가 아니라는 점이다.
용도에 따라 선언문 태그, 표현식 태그, 스크립트릿 태그로 나뉜다.
선언문 태그는 멤버 변수나 메서드를 선언할 때 사용한다.
표현식 태그는 계산된 값을 화면에 바로 출력할 때 사용한다.
스크립트릿 태그는 조건문, 반복문, 변수 선언처럼 실제 처리 흐름을 만드는 데 사용한다.
즉, 스크립팅 태그는 전부Java코드를 다루지만, 세부 역할은 서로 다르다.
- 선언문 태그는 준비하는 태그다.
- 표현식 태그는 보여 주는 태그다.
- 스크립트릿 태그는 처리하는 태그다.
이 차이를 알고 있어야 뒤에서 멤버 변수와 지역 변수 차이, 출력 태그와 처리 태그 차이도 자연스럽게 이해된다.
액션 태그는 어떤 역할인가
액션 태그는JSP가 미리 준비해 둔 기능을 태그 형태로 사용하는 문법이다.
즉, 직접 긴Java코드를 적지 않아도, 특정 기능을 바로 실행할 수 있게 만든 태그다.
대표적으로 다른 자원의 결과를 포함하는 태그, 다른 페이지로 처리를 넘기는 태그, 객체를 생성하고 속성 값을 다루는 태그들이 여기에 들어간다.
즉, 액션 태그는 설정용도 아니고 단순 출력용도 아니다.
이미 정해진 동작을 수행하는 기능성 태그라고 보면 된다.
- 다른 자원의 결과를 포함할 수 있다.
- 다른 페이지로 처리를 넘길 수 있다.
- 객체를 만들고 값을 넣고 꺼낼 수 있다.
그래서 액션 태그는
JSP를 조금 더 구조적으로 사용할 수 있게 도와주는 태그라고 이해하면 된다.
그림으로 보면 구조는 이렇다
JSP태그의 큰 분류를 그림으로 보면 아래와 같다.
그림을 보면
JSP태그가 한 종류가 아니라,지시자 태그,스크립팅 태그,액션 태그흐름으로 나뉘어 있다는 점이 한눈에 보인다.
즉, 태그를 단순히 기호로 외우는 것이 아니라 설정용인지, 코드 작성용인지, 기능 실행용인지로 구분해서 봐야 구조가 잘 잡힌다.
여기서 먼저 잡아야 할 핵심
이 구간에서 가장 중요하게 기억해야 할 것은 아래 내용이다.
JSP태그는 전부 같은 역할을 하는 문법이 아니다.- 먼저 큰 분류를 알아야 세부 태그가 덜 헷갈린다.
지시자 태그는 설정용이고,스크립팅 태그는 코드 작성용이고,액션 태그는 기능 실행용이다.이 큰 지도가 먼저 잡혀야 다음에 나오는
page지시자,include지시자, 선언문 태그, 표현식 태그, 스크립트릿 태그도 훨씬 쉽게 이어진다.
3-6. 지시자 태그
JSP에서 지시자 태그는<%@ %>형태로 작성하는 설정용 태그다.
이 태그는 화면에 직접 값을 출력하는 역할이 아니라, 현재JSP페이지를 서버가 어떤 조건으로 처리해야 하는지 알려 주는 역할을 한다.
즉, 결과 화면에 보이는 내용을 만드는 태그가 아니라, 그 화면이 어떤 환경에서 처리될지 먼저 정하는 태그라고 이해하면 된다.
초보자가 여기서 자주 헷갈리는 이유는 기호 모양이 다른 태그들과 비슷해 보이기 때문이다.
하지만 지시자 태그는 출력용 태그도 아니고, 처리용 자바 코드 태그도 아니다.
설정용이라는 점이 가장 중요하다.
지시자 태그는 무엇을 하는가
지시자 태그는
JSP페이지가 실행되기 전에 필요한 조건을 정한다.
예를 들어 문서 형식은 무엇인지, 문자 인코딩은 무엇인지, 세션을 사용할지, 다른 파일을 미리 포함할지 같은 내용을 여기서 설정한다.
즉,JSP가 어떻게 동작할지에 대한 기본 규칙을 먼저 알려 주는 역할이다.
- 현재 페이지의 처리 환경을 정한다.
- 서버가 페이지를 어떻게 읽고 처리할지 알려 준다.
- 화면에 직접 출력되기보다 실행 조건을 먼저 잡아 준다.
그래서 지시자 태그는 결과를 보여 주는 문법이 아니라, 결과가 잘 만들어지도록 처리 환경을 세팅하는 문법이라고 보면 된다.
왜 지시자 태그가 필요한가
서버는
JSP를 처리할 때 아무 정보 없이 실행할 수는 없다.
이 페이지를 어떤 문자셋으로 읽어야 하는지, 어떤 응답 형식으로 보내야 하는지, 어떤 클래스를 사용할지 같은 기준이 있어야 한다.
이 역할을 지시자 태그가 맡는다.
예를 들어 한글이 들어 있는 페이지라면 문자 인코딩이 맞아야 글자가 깨지지 않는다.
또Java클래스를 사용하려면 어떤 클래스를 불러올지 알려 주어야 한다.
오류가 날 때 다른 페이지로 넘기고 싶다면 그것도 미리 정해 두어야 한다.
즉, 지시자 태그는 화면보다 먼저 처리되어야 할 준비 사항을 담당한다.
- 문자 인코딩이 맞지 않으면 한글이 깨질 수 있다.
- 사용할 클래스를 미리 알려 주어야 할 수 있다.
- 오류 처리 방식도 미리 정해 둘 수 있다.
즉, 지시자 태그는
JSP페이지가 안정적으로 처리되도록 기본 조건을 잡아 주는 태그다.
어떤 종류가 있는가
지시자 태그에는 여러 종류가 있지만, 지금 단계에서 가장 자주 보는 것은
page지시자와include지시자다.
page지시자는 현재 페이지 자체의 실행 환경을 설정한다.
반면include지시자는 다른 파일 내용을 현재 페이지에 미리 합쳐 넣는 역할을 한다.
즉, 하나는 페이지 설정이고, 다른 하나는 파일 재사용과 연결된다.
실무나 학습에서도 처음에는 이 두 가지를 가장 먼저 자주 보게 된다.
page지시자는 현재 페이지의 설정을 담당한다.include지시자는 공통 파일을 미리 포함할 때 사용한다.뒤에서
page와include를 따로 자세히 보겠지만, 지금은 지시자 태그 안에도 역할이 나뉜다는 정도만 먼저 잡고 가면 된다.
출력 태그와 왜 다르게 봐야 하는가
지시자 태그를 표현식 태그나 스크립트릿 태그와 같은 감각으로 보면 헷갈리기 쉽다.
표현식 태그는 값을 화면에 보여 주는 태그다.
스크립트릿 태그는 처리 흐름을 만드는 태그다.
하지만 지시자 태그는 그 둘과 다르게, 화면에 직접 무언가를 보여 주는 역할을 하지 않는다.
예를 들어pageEncoding="UTF-8"같은 설정은 사용자 화면에 글자로 출력되는 것이 아니다.
이 페이지를 어떤 인코딩 기준으로 읽고 처리할지를 정하는 정보일 뿐이다.
즉, 지시자 태그는 눈에 보이는 결과보다 처리 기준을 먼저 정하는 태그라고 봐야 한다.
- 표현식 태그는 값을 출력한다.
- 스크립트릿 태그는 처리 흐름을 만든다.
- 지시자 태그는 실행 환경과 처리 조건을 정한다.
이 차이를 분명하게 잡아야 뒤에서
page지시자를 볼 때도 “왜 이게 출력이 안 되지?” 같은 헷갈림이 줄어든다.
여기서 먼저 잡아야 할 핵심
이 구간에서 가장 중요하게 기억해야 할 것은 아래 내용이다.
- 지시자 태그는
<%@ %>형태로 작성한다.- 지시자 태그는 화면 출력용이 아니라 설정용 태그다.
- 현재
JSP페이지가 어떤 조건에서 처리될지를 정하는 역할을 한다.- 지금 단계에서는
page와include지시자를 가장 중요하게 보면 된다.이 기준이 잡혀야 다음에 나오는
page지시자와include지시자를 훨씬 자연스럽게 이해할 수 있다.
3-7. page 지시자
page지시자는 현재JSP페이지가 어떤 조건으로 동작할지를 정하는 지시자 태그다.
즉, 화면에 직접 값을 출력하는 태그가 아니라, 이 페이지를 서버가 어떤 방식으로 읽고 처리할지 먼저 알려 주는 설정 태그다.
처음 보면 그냥 맨 위에 항상 적는 형식적인 코드처럼 보일 수 있다.
하지만 실제로는 문자 인코딩, 응답 문서 형식, 사용할 클래스, 오류 처리 방식처럼 페이지 실행에 필요한 중요한 기준을 여기서 정한다.
그래서page지시자는 현재 페이지의 실행 환경을 잡아 주는 중심 설정 태그라고 이해해야 한다.
page지시자는 무엇을 정하는가
page지시자는 현재JSP가 어떤 형식으로 처리될지 정한다.
예를 들어 브라우저에 어떤 문서 형식으로 응답할지, 파일을 어떤 문자셋으로 읽을지, 어떤 클래스를 사용할지, 오류가 나면 어디로 보낼지를 지정할 수 있다.
즉,JSP페이지가 동작하기 전에 필요한 기본 조건을 미리 정하는 역할이다.
- 어떤 형식의 응답을 만들지 정한다.
- 어떤 인코딩으로 페이지를 읽고 보낼지 정한다.
- 필요한
Java클래스를 사용할 수 있게 한다.- 오류가 발생했을 때 이동할 페이지를 정할 수 있다.
그래서
page지시자는 화면에 보이는 내용을 만드는 태그라기보다, 그 화면이 문제 없이 처리되도록 실행 기준을 세팅하는 태그라고 보면 된다.
자주 보는 속성은 무엇인가
page지시자에는 여러 속성이 들어갈 수 있지만, 초보자 기준에서는 자주 보는 것부터 먼저 잡는 것이 좋다.
가장 많이 보는 것은contentType,pageEncoding,import,errorPage,isErrorPage다.
contentType은 브라우저에 어떤 형식의 응답을 보낼지 정한다.
예를 들어text/html; charset=UTF-8이라고 적으면, 이 응답을HTML문서로 보내고 문자셋은UTF-8로 맞춘다는 뜻이다.
pageEncoding은JSP파일 자체를 어떤 인코딩 기준으로 읽을지를 정한다.
즉, 파일을 읽는 기준과 응답을 보내는 기준이 함께 맞아야 한글이 깨지지 않는다.
import는JSP안에서 사용할Java클래스를 불러올 때 사용한다.
errorPage는 현재 페이지에서 오류가 났을 때 대신 보여 줄 페이지를 지정한다.
isErrorPage는 그 페이지가 오류를 처리하는 전용 페이지라는 뜻이다.
contentType은 응답 문서 형식을 정한다.pageEncoding은 파일을 읽는 인코딩 기준을 정한다.import는 사용할 클래스를 불러온다.errorPage는 오류 발생 시 이동할 페이지를 정한다.isErrorPage는 오류 처리 페이지임을 표시한다.즉,
page지시자는 단순히 문서 맨 위에 붙는 코드가 아니라, 현재 페이지의 처리 조건을 한 번에 정리하는 설정 태그다.
errorPage속성은 무엇을 해결하는가
JSP를 실행하다 보면 요청값이 없거나 잘못된 계산 때문에 오류가 날 수 있다.
이때 기본 오류 화면을 그대로 보여 주면 사용자 입장에서도 갑자기 흐름이 끊기고, 화면도 거칠게 보인다.
그래서 오류가 발생했을 때 대신 보여 줄 페이지를 미리 정해 둘 수 있다.
이 역할을 하는 속성이errorPage다.
아래 예제는guestName요청값을 읽은 뒤 이름 길이를 출력하는 코드다.
그런데 요청값이 없으면name은null이 되고, 그 상태에서name.length()를 호출하면 오류가 발생할 수 있다.
이때errorPage="errorPage.jsp"를 설정해 두면 기본 오류 화면 대신 지정한 오류 페이지로 이동하게 된다.<!-- exam8.jsp --> <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" errorPage="errorPage.jsp" %> <!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title>Insert title here</title> </head> <body> <h2>errorPage 속성 테스트</h2> <hr /> <% String name = request.getParameter("guestName"); %> <!-- 요청으로 전달된 이름 값을 읽음 --> <h3>당신의 이름은 <%= name %> 이고 이름의 길이는 <%= name.length() %> 입니다.</h3> <!-- 값이 없으면 name.length()에서 오류가 날 수 있음 --> </body> </html>이 코드는 요청값이 정상적으로 전달되면 일반 결과 화면을 보여 준다.
출력 결과는 아래와 같다.
요청값이 정상적으로 들어오면 이름과 이름 길이가 일반 결과 화면에 출력된다.
반대로 요청값이 없어서 오류가 발생하면errorPage로 지정한 페이지가 대신 응답한다.
오류 처리 페이지 코드는 아래와 같다.<!-- errorPage.jsp --> <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %> <%@ page isErrorPage="true" %> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> </head> <body style="text-align:center"> <h2>오류 발생했어욤ㅠㅠ</h2> <h3>빠른시일내에 복구하겠습니다...</h3> <img src="error.jpg"> <% String msg = "오류 원인 : " + exception; System.out.println("----------------------------------------"); System.out.println(msg); System.out.println("----------------------------------------"); exception.printStackTrace(); %> <!-- 오류 객체 내용을 서버 콘솔에서 확인 --> </body> </html>여기서 중요한 점은
isErrorPage="true"다.
이 설정이 있어야 오류 페이지 안에서exception객체를 사용할 수 있다.
즉, 아무JSP나 오류 페이지처럼 쓰는 것이 아니라, 오류를 처리하는 전용 페이지라는 표시를 따로 해 주어야 한다.
출력 결과는 아래와 같다.
요청값이 정상적으로 전달을 해주지 않으니 에러 페이지가 나오는 것을 볼 수 있다.
errorPage속성을 사용하면 기본 오류 화면 대신 지정한 오류 페이지로 이동시킬 수 있다.
import속성은 왜 필요한가
JSP도 결국 서버에서 실행되는 자바 프로그램 흐름과 연결되어 있다.
그래서 일반Java클래스를 사용하려면 그 클래스를 불러와야 한다.
이때 사용하는 것이import속성이다.
아래 예제는LocalDate와LocalDateTime클래스를 불러와서 현재 날짜와 시간을 출력하는 코드다.
즉,page지시자의import를 사용하면JSP안에서도 일반Java클래스를 활용할 수 있다.<!-- exam9.jsp --> <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ page import="java.time.LocalDate"%> <%@ page import="java.time.LocalDateTime"%> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>JSP 예제</title> </head> <body> <% LocalDate ld = LocalDate.now(); %> <!-- 현재 날짜 객체 생성 --> <%=ld.getYear()%>년 <%=ld.getMonthValue()%>월 <%=ld.getDayOfMonth()%>일 <hr> <% LocalDateTime ldt = LocalDateTime.now(); %> <!-- 현재 날짜와 시간 객체 생성 --> <%=ldt.getYear()%>년 <%=ldt.getMonthValue()%>월 <%=ldt.getDayOfMonth()%>일 <%=ldt.getHour()%>시 <%=ldt.getMinute()%>분 <%=ldt.getSecond()%>초 </body> </html>이 예제에서 핵심은
import가 없으면LocalDate,LocalDateTime같은 클래스를 바로 사용할 수 없다는 점이다.
즉,page지시자는 인코딩만 정하는 태그가 아니라, 현재 페이지가 사용할 클래스까지 연결해 주는 역할도 한다.
출력 결과는 아래와 같다.
import속성을 사용하면JSP안에서도 날짜와 시간 관련 클래스를 불러와 결과를 화면에 출력할 수 있다.
여기서 먼저 잡아야 할 핵심
이 구간에서 가장 중요하게 기억해야 할 것은 아래 내용이다.
page지시자는 현재JSP페이지의 실행 환경을 정하는 태그다.- 자주 보는 속성은
contentType,pageEncoding,import,errorPage,isErrorPage다.errorPage는 오류가 발생했을 때 대신 보여 줄 페이지를 지정한다.isErrorPage는 오류 처리 페이지에서exception객체를 사용할 수 있게 한다.import는JSP안에서 일반Java클래스를 사용할 수 있게 해 준다.이 기준이 잡혀야 다음에 나오는
include지시자와도 차이를 분명하게 구분할 수 있다.
3-8. include 지시자
include지시자는 여러 페이지에서 반복되는 내용을 따로 빼서 재사용할 때 사용하는 지시자 태그다.
예를 들어 머리글, 바닥글, 공통 메뉴처럼 여러 화면에 반복해서 들어가는 내용을 매번 직접 복사해서 붙이는 대신, 한 파일로 분리해 두고 필요한 페이지에서 불러오는 방식이다.
즉,include지시자는 단순히 파일을 끼워 넣는 문법이 아니라, 반복되는 공통 부분을 한곳에서 관리하게 도와주는 기능이라고 이해하면 된다.
include지시자는 무엇을 하는가
include지시자는 현재JSP페이지 안에 다른 파일의 내용을 미리 합쳐 넣는 역할을 한다.
그래서 여러 페이지에 공통으로 들어가는 내용을 따로 파일로 빼 두고 재사용할 수 있다.
여기서 중요한 점은 이 태그가 실행 중에 다른 결과를 가져오는 방식이 아니라, 현재 페이지가 처리되기 전에 파일 내용을 먼저 붙여 넣는 방식이라는 점이다.
즉, 서버는JSP를 처리할 때 처음부터 하나의 파일처럼 합쳐진 상태로 보게 된다.
- 여러 페이지에 반복되는 내용을 따로 분리할 수 있다.
- 현재 페이지 안에 다른 파일 내용을 미리 합쳐 넣는다.
- 공통 부분을 한곳에서 관리할 수 있게 해 준다.
그래서
include지시자는 화면을 더 편하게 만드는 기능이면서, 동시에 유지보수를 쉽게 만드는 기능이기도 하다.
왜 공통 파일을 따로 빼는가
페이지를 여러 개 만들다 보면 같은 머리글, 메뉴, 바닥글이 반복되는 경우가 많다.
이때 모든 파일에 같은 내용을 직접 써 두면, 나중에 수정할 때 모든 파일을 하나씩 고쳐야 한다.
예를 들어 메뉴 한 줄이 바뀌었는데 관련 페이지가 열 개라면, 열 군데를 모두 수정해야 할 수도 있다.
이런 중복은 관리가 어렵고 실수도 늘린다.
그래서 반복되는 부분을 따로 파일로 빼 두고 필요한 곳에서 불러오는 방식이 훨씬 효율적이다.
- 공통 내용을 여러 파일에 중복해서 쓰지 않아도 된다.
- 한 군데만 수정해도 관련 페이지에 함께 반영할 수 있다.
- 코드가 덜 겹치고 구조도 더 깔끔해진다.
즉,
include지시자는 단순히 편하게 쓰는 기능이 아니라, 중복을 줄이고 관리 부담을 줄이는 기능이라고 보면 된다.
개념 흐름은 아래 그림처럼 이해하면 쉽다.
공통 내용을 별도 파일로 나누면 여러
JSP에서 같은 내용을 반복 없이 재사용할 수 있다.
왜
jspf확장자를 쓰는가첫 번째 그림을 보면 공통 파일 이름이
header.jspf처럼 되어 있다.
여기서jspf는 보통JSP fragment라고 보고, 다른JSP안에 포함해서 쓰는 조각 파일이라는 뜻으로 이해하면 된다.
즉, 혼자서 완성된 페이지처럼 실행하는 파일이라기보다, 공통으로 붙여 넣어 사용할 조각이라는 의미를 이름으로 드러낸 것이다.
jspf파일은 공통 머리글, 바닥글, 메뉴처럼 반복되는 조각을 따로 빼 둘 때 자주 사용한다.- 이런 파일은 보통
include지시자로 현재 페이지 안에 포함해서 사용한다.- 그래서 전체 페이지라기보다 재사용용 조각 파일이라는 성격이 더 강하다.
즉,
header.jspf라고 적어 두면 이 파일은 단독 실행용 화면이라기보다, 다른 페이지에 붙여 넣어 사용하는 공통 조각이라는 점이 더 분명해진다.
include지시자의 핵심 동작이 구간에서 가장 중요한 것은 처리 시점이다.
include지시자는 실행 도중에 다른 파일 결과를 가져오는 방식으로 이해하면 안 된다.
서버가JSP를 변환할 때, 다른 파일 내용을 먼저 합쳐서 하나처럼 만든다고 이해해야 한다.
즉, 지금 실행하다가 잠깐 다른 페이지를 호출하는 것이 아니다.
처음 처리될 때부터 이미 붙어 있는 상태로 본다는 점이 핵심이다.
이 점 때문에 뒤에서 배우는jsp:include와는 동작 방식이 다르다.
include지시자는 처리 전에 파일 내용을 합친다.- 현재 페이지와 포함 파일이 하나처럼 묶여서 처리된다.
- 실행 중에 다른 자원의 결과를 가져오는 방식과는 다르다.
include지시자는 파일 내용을 미리 붙여 넣는 방식이다.
이 기준이 정확히 잡혀야 나중에jsp:include와 헷갈리지 않는다.
처리 흐름은 아래 그림처럼 보면 더 쉽게 들어온다.
include지시자는 실행 중에 붙이는 것이 아니라, 변환 과정에서 파일 내용을 미리 합쳐 넣는 방식이다.
예제로 보면 어떻게 사용하는가
아래 예제는 공통 머리글 파일을 따로 두고, 현재 페이지에서
include지시자로 불러오는 가장 기본적인 형태다.
즉, 반복되는 상단 영역을header.jspf로 따로 빼 두고,main.jsp에서 포함하는 구조다.<!-- main.jsp --> <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %> <%@ include file="header.jspf" %> <!-- 공통 머리글 파일을 현재 페이지에 미리 포함 --> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>include 지시자 예제</title> </head> <body> <h2>본문 영역</h2> <p>이 부분은 현재 페이지의 본문 내용이다.</p> </body> </html>이 코드에서 중요한 부분은
<%@ include file="header.jspf" %>다.
이 한 줄 때문에header.jspf의 내용이main.jsp안으로 미리 합쳐진다.
즉, 서버는 이 페이지를 처리할 때 공통 머리글까지 이미 포함된 하나의 페이지처럼 본다.<!-- header.jspf --> <h1>공통 머리글</h1> <hr> <!-- 여러 페이지에서 함께 재사용할 공통 영역 -->여기서
header.jspf는 반복해서 사용할 조각 파일 역할을 한다.
이 단계에서는 확장자 자체를 외우는 것이 핵심이 아니다.
중요한 점은 반복되는 공통 내용을 따로 빼서 필요한 페이지에 연결했다는 것이다.
여기서 먼저 잡아야 할 핵심
이 구간에서 가장 중요하게 기억해야 할 것은 아래 내용이다.
include지시자는 반복되는 공통 내용을 재사용할 때 사용한다.- 여러 페이지에 같은 내용을 직접 복사하지 않고 따로 파일로 분리해서 관리할 수 있다.
jspf는 포함해서 쓰는 조각 파일이라는 뜻을 드러낼 때 자주 사용한다.include지시자는 실행 중에 결과를 가져오는 것이 아니라, 처리 전에 파일 내용을 미리 합친다.- 이 점 때문에 뒤에서 배우는
jsp:include와는 동작 방식이 다르다.이 기준이 잡혀야 나중에 액션 태그에서 나오는
jsp:include와 차이도 분명하게 구분할 수 있다.
3-9. 스크립팅 태그
JSP에서 스크립팅 태그는Java코드를 직접 넣을 수 있게 해 주는 태그다.
즉, 화면 안에 필요한 처리 코드, 출력 코드, 선언 코드를 함께 적을 수 있도록 만든 문법이다.
여기서 중요한 점은 스크립팅 태그가 전부 같은 역할을 하는 것이 아니라는 것이다.
겉보기에는 다 비슷하게 생겼지만, 어떤 태그는 준비를 위한 것이고, 어떤 태그는 값을 출력하기 위한 것이고, 어떤 태그는 실제 처리 흐름을 만들기 위한 것이다.
그래서 이 구간은 문법 모양만 외우는 것보다 역할 차이를 먼저 정확히 구분하는 것이 중요하다.
스크립팅 태그는 무엇인가
스크립팅 태그는
JSP안에서Java코드를 직접 다루는 태그를 묶어서 부르는 말이다.
즉, 화면에 필요한 계산을 하거나, 값을 출력하거나, 변수와 메서드를 선언하는 일을JSP안에서 바로 할 수 있게 해 준다.
JSP는 기본이HTML중심인 문서이기 때문에, 이런 스크립팅 태그가 있어야 화면 안에 동적인 처리를 연결할 수 있다.
즉, 스크립팅 태그는JSP가 단순한 문서가 아니라 서버 프로그램처럼 동작하게 해 주는 핵심 문법이라고 볼 수 있다.
Java코드를JSP안에 직접 넣을 수 있게 해 준다.- 화면에 필요한 처리와 출력을 연결할 수 있게 해 준다.
JSP를 동적인 페이지로 동작하게 해 주는 핵심 문법이다.즉, 스크립팅 태그는 화면 안에 서버 쪽 동작을 심는 역할을 한다고 이해하면 된다.
왜 세 가지로 나누어 봐야 하는가
초보자가 스크립팅 태그를 처음 볼 때 가장 많이 헷갈리는 이유는, 전부
Java코드를 적는 태그처럼 보이기 때문이다.
하지만 실제 역할은 서로 다르다.
선언을 하는 태그와, 값을 출력하는 태그와, 처리 흐름을 만드는 태그를 같은 것으로 보면 코드가 금방 복잡하게 느껴진다.
예를 들어 어떤 태그는 멤버 변수처럼 유지되는 값을 선언할 수 있고, 어떤 태그는 계산 결과를 화면에 바로 출력할 수 있고, 어떤 태그는if,for같은 흐름 제어를 담당한다.
즉, 전부Java코드라고 해서 같은 용도라고 생각하면 안 된다.
- 선언문 태그는 준비하는 태그다.
- 표현식 태그는 보여 주는 태그다.
- 스크립트릿 태그는 처리하는 태그다.
이 세 가지를 구분해야 뒤에서 멤버 변수와 지역 변수 차이, 출력 태그와 처리 태그 차이도 자연스럽게 이해된다.
선언문 태그, 표현식 태그, 스크립트릿 태그
스크립팅 태그는 크게 세 가지로 나뉜다.
선언문 태그는<%! %>형태로 작성하고, 멤버 변수나 메서드를 선언할 때 사용한다.
즉, 지금 바로 실행하는 코드라기보다 페이지 안에서 공통으로 사용할 준비물을 정의하는 태그다.
표현식 태그는<%= %>형태로 작성하고, 계산된 값이나 변수 값을 화면에 바로 출력할 때 사용한다.
즉, 이미 만들어진 결과를 브라우저에 보여 주는 역할을 한다.
스크립트릿 태그는<% %>형태로 작성하고, 조건문, 반복문, 변수 선언, 요청값 처리처럼 실제 실행 흐름을 만드는 데 사용한다.
즉, 화면 뒤에서 동작하는 처리 코드를 적는 태그다.
<%! %>는 선언문 태그다.<%= %>는 표현식 태그다.<% %>는 스크립트릿 태그다.겉보기에는 기호만 조금 다른 것처럼 보여도, 실제 역할은 준비, 출력, 처리로 분명하게 나뉜다.
각각 어떤 예제로 이어지는가
앞으로 이 세 가지 태그는 각각 따로 자세히 보게 된다.
현재 예제 흐름으로 보면 선언문 태그는exam2.jsp와exam5.jsp가 연결되고, 표현식 태그는exam3.jsp, 스크립트릿 태그는exam6.jsp가 연결된다.
즉, 지금 이 구간은 세부 문법을 끝내는 단계가 아니라, 뒤에서 나올 예제들을 이해하기 위한 큰 지도를 먼저 잡는 단계다.
exam2.jsp,exam5.jsp는 선언문 태그 흐름으로 이어진다.exam3.jsp는 표현식 태그 흐름으로 이어진다.exam6.jsp는 스크립트릿 태그 흐름으로 이어진다.그래서 지금은 각 태그를 세세하게 외우기보다, 이 예제가 어떤 종류의 태그를 보여 주는 예제인지를 먼저 연결해서 보는 것이 중요하다.
왜 나중에는 조심해서 쓰게 되는가
스크립팅 태그는
JSP를 배우는 초반에는 아주 중요하다.
왜냐하면JSP가 실제로 어떻게 동작하는지 가장 직접적으로 보여 주기 때문이다.
하지만 코드가 길어질수록 화면 구조와 처리 코드가 다시 섞이기 시작해서 가독성이 떨어질 수 있다.
즉, 스크립팅 태그는 원리를 이해하는 데는 아주 좋지만, 많이 섞일수록 다시 복잡해질 수 있다.
그래서 나중에는 표현을 더 단순하게 만드는 방식이나 역할을 나누는 방식이 더 중요해진다.
하지만 지금 단계에서는JSP의 동작 원리를 잡는 데 꼭 필요한 문법이다.
- 스크립팅 태그는
JSP의 동작 원리를 이해하는 데 도움이 된다.- 하지만 많이 섞일수록 화면과 처리 코드가 다시 복잡해질 수 있다.
- 그래서 지금은 역할 차이를 정확히 구분해서 배우는 것이 가장 중요하다.
즉, 스크립팅 태그는 많이 쓰기 위한 문법이라기보다,
JSP의 구조를 제대로 이해하기 위해 먼저 잡아야 하는 핵심 문법이라고 보면 된다.
여기서 먼저 잡아야 할 핵심
이 구간에서 가장 중요하게 기억해야 할 것은 아래 내용이다.
- 스크립팅 태그는
JSP안에Java코드를 직접 넣는 태그다.- 스크립팅 태그는 전부 같은 역할이 아니라 선언, 출력, 처리로 나뉜다.
- 선언문 태그는 준비용이고, 표현식 태그는 출력용이고, 스크립트릿 태그는 처리용이다.
- 뒤 예제는 이 세 가지를 각각 따로 보여 주는 흐름으로 이어진다.
이 큰 구분이 먼저 잡혀야 다음에 나오는 선언문 태그, 표현식 태그, 스크립트릿 태그를 훨씬 덜 헷갈리게 읽을 수 있다.
3-10. 선언문 태그
JSP의 선언문 태그는<%! %>형태로 작성한다.
이 태그는 화면에 바로 값을 출력하는 태그가 아니라, 멤버 변수나 메서드를 선언할 때 사용하는 태그다.
즉, 지금 당장 실행되는 한 줄짜리 처리 코드를 적는 자리가 아니라, 현재 페이지 안에서 공통으로 사용할 준비물을 정의하는 자리라고 이해하면 된다.
처음 보면 스크립트릿 태그와 비슷해 보여서 둘을 같은 코드 태그처럼 생각하기 쉽다.
하지만 선언문 태그와 스크립트릿 태그는 저장되는 위치와 역할이 다르다.
그래서 이 구간에서는 선언문 태그가 무엇을 선언하는지, 그리고 왜 스크립트릿 태그와 다르게 봐야 하는지를 먼저 정확히 잡아야 한다.
선언문 태그는 무엇을 선언하는가
선언문 태그는 이름 그대로 선언을 하는 곳이다.
여기에는 멤버 변수와 메서드를 넣을 수 있다.
즉, 요청이 들어올 때마다 잠깐 실행되고 끝나는 코드보다, 페이지 전체에서 공통으로 사용할 준비물을 적는 자리라고 보면 된다.
그래서 선언문 태그는 결과를 바로 출력하는 자리도 아니고,if,for처럼 처리 흐름을 만드는 자리도 아니다.
출력보다는 준비에 가깝고, 실행문보다는 정의에 가깝다.
- 멤버 변수를 선언할 수 있다.
- 메서드를 선언할 수 있다.
- 현재 페이지 안에서 공통으로 쓸 준비물을 정의하는 데 사용한다.
즉, 선언문 태그는 화면에 바로 보일 결과를 적는 자리가 아니라, 페이지 안에서 사용할 기능과 값을 미리 준비하는 자리다.
왜 스크립트릿 태그와 다르게 봐야 하는가
선언문 태그가 헷갈리는 가장 큰 이유는 스크립트릿 태그도
Java코드를 쓰고, 선언문 태그도Java코드를 쓰기 때문이다.
겉보기에는 둘 다 비슷해 보인다.
하지만 실제로는 역할이 다르다.
스크립트릿 태그는 요청이 들어왔을 때 실행되는 처리 코드를 적는 자리다.
반면 선언문 태그는 현재 페이지에서 계속 사용할 멤버 변수나 메서드를 정의하는 자리다.
즉, 둘 다 코드 태그이기는 하지만 저장 위치와 목적이 다르다.
- 선언문 태그는 준비용이다.
- 스크립트릿 태그는 실행용이다.
- 선언문 태그의 변수는 멤버 변수처럼 동작한다.
- 스크립트릿 태그의 변수는 지역 변수처럼 동작한다.
이 차이를 정확히 구분해야 뒤에서 값이 왜 누적되는지, 왜 어떤 메서드는 선언문 태그 안에 두는지가 자연스럽게 이해된다.
멤버 변수와 지역 변수는 어떻게 다른가
선언문 태그 안에 만든 변수는 멤버 변수처럼 동작한다.
즉, 변환된JSP프로그램 바깥쪽 구성 요소로 들어간다고 이해하면 된다.
반면 스크립트릿 태그 안에서 만든 변수는 요청을 처리하는 메서드 안의 지역 변수처럼 동작한다.
이 차이는 결과에서도 바로 드러난다.
멤버 변수는 값이 누적될 수 있지만, 지역 변수는 요청이 다시 들어오면 새로 시작한다.
그래서 둘 다 숫자 변수처럼 보여도 같은 방식으로 보면 안 된다.
- 멤버 변수는 선언문 태그 안에서 선언한다.
- 지역 변수는 스크립트릿 태그 안에서 선언한다.
- 멤버 변수는 값이 유지될 수 있다.
- 지역 변수는 요청마다 새로 만들어진다.
즉, 선언문 태그를 이해할 때는 문법 모양보다 어디에 선언되느냐가 동작을 바꾼다는 점을 먼저 봐야 한다.
예제로 보면 멤버 변수와 지역 변수 차이가 보인다
아래 예제는 선언문 태그 안의 변수와 스크립트릿 태그 안의 변수가 어떻게 다른지 가장 직접적으로 보여 준다.
member_v는 선언문 태그 안에 있고,local_v는 스크립트릿 태그 안에 있다.
즉, 같은 정수 변수처럼 보여도 저장되는 위치가 다르다.<!-- exam2.jsp --> <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title>Insert title here</title> </head> <body> <%! int member_v = 0; %> <!-- 멤버 변수 선언 --> <% int local_v = 0; <!-- 지역 변수 선언 --> member_v += 10; <!-- 멤버 변수 값 누적 --> local_v += 10; <!-- 지역 변수 값 증가 --> %> <h1>JSP의 멤버 변수와 지역 변수</h1> <hr /> <ul> <li>멤버 변수 : <%= member_v %></li> <li>지역 변수 : <%= local_v %></li> </ul> </body> </html>이 코드에서
member_v는 선언문 태그 안에 있기 때문에 새로고침을 반복하면 값이 누적될 수 있다.
반면local_v는 스크립트릿 안에서 요청마다 다시 만들어지므로 항상 같은 시작값에서 출발한다.
즉, 둘 다 변수이기는 하지만 저장 위치가 다르기 때문에 결과도 달라진다.
출력 결과는 아래와 같다.
선언문 태그로 만든 멤버 변수와 스크립트릿 안의 지역 변수는 저장 위치와 유지 방식이 다르게 동작한다.
선언문 태그는 메서드도 선언할 수 있다
선언문 태그는 변수만 선언하는 자리가 아니다.
메서드도 선언할 수 있다.
즉, 반복해서 사용할 계산 기능이나 공통 기능을 선언문 태그 안에 정의해 두고, 실제 실행은 스크립트릿 태그에서 하는 구조로 만들 수 있다.
이 점이 중요하다.
선언문 태그는 단순히 값을 저장하는 곳이 아니라, 현재 페이지에서 함께 사용할 기능까지 미리 준비하는 자리이기 때문이다.
- 선언문 태그 안에서는 메서드도 정의할 수 있다.
- 공통 계산 기능을 미리 만들어 둘 수 있다.
- 실제 호출과 분기는 스크립트릿 태그에서 이루어질 수 있다.
즉, 선언문 태그는 값만 담는 공간이 아니라, 현재 페이지에서 사용할 기능까지 정의할 수 있는 준비 공간이다.
예제로 보면 메서드 선언도 가능하다
아래 예제는 선언문 태그로
multiply()메서드를 정의하고, 스크립트릿 태그에서 그 메서드를 호출하는 흐름을 보여 준다.
처음GET요청일 때는 입력 폼을 보여 주고,POST요청이 들어오면 전달된 두 수를 읽어서 곱한 결과를 출력한다.
즉, 선언문 태그는 메서드를 준비하고, 스크립트릿 태그는 실제 처리 흐름을 만드는 구조다.<!-- exam5.jsp --> <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> </head> <body> <h1>선언문 태그</h1> <hr> <%!int multiply(int n1, int n2) { return n1 * n2; }%> <!-- 두 수를 곱하는 메서드 선언 --> <% int result = 0; <!-- 결과를 저장할 변수 --> if (request.getMethod().equals("GET")) { <!-- 처음 들어오면 입력 폼 출력 --> %> <h3>숫자 2개를 입력하세요</h3> <form method="post" action="/edu/jspexam/exam5.jsp"> 숫자 1 <input type="number" name="su1"><br> 숫자 2 <input type="number" name="su2"><br> <input type="submit"> </form> <% } else { int su1 = Integer.parseInt(request.getParameter("su1")); <!-- 첫 번째 숫자 읽기 --> int su2 = Integer.parseInt(request.getParameter("su2")); <!-- 두 번째 숫자 읽기 --> result = multiply(su1, su2); <!-- 선언문 태그에서 만든 메서드 호출 --> %> <h2>수행 결과 : <%=result%></h2> <a href="<%=request.getHeader("referer")%>"> 입력 화면으로 </a> <% } %> </body> </html>이 예제의 핵심은
multiply()가 선언문 태그 안에 있다는 점이다.
즉, 메서드는 선언문 태그에서 준비하고, 실제 요청 처리와 분기는 스크립트릿에서 이루어진다.
이 흐름을 보면 선언문 태그가 단순한 변수 선언 자리가 아니라, 페이지 안에서 사용할 공통 기능을 정의하는 자리라는 점이 더 분명해진다.
출력 결과는 아래와 같다.
선언문 태그는 변수뿐 아니라 메서드도 선언할 수 있고, 그 메서드는 스크립트릿 태그 안에서 호출해서 사용할 수 있다.
여기서 먼저 잡아야 할 핵심
이 구간에서 가장 중요하게 기억해야 할 것은 아래 내용이다.
- 선언문 태그는
<%! %>형태로 작성한다.- 선언문 태그는 멤버 변수와 메서드를 선언하는 데 사용한다.
- 선언문 태그의 변수는 멤버 변수처럼 동작하고, 스크립트릿 태그의 변수는 지역 변수처럼 동작한다.
- 선언문 태그는 준비용이고, 실제 실행과 분기는 보통 스크립트릿 태그에서 이루어진다.
선언문 태그와 스크립트릿 태그는 둘 다
Java코드를 적는다는 점은 같지만, 저장 위치와 역할은 다르다.
이 차이를 정확히 구분해야 다음에 나오는 표현식 태그와도 자연스럽게 비교할 수 있다.
3-11. 표현식 태그
JSP의 표현식 태그는<%= %>형태로 작성한다.
이 태그는 계산된 값이나 변수 값을 화면에 바로 출력할 때 사용하는 태그다.
즉, 긴 처리 흐름을 만드는 태그가 아니라, 이미 준비된 결과를 브라우저에 보여 주는 태그라고 이해하면 된다.
선언문 태그가 준비를 위한 태그였다면, 표현식 태그는 보여 주기 위한 태그다.
그래서JSP를 처음 배울 때 가장 자주 보게 되는 태그 중 하나이기도 하다.
현재 값, 계산 결과, 요청값, 내장 객체에서 꺼낸 정보를 화면에 바로 끼워 넣을 수 있기 때문이다.
표현식 태그는 무엇을 하는가
표현식 태그는 말 그대로 식의 결과를 출력한다.
즉, 숫자 하나, 변수 하나, 계산식 하나, 메서드 호출 결과 하나를 화면에 바로 붙이는 데 알맞다.
여기서 중요한 점은 표현식 태그가 처리 흐름을 만드는 태그가 아니라는 것이다.
if,for처럼 실행 순서를 바꾸는 역할은 하지 않는다.
그런 흐름은 스크립트릿 태그가 맡고, 표현식 태그는 이미 계산된 결과를 화면에 보여 주는 역할을 맡는다.
- 변수 값을 바로 출력할 수 있다.
- 계산 결과를 바로 출력할 수 있다.
- 요청값이나 내장 객체의 값도 출력할 수 있다.
즉, 표현식 태그는
JSP안에서 화면에 보여 줄 데이터를 가장 간단하게 출력하는 태그라고 보면 된다.
왜 출력용 태그로 따로 구분해야 하는가
처음 보면 표현식 태그도 그냥
Java코드를 쓰는 태그처럼 보일 수 있다.
하지만 선언문 태그나 스크립트릿 태그와는 역할이 다르다.
선언문 태그는 준비를 위한 태그이고, 스크립트릿 태그는 처리 흐름을 만드는 태그다.
반면 표현식 태그는 결과를 보여 주는 태그다.
즉, 이 태그는 무언가를 오래 저장하거나, 조건을 분기하거나, 반복을 만드는 역할이 아니다.
지금 현재 계산된 값을 응답 화면에 그대로 붙여 넣는 역할에 집중한다.
- 선언문 태그는 준비용이다.
- 스크립트릿 태그는 처리용이다.
- 표현식 태그는 출력용이다.
이 차이를 정확히 알아야 뒤에서 스크립트릿 태그와 표현식 태그를 섞어 쓸 때도 헷갈리지 않는다.
어떤 값까지 출력할 수 있는가
표현식 태그는 생각보다 다양한 값을 출력할 수 있다.
숫자도 가능하고, 문자열도 가능하고, 계산 결과도 가능하다.
요청 파라미터, 세션 정보, 애플리케이션 정보처럼 내장 객체에서 얻은 값도 출력할 수 있다.
즉, 화면에 보여 줄 수 있는 값이라면 대부분 표현식 태그로 연결할 수 있다고 보면 된다.
이 점 때문에 표현식 태그는JSP에서 아주 자주 쓰인다.
- 숫자와 문자열을 출력할 수 있다.
- 계산식 결과를 출력할 수 있다.
- 요청값과 세션 정보도 출력할 수 있다.
- 내장 객체에서 꺼낸 값도 출력할 수 있다.
즉, 표현식 태그는 화면에 보여 줄 수 있는 값을 바로 연결하는 태그라고 이해하면 된다.
예제로 보면 출력 범위가 한눈에 보인다
아래 예제는 표현식 태그가 어떤 값을 출력할 수 있는지 한 번에 보여 준다.
숫자, 변수, 계산식, 문자열 길이, 불린 결과, 요청 파라미터, 세션 생성 시각, 애플리케이션 정보까지 모두 표현식 태그로 출력하고 있다.<!-- exam3.jsp --> <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title>Insert title here</title> </head> <body> <h1>표현식 태그 점검</h1> <hr /> <% int num = 10; %> <!-- 출력에 사용할 지역 변수 준비 --> <ul> <li><%= 100 %></li> <!-- 숫자 값 출력 --> <li><%= num %></li> <!-- 변수 값 출력 --> <li><%= ++num %></li> <!-- 증가된 변수 값 출력 --> <li><%= num*2 %></li> <!-- 계산 결과 출력 --> <li><%= "가나다".length() %></li> <!-- 문자열 길이 출력 --> <li><%= num % 2 == 0 %></li> <!-- 조건식 결과 출력 --> <li><%= request.getParameter("stname") %></li> <!-- 요청 파라미터 값 출력 --> <li><%= new java.util.Date(session.getCreationTime()) %></li> <!-- 세션 생성 시각 출력 --> <li><%= application.getServerInfo() %></li> <!-- 서버 정보 출력 --> <li><%= application.getContextPath() %></li> <!-- 컨텍스트 경로 출력 --> </ul> </body> </html>이 예제에서 중요한 점은 표현식 태그가 단순히 숫자 하나만 출력하는 문법이 아니라는 것이다.
이미 계산할 수 있는 값이라면 거의 모두 출력할 수 있다.
즉, 화면에 보여 줄 데이터만 준비되어 있다면 표현식 태그로 바로 연결할 수 있다.
출력 결과는 아래와 같다.
이 이미지는
stname파라미터 값을 함께 전달해서 실행한 결과다.
그래서 표현식 태그가 숫자, 계산 결과, 서버 정보뿐 아니라 전달된 요청 파라미터 값까지 함께 출력하는 모습을 확인할 수 있다.
파라미터 값을 전달하지 않으면 어떻게 되는가
표현식 태그는 값을 예쁘게 가공해서 보여 주는 태그가 아니다.
현재 계산된 결과를 그대로 출력하는 태그다.
그래서 값이 없으면 그 결과도 그대로 드러난다.
예를 들어request.getParameter("stname")는 요청값이 전달되면 해당 값을 출력한다.
하지만 요청값이 없으면null이 그대로 보일 수 있다.
즉, 표현식 태그는 출력은 간단하지만, 값이 실제로 들어 있는지까지 대신 판단해 주지는 않는다.
- 값이 있으면 그 값을 그대로 출력한다.
- 값이 없으면
null같은 결과가 그대로 보일 수 있다.- 필요한 경우에는 먼저 값 존재 여부를 확인하는 처리가 필요하다.
즉, 표현식 태그는 출력 전용 태그이기 때문에, 값 검사는 별도의 처리 흐름에서 해야 한다.
출력 결과는 아래와 같다.
이 이미지는
stname파라미터 값을 전달하지 않고 실행한 결과다.
그래서request.getParameter("stname")부분에 값이 아니라null이 그대로 출력된다.
이 점을 보면 표현식 태그는 현재 결과를 그대로 보여 줄 뿐, 값이 없는 상황을 따로 처리해 주지는 않는다는 것을 알 수 있다.
여기서 먼저 잡아야 할 핵심
이 구간에서 가장 중요하게 기억해야 할 것은 아래 내용이다.
- 표현식 태그는
<%= %>형태로 작성한다.- 표현식 태그는 계산된 값을 화면에 바로 출력하는 태그다.
- 숫자, 문자열, 계산 결과, 요청값, 내장 객체 값까지 다양하게 출력할 수 있다.
- 요청 파라미터가 전달되면 그 값이 출력되고, 전달되지 않으면
null이 그대로 보일 수 있다.표현식 태그는 처리 흐름을 만드는 태그가 아니라, 이미 준비된 결과를 화면에 붙이는 출력 전용 태그다.
이 기준이 잡혀야 다음에 나오는 스크립트릿 태그와의 차이도 훨씬 분명하게 보인다.
3-12. 스크립트릿 태그
JSP의 스크립트릿 태그는<% %>형태로 작성한다.
이 태그는 값을 바로 출력하는 용도보다, 실제 처리 흐름을 만드는 데 사용하는 태그다.
즉, 조건문, 반복문, 변수 선언, 요청값 처리처럼 화면 뒤에서 실제로 움직이는 코드를 적는 자리라고 이해하면 된다.
앞에서 본 표현식 태그가 결과를 보여 주는 태그였다면, 스크립트릿 태그는 그 결과가 나오기까지의 과정을 만드는 태그다.
그래서JSP안에서 동적인 화면을 만들려면 스크립트릿 태그가 어떤 역할을 하는지 정확히 알아야 한다.
스크립트릿 태그는 무엇을 하는가
스크립트릿 태그는
JSP안에 일반Java실행문을 적을 수 있게 해 준다.
즉, 단순히 값 하나를 출력하는 수준이 아니라, 요청값을 읽고, 조건을 검사하고, 반복을 돌리고, 필요한 처리 흐름을 직접 만들 수 있다.
이 태그가 있기 때문에JSP는 단순히 값을 끼워 넣는 문서를 넘어서, 입력값에 따라 다른 결과를 만들어 내는 동적인 페이지가 될 수 있다.
- 변수 선언을 할 수 있다.
if문과for문 같은 제어문을 사용할 수 있다.- 요청값을 읽고 필요한 계산을 할 수 있다.
- 상황에 따라 다른 화면 결과를 만들 수 있다.
즉, 스크립트릿 태그는
JSP안에서 실제 처리 흐름을 담당하는 태그다.
표현식 태그와 무엇이 다른가
표현식 태그도
Java와 연결되고, 스크립트릿 태그도Java와 연결된다.
그래서 처음에는 둘이 비슷해 보일 수 있다.
하지만 역할은 분명히 다르다.
표현식 태그는 이미 계산된 값을 화면에 출력하는 태그다.
반면 스크립트릿 태그는 그 값을 만들기 위한 과정 자체를 작성하는 태그다.
즉, 표현식 태그는 결과를 보여 주고, 스크립트릿 태그는 결과가 나오기까지의 흐름을 만든다.
- 표현식 태그는 출력용이다.
- 스크립트릿 태그는 처리용이다.
- 표현식 태그는 결과를 붙인다.
- 스크립트릿 태그는 조건과 반복 같은 흐름을 만든다.
이 차이를 정확히 구분해야
JSP코드에서 무엇이 출력이고 무엇이 처리인지 헷갈리지 않게 된다.
왜 스크립트릿 태그가 필요한가
화면에 보여 줄 값이 이미 다 준비되어 있다면 표현식 태그만으로도 어느 정도는 가능하다.
하지만 실제 웹 페이지는 그보다 더 많은 처리가 필요하다.
입력값을 읽고, 값이 올바른지 검사하고, 반복해서 여러 줄을 만들고, 상황에 따라 다른 문장을 보여 주어야 할 수도 있다.
이런 동작은 단순 출력만으로는 처리할 수 없다.
그래서 실제 흐름을 작성할 수 있는 스크립트릿 태그가 필요하다.
- 사용자가 보낸 값을 읽을 수 있어야 한다.
- 값이 올바른지 검사할 수 있어야 한다.
- 반복문으로 여러 줄을 만들어 낼 수 있어야 한다.
- 조건에 따라 다른 화면을 보여 줄 수 있어야 한다.
즉, 스크립트릿 태그는 화면 뒤에서 실제로 동작을 만드는 태그이기 때문에 필요하다.
예제로 보면 처리 흐름이 더 잘 보인다
아래 예제는 스크립트릿 태그가 실제로 어떤 역할을 하는지 가장 잘 보여 주는 예제다.
사용자가 전달한dan값을 숫자로 바꾸고, 그 값이1부터9사이인지 검사한 뒤, 맞으면for문으로 구구단을 출력하고, 범위를 벗어나면 안내 문구를 보여 준다.
즉, 이 한 파일 안에서 요청값 읽기, 조건 검사, 반복 출력이 모두 이루어진다.<!-- exam6.jsp --> <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>JSP로 구현한 구구단</title> </head> <body> <h2>JSP로 구현한 구구단</h2> <% int dan = Integer.parseInt(request.getParameter("dan")); %> <!-- 전달된 dan 값을 숫자로 변환 --> <% if (dan >= 1 && dan <= 9) { %> <!-- 1부터 9 사이인지 먼저 검사 --> <% for (int i = 1; i <= 9; i++) { %> <!-- 표현식 태그로 구구단 한 줄씩 출력 --> <%=dan%> x <%=i%> = <%=dan * i%><br> <% } %> <hr> <% for (int i = 1; i <= 9; i++) { out.print(dan + " x " + i + " = " + dan * i + "<br>"); } %> <!-- 이번에는 out.print()로 다시 출력 --> <% } else { %> <h3 style="color: red">1에서 9사이의 값을 입력해 주세요..</h3> <% } %> </body> </html>이 예제의 핵심은 스크립트릿 태그 안에서 처리 흐름이 움직인다는 점이다.
request.getParameter("dan")으로 요청값을 읽고,Integer.parseInt()로 숫자로 바꾸고,if문으로 범위를 검사하고,for문으로 구구단을 출력한다.
즉, 화면에 보이는 결과는 표현식 태그와out.print()로 나타나지만, 그 결과를 만들기까지의 실제 흐름은 스크립트릿 태그 안에 있다.
출력 결과는 아래와 같다.
이 이미지는
dan값이 정상적으로 전달된 경우의 결과다.
그래서 스크립트릿 태그 안의if문과for문이 정상적으로 실행되어 구구단이 화면에 출력된다.
같은 결과를 두 방식으로 출력하고 있다
이 예제는 단순히 구구단만 보여 주는 것이 아니다.
같은 결과를 두 방식으로 출력하고 있다는 점도 중요하다.
위쪽은 표현식 태그를 사용해서 출력했고, 아래쪽은out.print()를 사용해서 출력했다.
즉, 스크립트릿 태그는 처리 흐름만 담당하는 것이 아니라, 필요하면 직접 출력 코드와도 연결될 수 있다.
이 점을 보면 표현식 태그와out.print()가 결국 같은 응답 생성 흐름 안에 있다는 것도 함께 이해할 수 있다.
- 위쪽 구구단은 표현식 태그로 출력한다.
- 아래쪽 구구단은
out.print()로 출력한다.- 둘 다 결국 브라우저에 응답을 보내는 같은 흐름이다.
즉, 표현식 태그와
out.print()는 문법은 다르지만 둘 다 화면 출력을 만든다는 점에서 연결되어 있다.
잘못된 범위가 들어오면 어떻게 되는가
스크립트릿 태그 안에서는 조건을 검사해서 다른 결과를 보여 줄 수도 있다.
이 예제에서는dan값이1부터9사이가 아니면 구구단을 출력하지 않고 빨간 안내 문구를 보여 준다.
즉, 스크립트릿 태그는 상황에 따라 다른 화면을 만들 수 있다.
- 올바른 범위면 구구단을 출력한다.
- 범위를 벗어나면 안내 문구를 보여 준다.
- 조건에 따라 결과 화면이 달라진다.
이 점이 바로 스크립트릿 태그가 처리용 태그라는 것을 보여 준다.
출력 결과는 아래와 같다.
이 이미지는
dan값이1부터9사이가 아닌 경우의 결과다.
그래서 스크립트릿 태그 안의 조건 검사에 의해 구구단 대신 안내 문구가 출력된다.
요청값이 아예 없으면 예외가 날 수 있다
이 예제에서 하나 더 봐야 할 부분은 예외 상황이다.
현재 코드는 먼저request.getParameter("dan")값을 가져오고, 바로Integer.parseInt()를 수행한다.
그런데 요청 파라미터가 아예 없으면 숫자로 바꿀 값이 없기 때문에 여기서 예외가 발생할 수 있다.
즉, 스크립트릿 태그는 처리 흐름을 직접 다루는 만큼, 잘못된 입력이나 예외 상황도 함께 생각해야 한다.
이 점에서 표현식 태그보다 더 강한 기능을 가지지만, 그만큼 더 조심해서 써야 한다.
- 요청값이 없으면 숫자 변환 단계에서 문제가 날 수 있다.
- 조건 검사 전에 이미 예외가 발생할 수 있다.
- 처리 흐름을 직접 다룰수록 예외 상황도 같이 확인해야 한다.
즉, 스크립트릿 태그는 강력한 만큼 입력값 검증과 예외 처리도 함께 신경 써야 한다.
출력 결과는 아래와 같다.
이 이미지는
dan파라미터 값이 아예 전달되지 않은 상태에서 실행한 결과다.
그래서 범위 검사까지 가기 전에 숫자 변환 단계에서 예외가 발생한 모습을 확인할 수 있다.
여기서 먼저 잡아야 할 핵심
이 구간에서 가장 중요하게 기억해야 할 것은 아래 내용이다.
- 스크립트릿 태그는
<% %>형태로 작성한다.- 스크립트릿 태그는 조건문, 반복문, 변수 선언, 요청값 처리처럼 실제 실행 흐름을 만드는 태그다.
- 표현식 태그가 결과를 출력한다면, 스크립트릿 태그는 그 결과가 나오기까지의 과정을 만든다.
- 처리 흐름을 직접 다루는 만큼, 잘못된 입력과 예외 상황도 함께 생각해야 한다.
스크립트릿 태그는
JSP안에서 실제로 움직이는 자바 코드 구간이다.
이 기준이 잡혀야 다음에 나오는 액션 태그와 내장 객체도 더 자연스럽게 이해할 수 있다.
3-13. 액션 태그
JSP의 액션 태그는<jsp:...>형태로 작성하는 기능성 태그다.
지시자 태그가 페이지의 처리 조건을 정하는 태그였다면, 액션 태그는 실행 과정에서 정해진 기능을 직접 수행하는 태그라고 보면 된다.
즉, 다른 페이지로 처리를 넘기거나, 다른 자원의 결과를 포함하거나, 객체를 만들고 값을 넣고 꺼내는 기능을 태그 형태로 사용할 수 있게 해 주는 문법이다.
여기서 중요한 점은 액션 태그가include지시자와 다르다는 것이다.
include지시자는 파일 내용을 미리 합쳐 넣는다.
반면 액션 태그는 실행 중에 기능을 수행한다.
즉, 비슷해 보여도 처리 시점이 다르다.
액션 태그는 무엇을 하는가
액션 태그는
JSP가 미리 준비해 둔 기능을 태그 형태로 실행하는 문법이다.
즉, 직접 긴Java코드를 적지 않아도, 특정 기능을 바로 사용할 수 있게 만든 태그다.
대표적으로 많이 보는 것은jsp:forward,jsp:include,jsp:useBean,jsp:setProperty,jsp:getProperty다.
이 중에서 지금 예제에서는jsp:forward와jsp:include가 중심이고,useBean계열은 마지막에 흐름만 정리해 두면 된다.
jsp:forward는 다른 자원으로 처리를 넘긴다.jsp:include는 다른 자원의 실행 결과를 현재 페이지에 포함한다.jsp:useBean은 객체를 준비한다.jsp:setProperty는 객체에 값을 넣는다.jsp:getProperty는 객체의 값을 꺼내서 보여 준다.즉, 액션 태그는 설정용 태그가 아니라 실행 중에 동작을 수행하는 태그라고 이해하면 된다.
jsp:forward는 무엇을 하는가
jsp:forward는 현재 페이지가 직접 응답하지 않고, 다른 페이지가 대신 응답하도록 처리를 넘기는 액션 태그다.
즉, 지금 페이지는 중간에서 분기만 하고, 실제 결과 화면은 다른 페이지가 만들게 하는 방식이다.
이 태그는 조건에 따라 다른 결과 페이지를 보여 주고 싶을 때 잘 어울린다.
예를 들어 관리자면 관리자 화면으로 보내고, 일반 사용자면 사용자 화면으로 보내는 식이다.
또jsp:param을 함께 쓰면, 넘겨 주는 페이지에 추가 파라미터도 전달할 수 있다.
- 현재 페이지가 직접 응답하지 않는다.
- 다른 페이지가 대신 최종 화면을 만든다.
jsp:param으로 추가 데이터를 함께 전달할 수 있다.즉,
jsp:forward는 분기하고 넘기는 태그라고 보면 된다.
예제로 보면
jsp:forward가 더 잘 보인다아래 예제는
type파라미터 값에 따라 다른 페이지로 이동시키는 코드다.
type이 없거나admin이면admin_new.jsp로 넘기고, 그 외에는user_new.jsp로 넘긴다.
이때message값도 함께 전달하고 있다.<!-- exam10.jsp --> <%@ page contentType="text/html; charset=utf-8" %> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>forward 액션 태그를 이용한 분기 예제</title> </head> <body> <% if (request.getParameter("type") == null || request.getParameter("type").equals("admin")) { %> <!-- 관리자 화면으로 전달 --> <jsp:forward page="admin_new.jsp"> <jsp:param name="message" value="Hi! Administrator" /> <!-- 함께 전달할 파라미터 --> </jsp:forward> <% } else { %> <!-- 일반 사용자 화면으로 전달 --> <jsp:forward page="user_new.jsp"> <jsp:param name="message" value="Hi! User" /> <!-- 함께 전달할 파라미터 --> </jsp:forward> <% } %> </body> </html>이 코드는 현재 페이지가 직접 결과를 만들지 않는다.
조건만 검사한 뒤, 실제 결과를 보여 줄 페이지로 넘긴다.
즉, 이 예제의 핵심은exam10.jsp가 최종 화면 역할을 하지 않고, 분기 역할만 한다는 점이다.<!-- admin_new.jsp --> <%@ page contentType="text/html; charset=utf-8" %> <html> <head> <title>관리자 화면</title> </head> <body> 관리자님 환영합니다. <br /> 이 화면은 관리자를 위한 화면입니다. <br /> 전달된 파라미터 : <span style="color: blue"><%= request.getParameter("message") %></span> <!-- 전달받은 message 값 출력 --> </body> </html><!-- user_new.jsp --> <%@ page contentType="text/html; charset=utf-8" %> <!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title>user화면</title> </head> <body> 일반 사용자님 환영합니다. <br /> 이 화면은 사용자를 위한 화면입니다. <br /> 전달된 파라미터 : <span style="color: red"><%= request.getParameter("message") %></span> <!-- 전달받은 message 값 출력 --> </body> </html>출력 결과는 아래와 같다.
이 이미지는
type=admin으로 요청했을 때의 결과다.
주소창은exam10.jsp?type=admin그대로인데, 실제 화면 내용은admin_new.jsp가 대신 만든 결과가 출력된다.
즉,forward는 브라우저가 새로 다른 주소를 요청한 것이 아니라, 서버 안에서 처리를 넘긴 것이다.
이 이미지는
type=user1로 요청했을 때의 결과다.
이번에는else구간이 실행되어user_new.jsp가 대신 응답하고, 함께 전달한message값도 화면에 출력된다.
즉,jsp:forward는 조건에 따라 다른 페이지가 최종 응답을 맡도록 만들 수 있다.
jsp:include는 무엇을 하는가
jsp:include는 다른 자원의 실행 결과를 현재 페이지 안에 포함시키는 액션 태그다.
즉, 현재 페이지를 버리고 다른 페이지로 완전히 넘기는 것이 아니라, 다른 자원이 만든 결과를 끼워 넣어서 함께 응답하는 방식이다.
여기서 중요한 점은 이 태그가include지시자와 다르다는 것이다.
include지시자는 파일 내용을 미리 합친다.
반면jsp:include는 실행하는 순간 다른 자원의 결과를 가져와 현재 페이지 안에 포함한다.
또jsp:param을 함께 쓰면 포함되는 자원에 값도 전달할 수 있다.
- 현재 페이지는 그대로 유지된다.
- 다른 자원의 결과만 현재 페이지 안에 포함된다.
- 실행 중에 포함이 일어난다.
jsp:param으로 포함 대상에 값을 전달할 수 있다.즉,
jsp:include는 실행 중에 결과를 끼워 넣는 태그라고 이해하면 된다.
예제로 보면
jsp:include도 쉽게 보인다아래 예제는
greeting.jsp를 세 번 포함하면서, 매번 다른country값을 전달하는 코드다.
즉, 같은 페이지를 재사용하지만 전달하는 파라미터를 바꾸어서 다른 결과를 얻고 있다.<!-- exam11.jsp --> <%@ page contentType="text/html; charset=utf-8" %> <!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title>INCLUDE 액션태그 예제</title> </head> <body> <h3>INCLUDE 액션태그 예제</h3> <h4>각 나라의 감사 인사말입니다.</h4> <p> 한국어 : <jsp:include page="greeting.jsp"> <jsp:param name="country" value="korea" /> <!-- 한국어 값 전달 --> </jsp:include> </p> <p> 영어 : <jsp:include page="greeting.jsp"> <jsp:param name="country" value="english" /> <!-- 영어 값 전달 --> </jsp:include> </p> <p> 일본어 : <jsp:include page="greeting.jsp"> <jsp:param name="country" value="japan" /> <!-- 일본어 값 전달 --> </jsp:include> </p> </body> </html>이 코드는 현재 페이지 안에서
greeting.jsp를 세 번 불러오고 있다.
하지만 매번 같은 결과가 나오는 것이 아니라, 전달하는 파라미터가 다르기 때문에 포함되는 결과도 달라진다.
즉,jsp:include는 같은 자원을 반복해서 사용하면서도 상황에 따라 다른 결과를 포함할 수 있다.<!-- greeting.jsp --> <%@ page contentType="text/html; charset=utf-8"%> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>감사인사</title> </head> <body> <% if (request.getParameter("country").equals("korea")) { %> <!-- 한국어 인사말 출력 --> <%= "감사합니다." %> <% } else if (request.getParameter("country").equals("english")) { %> <!-- 영어 인사말 출력 --> <%= "Thank You." %> <% } else if (request.getParameter("country").equals("japan")) { %> <!-- 일본어 인사말 출력 --> <%= "ありがとうございます" %> <% } %> </body> </html>이 예제에서
greeting.jsp는 현재 페이지 안에 포함되어 결과 일부를 만들어 주는 역할로 사용된다.
즉, 여기서는jsp:include가 다른 자원의 실행 결과를 현재 화면 안에 끼워 넣는 흐름 자체를 확인하는 데 초점을 두면 된다.
이 이미지는
exam11.jsp실행 결과다.
현재 페이지 안에greeting.jsp의 결과가 세 번 포함되어, 한국어, 영어, 일본어 감사 인사말이 각각 다른 값으로 출력된다.
즉,jsp:include는 현재 페이지를 유지하면서 다른 자원의 결과를 끼워 넣는 방식이라는 점이 화면으로 드러난다.
include지시자와jsp:include는 어떻게 다른가둘 다 다른 내용을 현재 페이지에 넣는다는 점에서는 비슷해 보인다.
하지만 핵심은 처리 시점이 다르다는 점이다.
include지시자는 변환 과정에서 파일 내용을 미리 합친다.
반면jsp:include는 실행 중에 다른 자원의 결과를 가져와 포함한다.
즉, 하나는 파일 자체를 미리 붙여 넣는 방식이고, 다른 하나는 실행 결과를 그때그때 가져오는 방식이다.
이 차이가 정확히 잡혀야 두 문법을 헷갈리지 않는다.
include지시자는 파일 내용을 미리 합친다.jsp:include는 실행 결과를 포함한다.include지시자는 정적인 공통 조각에 더 잘 어울린다.jsp:include는 실행 시점에 따라 바뀌는 결과를 포함할 때 더 잘 어울린다.즉, 둘 다 포함이지만 미리 합치는 방식인지, 실행 중 결과를 끼워 넣는 방식인지가 다르다.
비교 예제로 보면 차이가 더 분명하다
아래 예제는
include지시자와jsp:include액션 태그를 한 화면에서 비교해서 보여 주기 위한 예제다.
위쪽 두 줄은include지시자로 포함한 결과이고, 아래쪽 두 줄은jsp:include로 포함한 결과다.
즉, 둘 다 같은exam9.jsp를 이용하지만 처리 방식이 다르다는 점을 비교하는 구조다.<!-- exam12.jsp --> <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title>JSP 예제</title> </head> <body> <h2>include 지시자와 액션태그 비교</h2> <hr /> <%@ include file="exam9.jsp" %> <!-- 변환 과정에서 파일 내용을 미리 합침 --> <hr /> <%@ include file="exam9.jsp" %> <!-- 같은 파일을 한 번 더 미리 포함 --> <hr /> <jsp:include page="exam9.jsp" /> <!-- 실행 중 exam9.jsp 결과를 포함 --> <hr /> <jsp:include page="exam9.jsp" /> <!-- 실행 중 같은 결과를 다시 포함 --> </body> </html>현재 업로드된
exam12.jsp파일은 지시자include부분이 주석 처리되어 있다.
하지만 아래 이미지처럼 비교 결과를 보여 주려면 지시자include부분이 실제로 실행되도록 작성되어 있어야 한다.
즉, 이 비교 예제는 지시자include와 액션 태그jsp:include를 나란히 배치해서 결과를 비교하는 용도라고 보면 된다.
출력 결과는 아래와 같다.
이 화면은
include지시자와jsp:include액션 태그를 한 번에 비교한 결과다.
위쪽 두 줄은 지시자include로 포함한 결과이고, 아래쪽 두 줄은jsp:include로 포함한 결과다.
즉, 눈으로 보기에는 비슷해 보여도, 처리 시점은 서로 다르다는 점을 이 예제로 정리할 수 있다.
jsp:useBean,jsp:setProperty,jsp:getProperty는 어떤 흐름인가액션 태그에는 포함과 전달만 있는 것이 아니다.
객체를 다루는 태그도 있다.
jsp:useBean은 객체를 준비하고,jsp:setProperty는 그 객체에 값을 넣고,jsp:getProperty는 그 값을 꺼내서 화면에 보여 준다.
즉, 흐름은 객체 준비 → 값 저장 → 값 출력이다.
이 태그들은JSP안에서 값을 따로따로 흩어 놓지 않고, 객체 단위로 묶어서 다루고 싶을 때 사용한다.
지금 예제는forward와include중심이지만, 액션 태그 범위를 이해할 때는 이 객체 관련 태그들도 함께 기억해 두는 것이 좋다.
jsp:useBean은 객체를 준비한다.jsp:setProperty는 객체에 값을 넣는다.jsp:getProperty는 객체 값을 화면에 출력한다.즉, 액션 태그는 페이지 이동이나 포함만 담당하는 것이 아니라, 객체를 다루는 기능까지 포함하는 태그 집합이다.
여기서 먼저 잡아야 할 핵심
이 구간에서 가장 중요하게 기억해야 할 것은 아래 내용이다.
- 액션 태그는
<jsp:...>형태로 작성하는 기능성 태그다.jsp:forward는 다른 페이지가 대신 응답하도록 처리를 넘긴다.jsp:include는 다른 자원의 실행 결과를 현재 페이지 안에 포함한다.jsp:param은forward나include와 함께 추가 값을 전달할 때 사용한다.
*include지시자와jsp:include는 이름은 비슷하지만 처리 시점이 다르다.jsp:useBean,jsp:setProperty,jsp:getProperty는 객체 준비, 값 저장, 값 출력 흐름을 만든다.액션 태그는 실행 중에 정해진 기능을 수행하는 태그이고, 특히
forward와include는 현재 페이지와 다른 자원을 어떻게 연결할지를 결정하는 핵심 태그다.
이 기준이 잡혀야 마지막 내장 객체 구간도 훨씬 자연스럽게 이어진다.
3-14. JSP 내장 객체
JSP에서는 자주 쓰는 객체들을 따로 만들지 않아도 바로 사용할 수 있다.
이렇게JSP실행 환경이 미리 준비해 두는 객체를 내장 객체라고 한다.
즉, 요청 정보, 응답 정보, 세션 정보, 출력 기능처럼 웹 처리에서 자주 필요한 기능을 바로 꺼내 쓸 수 있게 해 둔 것이다.
처음JSP를 보면request,response,session,application,out같은 이름이 갑자기 나와서 헷갈릴 수 있다.
하지만 이 객체들은 갑자기 생긴 것이 아니라, 서버가JSP를 실행할 때 기본으로 준비해 주는 도구들이다.
그래서 내장 객체를 이해하면JSP가 서버 프로그램으로 어떻게 움직이는지도 함께 보이기 시작한다.
내장 객체란 무엇인가
내장 객체는 개발자가 직접
new로 만들지 않아도 바로 사용할 수 있게 준비된 객체다.
즉,JSP가 실행될 때 서버가 기본으로 만들어 주는 도구라고 보면 된다.
이 점이 중요한 이유는JSP가 단순한 문서가 아니라 서버에서 실행되는 프로그램이라는 사실을 가장 직접적으로 보여 주기 때문이다.
사용자가 보낸 값을 읽을 때는request를 쓰고, 응답 상태를 확인할 때는response를 쓰고, 로그인 상태를 유지할 때는session을 쓴다.
즉, 내장 객체는JSP안에서 웹 프로그램이 실제로 움직이게 해 주는 기본 장치다.
- 개발자가 직접 만들지 않아도 바로 사용할 수 있다.
JSP실행 환경이 기본으로 준비해 준다.- 요청, 응답, 세션, 출력 같은 기능을 바로 다룰 수 있다.
즉, 내장 객체는 외워야 할 이름 목록이 아니라,
JSP가 서버에서 어떻게 동작하는지를 보여 주는 실제 도구들이다.
request는 사용자가 보낸 요청을 읽는 객체다
request는 브라우저가 서버로 보낸 요청 정보를 읽는 객체다.
즉, 사용자가 입력한 값, 어떤 방식으로 요청했는지, 어떤 주소로 요청했는지 같은 정보를 꺼낼 때 사용한다.
내장 객체 중에서도 가장 먼저 익혀야 하는 객체가request다.
왜냐하면 폼 입력과 결과 화면이 이어지는 대부분의 흐름이request에서 시작되기 때문이다.
- 요청 파라미터를 읽을 수 있다.
- 요청 방식이
GET인지POST인지 확인할 수 있다.- 요청 주소나 헤더 정보도 확인할 수 있다.
즉,
request는 사용자가 무엇을 보내 왔는지를 읽는 기본 통로라고 보면 된다.
예제로 보면
request의 기본 사용이 바로 보인다아래 예제는
request내장 객체를 가장 단순하게 보여 주는 코드다.
사용자가 보낸name값을 읽고, 요청 방식도 함께 출력한다.
또referer헤더를 이용해서 이전 화면으로 돌아가는 링크도 만든다.<!-- exam4.jsp --> <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> </head> <body> <h1>Query 문자열 추출(GET&POST)</h1> <hr> <h2> 당신의 이름은 <%=request.getParameter("name")%> 이군요!! </h2> <!-- name 파라미터 값 출력 --> <h2> 요청방식 : <%=request.getMethod()%> </h2> <!-- 요청 방식 출력 --> <a href="<%=request.getHeader("referer")%>"> 입력 화면으로 </a> <!-- 이전 페이지 주소를 읽어서 다시 이동 --> </body> </html>이 예제에서 핵심은 세 가지다.
첫째,request.getParameter("name")으로 사용자가 보낸 값을 읽는다.
둘째,request.getMethod()로 현재 요청 방식이GET인지POST인지 확인한다.
셋째,request.getHeader("referer")로 이전 페이지 정보를 읽어서 다시 이동할 수 있게 만든다.
즉,request는 입력값만 읽는 객체가 아니라 요청 전체와 관련된 여러 정보를 다룰 수 있다.
출력 결과는 아래와 같다.
이 이미지는
name파라미터 값을 전달한 상태에서 실행한 결과다.
그래서 사용자 이름과 요청 방식이 함께 출력된다.
이 이미지는
name파라미터 값을 전달하지 않고 실행한 결과다.
이 경우에는 이름 부분에 값이 없거나null이 그대로 보일 수 있다.
즉,request.getParameter()는 값을 자동으로 보정해 주는 것이 아니라, 현재 전달된 결과를 그대로 꺼내 준다.
request는 요청 방식에 따라 다른 화면을 만들 때도 사용된다
request는 단순히 값 하나를 읽는 데서 끝나지 않는다.
요청 방식이GET인지POST인지에 따라 아예 다른 화면을 보여 주는 데도 자주 사용된다.
즉, 같은JSP파일 안에서도 처음 들어왔을 때는 입력 폼을 보여 주고, 전송한 뒤에는 결과를 보여 주는 식으로 흐름을 나눌 수 있다.
GET일 때는 입력 화면을 보여 줄 수 있다.POST일 때는 전달된 값을 읽어서 결과를 보여 줄 수 있다.- 같은 파일 안에서도 요청 방식에 따라 역할이 달라질 수 있다.
즉,
request는 단순한 값 읽기뿐 아니라, 화면 흐름을 나누는 기준으로도 많이 쓰인다.
예제로 보면
GET과POST흐름이 더 잘 보인다아래 예제는 처음
GET으로 접근하면 색상과 날짜를 선택하는 폼을 보여 주고,POST로 전송하면 전달된 값을 읽어서 화면에 반영한다.
즉,request.getMethod()와request.getParameter()를 함께 활용하는 흐름이다.<!-- exam7.jsp --> <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>요청 방식에 따른 처리</title> <style> input { margin: 3px; } </style> </head> <body> <% if (request.getMethod().equals("GET")) { %> <!-- 처음 접근하면 입력 폼을 보여 줌 --> <h2>원하는 칼라와 날짜를 선택하세요</h2> <form method="post" action="/edu/jspexam/exam7.jsp"> 칼라 : <input type="color" name="fcolor"><br> 날짜 : <input type="date" name="fdate"><br> <input type="submit" value="전송"> </form> <% } else { %> <!-- 전송 후에는 전달된 값을 읽어서 결과 화면을 만듦 --> <script> document.body.style.backgroundColor = '<%= request.getParameter("fcolor") %>'; </script> <h2> 선택 날짜는 <%= request.getParameter("fdate") %> 이네요.. </h2> <% } %> </body> </html>이 예제의 핵심은 같은 페이지가 상황에 따라 두 역할을 한다는 점이다.
처음에는 입력 폼을 보여 주는 화면으로 동작하고, 전송 후에는 전달된 값을 읽어서 결과를 보여 주는 화면으로 동작한다.
즉,request.getMethod()가 화면 흐름을 나누고,request.getParameter()가 실제 입력값을 결과 화면에 연결한다.
출력 결과는 아래와 같다.
이 이미지는 브라우저에서 결과 페이지의 소스 보기를 확인한 화면이다.
여기서document.body.style.backgroundColor = '#7a4848';처럼 전달된 색상 값이 실제 코드 안에 반영된 모습과,선택 날짜는 2026-04-30 이네요..처럼 전달된 날짜 값이 출력된 모습을 함께 확인할 수 있다.
즉,POST로 전달된 파라미터 값이 최종 응답 문서 안에 어떻게 들어갔는지를 보여 주는 화면이다.
이 이미지는 개발자도구의
Network탭에서 요청에 함께 전달된 파라미터를 확인한 화면이다.
여기서fcolor에는#7a4848,fdate에는2026-04-30값이 담겨 전송된 것을 볼 수 있다.
즉, 사용자가 입력한 값이 실제 요청 데이터로 서버에 전달되었고, 그 값이 다시request.getParameter()로 읽혀 화면 결과에 반영된다는 흐름을 확인할 수 있다.
여러 내장 객체를 한 화면에서 같이 보면 차이가 더 잘 보인다
아래 예제는
request,out,session,response,application을 한 화면에서 함께 확인하는 코드다.
즉, 각 내장 객체가 어떤 정보를 다루는지 한 번에 비교해 보는 점검용 예제라고 보면 된다.<!-- exam13.jsp --> <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" import="java.util.Date"%> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>JSP의 내장 객체들</title> </head> <body> <h2>JSP의 내장 객체들 점검</h2> <h3>[ request ]</h3> getMethod() : <%=request.getMethod()%><br> <!-- 요청 방식 출력 --> getRequestURI() : <%=request.getRequestURI()%><br> <!-- 요청 URI 출력 --> getHeader("user-agent") : <%=request.getHeader("user-agent")%><br> <!-- 브라우저 정보 출력 --> <h3>[ out ]</h3> <% out.print("<h4>out내장 객체로 출력!!</h4>"); %> <!-- out 객체로 직접 출력 --> <h3>[ session ]</h3> getId() : <%=session.getId()%><br> <!-- 세션 ID 출력 --> getCreationTime() : <%=new Date(session.getCreationTime())%><br> <!-- 세션 생성 시각 출력 --> <h3>[ response ]</h3> getStatus() : <%=response.getStatus()%><br> <!-- 응답 상태 코드 출력 --> getBufferSize() : <%=response.getBufferSize()%><br> <!-- 응답 버퍼 크기 출력 --> getContentType() : <%=response.getContentType()%> <!-- 응답 문서 형식 출력 --> <% response.addCookie(new Cookie("myCookie", "myValue")); %> <!-- 응답에 쿠키 추가 --> <h3>[ application ]</h3> getContextPath() : <%=application.getContextPath()%><br> <!-- 현재 웹 애플리케이션 경로 출력 --> getServerInfo() : <%=application.getServerInfo()%><br> <!-- 서버 정보 출력 --> getMajorVersion() : <%=application.getMajorVersion()%><br> <!-- 서블릿 메이저 버전 출력 --> <h4>Web Application(/edu) 디렉토리의 파일 리스트</h4> <% java.util.Set<String> list = application.getResourcePaths("/"); if (list != null) { Object obj[] = list.toArray(); for (int i = 0; i < obj.length; i++) { out.print(obj[i] + ", "); } } %> <!-- 애플리케이션 루트 경로의 파일 목록 출력 --> </body> </html>이 예제에서는
response.addCookie(new Cookie("myCookie", "myValue"));를 사용하고 있으므로,
실제로 실행하려면Cookie클래스에 대한import가 함께 필요하다.
즉, 이 코드는response객체가 쿠키를 응답에 추가하는 방식까지 함께 보여 주는 예제라고 보면 된다.
이 예제의 핵심은 내장 객체를 따로따로 외우는 것이 아니라, 어떤 객체가 어떤 종류의 정보를 다루는지 한 화면에서 비교해 보는 데 있다.
request는 요청 자체를 보여 주고,out은 직접 출력하는 역할을 보여 주고,session은 사용자별 상태 정보를 보여 주고,response는 응답 정보를 보여 주고,application은 서버와 애플리케이션 차원의 정보를 보여 준다.
즉, 각 객체가 맡는 역할이 분명히 나뉘어 있다는 점이 이 예제에서 한 번에 드러난다.
출력 결과는 아래와 같다.
이 화면을 보면
request에서는 요청 방식, 요청 주소,user-agent같은 요청 정보가 보인다.
out에서는 직접 출력한 문장이 보이고,session에서는 세션 ID와 생성 시각이 보인다.
또response에서는 상태 코드와 버퍼 크기, 문서 형식이 보이고,application에서는 컨텍스트 경로와 서버 정보, 파일 목록까지 확인할 수 있다.
즉, 내장 객체는 각각 꺼내는 정보 종류가 다르다는 점이 결과 화면에서 그대로 드러난다.
session객체를 따로 보면 상태 유지 개념이 더 잘 보인다내장 객체 중에서도
session은 특히 중요하다.
왜냐하면 웹은 기본적으로 요청이 끝나면 연결 상태를 계속 기억하지 않는 구조이기 때문이다.
그래서 로그인 상태처럼 사용자별로 기억해야 하는 정보를 잠시 유지하려면session이 필요하다.
아래 예제는session객체에서 가장 자주 보는 값 몇 가지를 바로 출력하는 코드다.
isNew()는 현재 세션이 새로 만들어진 것인지 보여 주고,getId()는 세션 ID를 보여 주고,getCreationTime()은 세션이 처음 만들어진 시각을 밀리초 값과 날짜 형태로 보여 준다.
즉, 세션이 사용자마다 서버에 따로 유지되는 객체라는 점을 확인하는 예제라고 보면 된다.<!-- exam14.jsp --> <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %> <!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title>Insert title here</title> </head> <body> <h2>JSP에서의 HttpSession 객체</h2> <hr /> <%= session.isNew() %><br /> <!-- 현재 세션이 새로 만들어진 상태인지 출력 --> <%= session.getId() %><br /> <!-- 세션 ID 출력 --> <%= session.getCreationTime() %><br /> <!-- 세션 생성 시각을 밀리초 값으로 출력 --> <%= new java.util.Date(session.getCreationTime()) %><br /> <!-- 세션 생성 시각을 날짜 형태로 변환해서 출력 --> </body> </html>이 예제의 핵심은
session이 단순 문자열 저장소가 아니라, 현재 사용자에게 연결된 세션 객체라는 점을 직접 보여 준다는 것이다.
특히isNew()값과getId()를 같이 보면, 이미 만들어진 세션인지 새로 만들어진 세션인지 감을 잡기 쉽다.
또getCreationTime()을 숫자 그대로 볼 수도 있고,Date객체로 감싸서 사람이 읽기 쉬운 날짜 형태로 바꿀 수도 있다는 점도 함께 보여 준다.
출력 결과는 아래와 같다.
이 화면에서는
false가 먼저 보이는데, 이는 현재 세션이 완전히 새로 만들어진 상태가 아니라는 뜻이다.
그 아래에는 세션 ID가 보이고, 그다음에는 생성 시각이 밀리초 값으로, 마지막에는 사람이 읽기 쉬운 날짜 형태로 출력된다.
즉,session객체는 현재 사용자에게 연결된 상태 정보를 서버 쪽에서 유지하고 있다는 점을 이 결과로 확인할 수 있다.
로그인 예제로 보면
session이 왜 중요한지 더 잘 보인다
session은 값을 보여 주는 데서 끝나지 않는다.
실제로는 로그인 상태처럼 사용자가 다음 요청에서도 계속 유지되어야 하는 정보를 담는 데 많이 사용한다.
아래 예제는 그런 흐름을 보여 준다.
login.jspf는 로그인 폼 조각이고,exam15.jsp는 로그인 처리와 로그인 상태 확인을 맡고,exam16.jsp는 로그아웃을 맡는다.
즉, 세 파일이 함께 움직이면서session의 실제 사용 흐름을 보여 준다.<!-- login.jspf --> <%@ page pageEncoding="UTF-8" %> <h2>로그인</h2> <hr> <form method="post" action="/edu/jspexam/exam15.jsp"> <input placeholder="계정을 입력하세요" name="membername"><br> <input type="password" placeholder="암호를 입력하세요" name="memberpassword"><br> <input type="submit" value="로그인"> </form>이 파일은 단독 페이지라기보다 로그인 폼만 따로 빼 둔 조각 파일이다.
즉, 필요할 때include해서 다시 쓸 수 있도록 만든 구조다.<!-- exam15.jsp --> <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>내장객체 예제</title> <style> input { margin: 1px; } </style> </head> <body> <% if (request.getMethod().equals("POST")) { <!-- 로그인 버튼을 눌러 POST 요청이 들어온 경우 --> if (session.isNew() || session.getAttribute("member_id") == null) { String name = request.getParameter("membername"); String passwd = request.getParameter("memberpassword"); <!-- 입력한 계정과 암호 읽기 --> if (name.equals("duke") && passwd.equals("java")) { session.setAttribute("member_id", name); session.setAttribute("member_passwd", passwd); session.setMaxInactiveInterval(60); <!-- 로그인 성공 시 세션에 사용자 정보 저장 --> %> <script> alert("성공적으로 로그인했습니다!!"); </script> <h3><%=name%> 회원님.. 좋은하루 되세요...</h3> <a href="/edu/jspexam/exam16.jsp">로그아웃</a> <% } else { <!-- 로그인 실패 시 다시 로그인 폼 출력 --> %> <script> alert("로그인에 실패했습니다 !!"); </script> <%@ include file="login.jspf"%> <% } } } else if (request.getMethod().equals("GET")) { <!-- GET 요청이면 현재 로그인 상태인지 먼저 확인 --> String name = (String) session.getAttribute("member_id"); if (name != null) { %> <h3><%=name%> 회원님.. 좋은하루 되세요...</h3> <a href="/edu/jspexam/exam16.jsp">로그아웃</a> <% } else { %> <script> window.alert("로그인 해주세요!"); </script> <%@ include file="login.jspf"%> <% } } %> </body> </html>이 코드에서 핵심은 로그인에 성공하면
member_id,member_passwd를 세션에 저장한다는 점이다.
이렇게 저장해 두면 사용자가 다음 요청을 보내도 서버가 같은 세션 안에서 로그인 상태를 이어서 볼 수 있다.
또setMaxInactiveInterval(60)으로 세션 유지 시간을60초로 정하고 있다는 점도 같이 봐야 한다.
즉,session은 사용자 정보를 잠깐 보관하는 창고 역할을 한다.<!-- exam16.jsp --> <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>내장객체 예제</title> <style> input { margin: 1px; } </style> </head> <body> <% String membername = (String) session.getAttribute("member_id"); <!-- 현재 로그인 상태인지 확인 --> if (membername != null) { session.removeAttribute("member_id"); session.removeAttribute("member_passwd"); <!-- 세션에 저장된 로그인 정보 삭제 --> %> <script> alert("성공적으로 로그아웃했습니다 !!"); </script> <% } else { %> <script> alert("로그인 상태가 아닙니다 !!"); </script> <% } %> <%@ include file="login.jspf"%> <!-- 로그아웃 후 다시 로그인 폼 표시 --> </body> </html>이 코드는 세션에 저장된 로그인 정보를 지워서 로그아웃을 처리한다.
즉,session은 로그인 상태를 유지하는 데도 쓰이고, 그 상태를 끝내는 데도 같이 사용된다.
이 흐름을 보면 왜session이 단순한 값 저장이 아니라 사용자 상태 유지와 연결되는 객체인지 더 분명하게 보인다.
- 로그인 성공 시 세션에 사용자 정보를 저장한다.
- 다음 요청에서도 세션을 통해 로그인 상태를 확인할 수 있다.
- 로그아웃할 때는 세션 값을 지워서 상태를 해제한다.
즉,
session객체는 단순히 값을 잠깐 보여 주는 객체가 아니라, 로그인 같은 사용자 상태를 이어서 유지하기 위한 핵심 객체다.
출력 결과는 아래와 같다.
이 영상은 로그인 폼에 계정과 암호를 입력하고, 로그인 성공 후 환영 문구가 출력되며, 로그아웃 뒤 다시 로그인 화면으로 돌아가는 전체 흐름을 보여 준다.
즉, 세션에 로그인 정보를 저장했다가 삭제하는 과정이 실제 화면 변화로 이어진다는 점을 한 번에 확인할 수 있다.
여기서 먼저 잡아야 할 핵심
이 구간에서 가장 중요하게 기억해야 할 것은 아래 내용이다.
- 내장 객체는
JSP실행 환경이 미리 준비해 주는 객체다.- 자주 보는 내장 객체는
request,response,session,application,out이다.request는 요청 정보를 읽고,response는 응답 정보를 다루고,out은 출력과 연결된다.session은 사용자별 상태를 일정 시간 유지하는 데 사용한다.application은 웹 애플리케이션 전체에서 함께 쓰는 정보를 다룬다.- 로그인 예제를 보면
session이 실제로 어떻게 상태를 유지하는지 더 분명하게 보인다.내장 객체는
JSP가 서버 프로그램처럼 동작하도록 만드는 기본 도구들이고, 그중에서도session은 사용자 상태 유지와 직접 연결되는 아주 중요한 객체다.