JAVA를 이용하여 웹 프로그램을 개발할때 JSP와 servlet(서블릿)을 많이 이용하게 됩니다. JSP와 servlet(서블릿)은 무엇인지 알아보도록 하겠습니다.
JSP란?
JSP(Java Server Pages)란 PHP처럼 태그를 사용해서 html 안에 작성할 수 있는 것을 말합니다.
그리고 서블릿이라고 불리는 것이 있습니다.
서블릿은 JSP를 더욱더 쉽게 사용해주기 위해 사용되는 것입니다.
servlet(서블릿) 이란?
서블릿은 서버에 동적인 콘텐츠를 생성하기 위해 사용되는 기술입니다.
Java 서버에서 움직이는 작은 프로그램으로 JSP의 기반이 됩니다.
JSP는 Java 서버가 JSP 코드를 읽어들여 그것을 서블릿 소스 코드로 변환합니다.
HTML 태그 등도 모두 println으로 출력하도록 변환됩니다.
그리고 생성한 서블릿 소스 코드를 컴파일하고, 서블릿을 생성해서 불러오게 됩니다.
JSP 파일 ⇒ servlet 파일 ⇒ 클래스 파일 ⇒ 실행
서블릿은 버전에 따라 서버에서 동작을 안 하는 경우도 있으니 주의해야 합니다.
서블릿은 웹 서비스를 Java로 만들 때에 반드시 필요합니다.
그리고 서블릿이나 JSP를 이용할 때에는 JavaSE가 아닌 JavaEE로 해줘야 합니다.
서블릿은 브라우저에서 리퀘스트가 있는 경우 애플리케이션 서버가 서블릿 클래스의 인스턴스를 생성합니다.
매번 리퀘스트 할 때마다 인스턴스를 생성하는 것은 서버에 부하가 걸리기 때문에, 처음 생성된 인스턴스를 리퀘스트에 대한 응답 뒤에도 파기하지 않고 다음 리퀘스트에서도 재사용합니다.
단, 서버를 종료하는 등의 경우 서버에서 인스턴스를 파기합니다.
servlet(서블릿) 작성법
서블릿의 작성법을 보도록 하겠습니다.
sample.java
//①임포트부분.
//Eclipse에서 서블릿 클래스를 작성하면 자동으로 작성됨
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
//②서블릿 클래스를 작성하기위해 서블릿 클래스의 베이스가 되는
//HttpServlet를 상속 해줘야함.
public class Sample extends HttpServlet{
//③서블릿 클래스가 GET으로 호출되는 경우, doGet 함수를 오버라이드.
//작성방법은 기본 규칙에 따라 작성해야함.
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException{
//처리 내용 작성
}
//④서블릿 클래스가 POST로 호출되는 경우, doPost 함수를 오버라이드
//작성방법은 기본 규칙에 따라 작성해야함.
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException{
//처리 내용 작성
}
}
브라우저로부터 리퀘스트를 받게 되면 애플리케이션 서버가 서블릿 클래스 doGet()을 호출합니다.
호출할 때 인수로, 브라우저에서 건네준 리퀘스트 정보 안에 있는 HttpServletRequest와 서버에서 전송할 리스폰스에 관련된 정보와 기능을 가진 HttpServletResponse를 건네줍니다.
HttpServletRequest 인스턴스에 저장된 정보를 가지고 처리를 하고 HttpServletResponse 인스턴스를 사용해서 브라우저에 결과를 반환합니다.
sample.java
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
//①브라우저에 반환할 정보의 문자 코드를 설정
response.setContentType("text/html; charset=UTF-8");
//②html 출력
PrintWriter out = response.getWriter();
out.println("<html>");
out.println("<head>");
out.println("</head>");
out.println("<body>");
out.println("<p>Hello Java!</p>");
out.println("</body>");
out.println("</html>");
}
서블릿 클래스 컴파일
서블릿 클래스는 아래의 순서로 동작을 합니다.
서블릿 클래스 소스 파일 ⇒ 컴파일 ⇒ 서블릿 클래스 파일 생성 ⇒ 브라우저 리퀘스트 ⇒서블릿 클래스 파일 실행 ⇒ 서블릿 클래스 파일로부터 인스턴스화 ⇒ 서블릿 클래스 인스턴스 실행
서블릿 클래스와 URL
서블릿을 호출할 때 URL은 아래와 같은 구조를 가집니다.
http://서버명/애플리케이션명/URL 패턴
URL 패턴이란 서블릿 클래스에서 정해준 닉네임이라고 볼 수 있습니다.
서블릿 클래스에서 URL 패턴을 설정해 두면, 그것을 URL로써 호출할 수 있습니다.
이 URL을 html에서 a 태그의 href 속성이나 form의 action 속성에 설정해주면 서블릿으로 이동하게 됩니다.
URL 패턴 설정
URL 패턴을 서블릿 클래스에서 설정하는 방법은 @WebServlet 어노테이션을 사용합니다.
sample.java (서블릿 파일)
//①어노테이션을 사용하기 위해 작성
import javax.servlet.annotation.WebServlet;
・・・생략
//②URL 패턴을 sample 이라고 설정
@WebServlet("/sample")
public class Sample extends
・・・생략
URL 패턴을 슬래쉬로 나눠 세부적으로 나눠줄 수도 있습니다.
URL 패턴을 설정하는 방법에는 어노테이션외에도 web.xml이라는 설정 파일을 사용하는 방법도 있습니다.
Eclipse에서는 서블릿 클래스를 작성하면 자동으로 어노테이션에 [/클래스명]이 설정됩니다.
서블릿 주의점
서블릿 클래스 코드를 수정해도 바로 반영되지 않습니다.
Eclipse에서는 수정 뒤에 조금 기다리면 콘솔창에 [로드가 완료되었습니다.]라고 나옵니다.
콘솔창에 메세지가 나왔다면 반영이 된 것입니다.
아니면 서버를 재기동 해줘야 합니다.
JSP 파일에서 작성된 서블릿 클래스
Eclipse를 사용하는 경우 Workspace에서 지정한 장소안에 JSP 파일에서 작성된 서블릿 클래스를 찾을 수 있습니다.
Workspace/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/work/Catalina/localhost/프로젝트명/org/apache/jsp
jsp를 작성하고 실행하면 위에 장소에 java 파일과 calss파일이 작성됩니다.
가끔 jsp 파일을 수정해도 반영되지 않는 경우에는 여기에 있는 java 파일이나 class 파일이 최신 파일로 갱신되지 않았을 경우도 있기 때문에 삭제하고 실행하면 작업한 최신 파일로 갱신됩니다.
JSP 파일 URL
jsp 파일은 html 파일처럼 취급하며 WebContent 폴더 안에 배치되어 jsp 파일명이 URL이 됩니다.
URL은 아래와 같습니다.
http://서버명/애플리케이션명/WebContent 경로
JSP 주의점
Eclipse에서 jsp를 작성하는 경우 문법 에러가 있는 경우는 코드의 좌측에 X가 표시되지만, 에러가 아닌 경우에도 표시되는 경우가 있습니다.
이러한 에러가 나오는 경우에는 소스를 잘라내기 했다가 붙여넣기를 한 후 저장하면 고쳐지는 경우도 있습니다.
만약 에러가 없어지지 않는다면 진짜 에러일 가능성이 큽니다.
JSP와 서블릿 사용하기
JSP에서 서블릿에 값을 전달하는 방법
브라우저에서 GET이나 POST로 전달한 리퀘스트 파라미터는 HttpServletRequest 인스턴스에 저장되어 지정한 JSP나 서블릿에 전송됩니다.
doPost 함수나 goGet 함수 안 작성 예
//리퀘스트 파라미터 문자 코드를 설정
request.setCharacterEncoding("UTF-8");
//리퀘스트 파라미터 취득
//getParameter("속성 이름");
String name = request.getParameter("name");
String gender = request.getParameter("gender");
리퀘스트 파라미터를 JSP 파일에서 취득
jsp 파일 작성 예
<%
//리퀘스트 파라미터 문자 코드를 설정
request.setCharacterEncoding("UTF-8");
//리퀘스트 파라미터 취득
//getParameter("속성 이름");
String name = request.getParameter("name");
String gender = request.getParameter("gender");
%>
request는 암묵적 오브젝트이기 때문에 선언하지 않아도 사용 가능합니다.
MVC모델
컨트롤 ・・・ 브라우저로부터 리퀘스트를 받는 역할(서블릿)
뷰 ・・・ 리스폰스로써 반환되는 파일(JSP 파일)
모델 ・・・ 실제로 처리를 하는 역할(java)
포워드와 리다이렉트
포워드
서버에서 다른 파일 처리에 이동이 가능.
브라우저에서 URL을 바꾸지 않고 화면 등을 바꿀 수 있음.
서블릿에서 JSP 파일에 포워드
javax.servlet.RequestDispatcher 를 임포트 한 뒤에 아래를 작성하면 됩니다.
RequestDispatcher dispatcher = request.getRequestDispatcher("포워드 경로");
dispatcher.forward(request,response);
포워드 경로는 JSP 파일이면 /WebContent로 시작하는 경로
서블릿 이면 /URL 패턴이 됩니다.
JSP 파일 배치와 리퀘스트
JSP 파일을 아래처럼 배치하면 브라우저에서 직접적으로 리퀘스트 할 수 없게 됩니다.
JSP 파일은 기본적으로 서블릿이 호출해서 브라우저에 전달해주기 때문에 아래처럼 배치를 하고 있는 것입니다.
/WebContent
|___ /WEB-INF
|___ /jsp
|___여기에 포워드할 jsp 파일을 배치
리다이렉트
서버 측에서는 우선 “이 파일을 호출해줘”라고 리스폰스를 반환하고, 반환 내용을 받은 브라우저에서는 다시 파일을 리퀘스트 합니다.
리다이렉트 방법
response.sendRedirect("리다이렉트 URL");
리다이렉트는 같은 서버에 있는 곳을 지정하는 경우 아래와 같이 설정할 수 있습니다.
서블릿의 경우 → /어플리게이션명/URL 패턴
JSP 파일의 경우 → /어플리게이션명/WebContent 로 시작하는 경로
스코프
스코프란 화면 이동을 할 때 데이터를 계속해서 가지고 이동하는 것을 말합니다.
Java에는 값을 계속해서 사용하기 위해 JavaBeans를 사용해 인스턴스를 전달합니다.
인스턴스를 저장 가능한 스코프는 4종류가 있습니다.
・페이지 스코프
・리퀘스트 스코프
・세션(Session) 스코프
・애플리케이션 스코프
페이지 스코프
하나의 화면 내에서만 사용 가능.
리퀘스트 스코프
클라이언트(사용자)가 리퀘스트 한 정보로, 서버가 레스폰스를 반환할 동안까지 보존.
만약 리다이렉트를 하는 경우 삭제됨.
포워드의 경우는 정보가 삭제되지 않음.
서블릿 안에서 리퀘스트 스코프에 인스턴스를 보존하는 작성 예
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException{
//리퀘스트 스코프에 저장할 인스턴스를 생성
People people = new People("ponyo", 12);
//리퀘스트 스코프에 인스턴스 저장
//첫 번째 파라미터는 속성명
//두번째 파라미터는 인스턴스
request.setAttribute("people",people);
//리퀘스트 스코프에서 인스턴스를 취득하고 싶은 경우
//취득한 인스턴스는 Object형이기 때문에
//원래의 형태로 캐스터(형변환)가 필요
people h = (People) request.getAttribute("people");
}
JSP에서 리퀘스트 스코프에 저장한 인스턴스 취득 작성 예
//취득하고 싶은 인스턴스 클래스를 임포트
<%@ page import = "bean.People" %>
<%
//리퀘스트 스코프에서 인스턴스를 취득
People h = (People) request.getAttribute("people");
%>
//인스턴스 프로퍼티에 접근하여 값을 취득
<%= h.getName() %>님의 나이는<%= h.getAge() %>세 입니다.
세션(Session) 스코프
세션 스코프에 저장한 값은 인스턴스를 삭제하거나 브라우저를 닫을 때까지 사용 가능합니다.
그렇기 때문에 리다이렉트를 사용해도 값을 계속해서 사용할 수 있습니다.
Cookie라는 형태를 사용해서 값을 저장해둡니다.
세션과 Cookie에 대한 설명은 생략하도록 하겠습니다.
세션 스코프를 사용하기 위해서는 javax.servlet.http.HttpSession 인스턴스를 사용합니다.
서블릿으로 세션 스코프 작성 예
People people = new People();
people.setName("ponyo");
people.setAge(12);
//HttpSession 인스턴스를 취득
//javax.servlet.http.HttpSession를 임포트 해둬야함
HttpSession session = request.getSession();
//세션 스코프에 인스턴스를 저장
session.setAttribute("people", people);
//세션 스코프에서 인스턴스를 취득하고 싶은 경우
People h = (People) session.getAttribute("people");
//세션 스코프에서 인스턴스를 삭제하고 싶은 경우
session.removeAttribute("people");
//세션 스코프를 삭제하고 싶은 경우
//스코프가 삭제되며, 저장하고 있던 인스턴스도 모두 파기.
//쇼핑몰 사이트등에서 유저 로그아웃등을 할때 사용
session.invalidate();
애플리케이션 스코프
WEB 애플리케이션이 종료되기 전까지 값을 보존합니다.
서버를 재기동 하기 전까지 보존됩니다.
데이터 베이스에 저장하기에는 애매한 데이터이지만 계속해서 필요한 정보라면 애플리케이션 스코프에 저장해두기도 합니다.
서블릿 애플리케이션 스코프 작성 예
People people = new People("ponyo",12);
//ServletContext 인스턴스를 취득
//javax.servlet.http.ServletContext를 임포트 해둬야함
ServletContext app = this.getServletContext();
//애플리케이션 스코프에 인스턴스 보존
app.setAttriute("people", people);
//애플리케이션 스코프에서 인스턴스를 취득하고 싶은 경우
People h = (People) app.getAttribute("people");
//애플리케이션 스코프에서 인스턴스를 삭제하고 싶은 경우
app.removeAttribute("people");
jsp 파일에서 애플리케이션 스코프 작성 예
<%@ page import = "bean.People" %>
<%
//애플리케이션 스코프에서 인스턴스를 취득
People h = (People) app.getAttribute("people");
%>
<%= h.getName() %>님 나이는<%= h.getAge() %>세 입니다.
필터
필터란 반복되는 처리를 한곳에 작성해두는 것을 의미합니다.
예를 들어 서블릿에서 매번 작성하는 문자 코드 설정입니다.
request.setCharacterEncoding(“UTF-8”);
또는 로그인하지 않으면 볼 수 없는 페이지 등의 처리도 매번 로그인 되어있는지 체크 처리를 하는 것보다 필터라는 구조로 사용하면 매번 같은 소스를 작성할 필요가 없습니다.
필터 작성 예
//①어노테이션을 작성
//javax.servlet.annotation.WebFilter 임포트 필요함.
@WebFilter("/*")
public class FilterSample implements Filter {
//필터를 인터턴스화(초기 설정)될때 처리할 내용을 작성
public void init(FilterConfig fConfig) throws ServletException{ }
//지정한 서블릿 클랫스가 호출될때 처리할 내용을 작성
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException{
request.setCharacterEncoding("UTF-8");
chain.doFilter(request, response);
}
//필터 인스턴스가 파기되기전에 실행할 처리할 내용을 작성
public void destroy(){ }
}
①처럼 필터에는 @WebFilter 어노케이션을 사용합니다.
필터 작성 방법
//필터를 설정하는 서블릿 클래스 URL 패턴
@WebFilter("/URL 패턴")
//Sample 서블릿 클래스에 설정
@WebFilter("/Sample")
//Sample이하의 서블릿 클래스에 설정
@WebFilter("/Sample/*")
//모든 서블릿 클래스에 설정
@WebFilter("/*")
jsp 파일을 분할해서 인클루드(include)하기
화면을 만들다 보면 jsp 파일에서도 헤더나 푸터등 공통적인 부분이 있습니다.
이러한 경우 매번 jsp에 헤더와 푸터를 작성하는 것은 매우 번거로운 작업입니다.
또한 헤더나 푸터에 수정이 생기게 되면 모든 jsp 파일을 수정해야 하는 번거로움이 있습니다.
이렇듯 헤더나 푸터처럼 공통적으로 사용되는 부분은 공통화해서 각각의 jsp 파일에 공통화 시킨 헤더 부분과 푸터 부분을 읽어들이도록 합니다.
jsp 파일에서 다른 jsp 파일을 읽어들이는 방법입니다.
jsp 파일 읽어오기 작성 예
<%
RequestDispatcher dpc = request.getRequestDispatcher("읽어올 파일명");
dpc.include(request, response);
%>
서블릿안에서도 사용 가능합니다.
또는 jsp에서 사용할 수 있는 액션 태그를 사용해서 다른 jsp 파일을 읽어올 수 있습니다.
<jsp:include page="읽어올 파일명" />
액션 태그에는 처음부터 jsp에 준비되어 태그입니다.
이러한 태그를 표준 액션 태그라고 합니다.
표준 액션 태그
많이 사용되는 표준 액션 태그입니다.
<jsp:useBean> ・・・ 스코프에서 JavaBeans 인스턴스를 취득. 취득하지 못한 경우에는 인스턴스를 새로작성해서 스코프에 저장.
<jsp:setProperty> ・・・ JavaBean 프로퍼티 값을 설정
<jsp:getProperty> ・・・ JavaBean 프로퍼티 값을 취득
<jsp:include> ・・・ 인클루드 설정
<jsp:forward> ・・・ 포워드 설정
html 태그처럼 사용되지만 대문자와 소문자를 구별하기 때문에 주의해야 합니다.
동적 인클루드와 정적 인클루드
인클루드에는 2가지가 있습니다.
동적 인클루드는 파일을 실행 중에 인클루드를 하여 다른 jsp 파일을 읽어오고 그 파일을 처리해 결과를 원래 파일에 반환해주는 것입니다.
정적 인클루드는 파일을 실행 중에 인클루드를 하여 다른 jsp 파일을 읽어와 그대로 실행하는 것을 의미합니다.
동적 인클루드에서는 호출을 한 원래 파일과는 별도로 실행되기 때문에 원래 파일에서는 호출한 다른 파일에 정의된 변수, 인스턴스, 태그 라이브러리 등을 사용할 수 없습니다.
정적 인클루드의 경우는 하나의 파일로 인식되어 실행되기 때문에 호출한 파일에 정의된 변수, 인스턴스, 태그 라이브러리 등을 사용할 수 있습니다.
주의점으로 변수명이 중복되지 않도록 미리 설정을 해둬야 합니다.
정적 인클루드
정적 인클루드(include)의 사용법입니다.
<%@ include file=”읽어올 파일명” @>
・읽어올 파일명은 /WebContent로 시작하는 경로부터 설정
・서브릿 클래스는 인클루드 할 수 없음.
EL식
EL식을 사용하면 스코프에 저장한 값을 더욱 간단하게 취득할 수 있습니다.
EL식을 사용하지 않은 경우
<%@ page import="model.Sample" @>
<@ Sample sp = *Smaple) session.getATtribute("sample"); @>
<@= sp.getName() @>
EL식을 사용한 경우
${ sp.name }
${ sp[2].name } //리스트 에서 취득 가능
EL식 작성 방법
//스코프에 저장한 인스턴스를 취득
${속성명}
//스코프에 저장한 인스턴스 프로퍼티를 취득
//지정한 프로퍼티의 getter가 자동으로 실행됨.
${속성명.프로퍼티}
EL식은 지정한 속성명의 인스터스를 아래와 같은 순서로 찾습니다.
페이지 스코프 → 리퀘스트 스코프 → 세션 스코프→ 애플리케이션 스코프
만약 지정한 속성명을 찾지 못한 경우에는 예외 처리는 하지 않습니다.
찾지 못한 부분을 표시하지 않을 뿐입니다.
스코프의 장소를 지정하여 사용할 수도 있습니다.
만약 세션 스코프에 저장되어 있는 인스턴스를 사용하고 싶을 경우
${ sessionScope.msg }
처럼 작성하여 사용할 수 있습니다.
JSTL
EL식은 if문이나 for문에서 사용하고 싶은 경우 JSTL을 사용해야 합니다.
JSTL을 커스텀 태그라고 불립니다.
커스텀 태그란 개발자가 독자적으로 개발한 액션 태그를 말합니다.
jsp에에서는 <jsp:forward>처럼 이미 준비되어 있는 표준 태그가 있지만, 직정 작성할 수도 있습니다.
직접 작성한 액션 태그는 라이브라리에 모아 다른 사람에게도 배포할 수 있습니다.
JSTL은 5개 태그 라이브러리로 구성되어 있습니다.
DB 조작, 조건식, 반복문 등의 태그가 있습니다.
JSTL 이용하기
JSTL을 사용하기 위해서는 JAR 라이브러리를 다운 받아서 WEB-INF/lib 폴더에 넣어줘야 합니다.
JSP에서 태그 라이브러리를 사용하기 위해 아래처럼 taglib를 사용하여 설정해야 합니다.
JSP에서 태그 라이브러리 설정 방법
<%@ tablib prefix="c" url="http://java.sun.com/jsp/jstl/core" %>
Core 태그 라이브러리
조건식 등이 가능한 라이브러리입니다.
사용법은 다음과 같습니다.
//변수 값을 출력. 에스케이프 처리도 해줌.
<c:out value="변수명">
//EL식도 사용가능
<c:out value="${sample.name}">
//조건식1
<c:if test="조건식">
//true의 경우 처리
</c:if>
//조건식2(EL식을 사용한 경우)
<c:if test="${sample.age == 20}">
//true의 경우 처리
</c:if>
//조건식3(if-else 를 사용하고 싶은 경우)
<c:choose>
<c:when test="조건식">
//true의 경우 처리
</c:when>
<c:otherwise>
//false의 경우 처리
</c:otherwise>
</c:choose>
//반복문
<c:forEach var="i" bigin="0" end="9" step="1" >
//반복문에서 처리하고 싶은 내용
</c:forEach>
//반복문(확장 for문)
<c:forEach var="변수명" items="배열">
//반복문에서 처리하고 싶은 내용
//var에 지정한 변수명을 사용하여 여러가지 처리가 가능.
</c:forEach>
디렉티브
디렉티브 기본 사용법
<%@ 디렉티브명 속성명="속성값1" 속성명2="속성값2" … %>
속성값은 반드시 더블 쿼테이션(“”)으로 감싸줘야 합니다.
주로 사용하는 디렉티브
@page ・・・ 기본적인 처리 방법
@include ・・・ 외부 파일을 인크루트
@taglib ・・・ 페이지 내에서 사용할 태그 라이브러리를 선언
@page 디렉티브 주요 속성
contentType ・・・ 페이지 출력 콘텐츠 타입(문자 코드 등)을 설정. 기본은[text/html]
사진이나 동영상을 출력하는 경우에는 [image/jpeg], 등을 설정pageEncoding ・・・ jsp 파일 문자 코드
import ・・・ 임포트 할 패키지 또는 클래스를 설정
errorPage ・・・ 예외 처리 발생 시에 표시할 에러 페이지 경로
자바 JSP와 Servlet에 대해서 여러가지 설명을 하였습니다.
잘못된 내용이나 다른 정보들이 있으시면 코멘트 남겨주시면 감사하겠습니다.
댓글