JSP 맛보기

JSP : 2007.04.06 20:24

JSP 맛보기

김세곤 <sehkone@bawi.org>

1999년 12월 19일

이번 글은 JSP를 어떻게 쉽게 사용해 볼 수 있는지, 그 사용 방법에 대한 일종의 간단한 튜토리얼이다. 메카니즘에 대한 이해와 높은 난이도의 JSP 사용에 대한 글을 계속적으로 연재할 예정이다.

JSP의 문서 구성

JSP는 HTML문서안에 자바 코드를 써 넣는 방법으로 동적 문서를 생산한다. HTML안에 써 놓은 자바 코드는 웹 서버가 가동한 JVM을 통해 알맞는 HTML 문서로 동적 생산되어 브라우저로 보내진다. 정확하게 말하면 웹 서버의 여러 모듈 중 JSP를 담당하는 모듈이 이 일을 하게 된다. 메카니즘에 대한 소개는 뒤로 미루고, 우선 JSP 문서가 어떻게 구성되는지 살펴 보자. JSP 문서 내에 JSP를 위한 태그는 <% %>, <%= %>, <%@ %>, <%! %>, <jsp: /> 등이 있다(태그는 기본적으로 XML 체계를 따르고 있다). 먼저, <%@ %>, <% %>, <%= %> 태그를 살펴보자. 이것만으로도 어지간한 웹 문서는 모두 만들 수 있으며, <jsp: />는 1.0 이상에서만 가능하므로 간혹 지원을 제대로 하지 못 하는 환경이 있을 수도 있다. JSP문서의 기본 구성을 보자.

<%@ page contentType="text/html; charset=EUC-KR" %>
<HTML>
<HEAD><TITLE>JSP 문서</TITLE></HEAD>
<BODY>
<% 
    String email = 
"sehkone@bawi.org";

%> 저에게 연락을 하시고 싶으시면 <ahref="mailto:<%= email %>">여기를</a> 클릭하세요.

</BODY>
</HTML>

JSP의 구성은 매우 간단하다. 우선 맨 위의 <%@ page contentType="text/html; charset=EUC-KR" %>는 브라우저가 전송받는 문서가 HTML이고 한글 문서라는 사실을 알도록 하기 위한 것이다. 쉽게 생각해서, 이 줄은 공통적으로 모든 JSP파일의 첫머리에 들어가는 것으로 보면 된다. <% %>안에는 자바 코드가 들어간다. 위의 예에서는 String 클래스로 email 인스턴스(변수)를 만든 것이 전부이지만, <% %>안에는 코드의 분량에 구애됨이 없이 자유롭게 자바 코드를 써 넣을 수 있다. <% 로 시작한 자바 코드는 %>로 끝나며 다시 HTML 문서가 등장한다. 위의 예에서 "저에게...클릭하세요" 가운데를 살펴보면 <%= %> 태그를 볼 수 있는데, <%= %> 태그 안의 자바 코드 결과는 그대로 HTML 문서내에 보여지게 된다. 따라서, 위의 예는 다음의 HTML 문서가 되어 브라우저로 보내지게 된다.
<HTML>
<HEAD><TITLE>JSP 문서</TITLE></HEAD>
<BODY>

저에게 연락을 하시고 싶으시면 <a href="mailto:sehkone@bawi.org">여기를</a> 클릭하세요.

</BODY>
</HTML>

간단하지 않은가? 이제 여러분은 JSP 문서의 대체적인 골격은 이해하였다.

다음으로 넘어가기 전에 한 가지만 더 알아둘 것이 있다. 첫번째 줄 <%@ page ... %> 안에는 import 변수가 들어가는 경우가 많은데, java.io.*와 java.lang.*, javax.servlet.*, javax.servlet.http.*, javax.servlet.jsp.* 클래스는 JSP 문서에 기본적으로 import 되므로 굳이 import 변수에 명시할 필요가 없으나, 그 외의 클래스를 쓰고 싶다면 import 변수에 써 주어야 한다. JDBC를 쓴다면 java.sql.* 클래스를 포함시켜야 하고 자바 메일 클래스를 이용하려면 javax.mail.*, javax.mail.internet.* 등을 포함시켜야 하는데 이 경우는 다음처럼 쓰면 된다.

<%@ page import="java.sql.*, javax.mail.*,javax.mail.internet.*" contentType="text/html; charset=EUC-KR" %>

import의 값으로 포함시키고자 하는 클래스를 콤마로 구분하여 나열하기만 하면 되는 것이다.

GET, POST도 간편하게 - getParameter() 이용하기

동적인 문서 생산하기 위해서는 사용자와 호흡해야 하고, 이를 위해서는 브라우저 내에 사용자가 정보를 입력하는 일이 많다. 이 정보를 처리하기 위해서 JSP는 getParameter() 메쏘드를 제공한다. getParameter 메쏘드는 ServletRequest 인터페이스의 메쏘드로서 GET이나 POST로 넘어온 값들을 얻을 수 있도록 해 준다. ServletRequest는 HttpServletRequest가 계승하는데 JSP 표준 스펙에서는 HttpServletRequest 클래스 타입으로 request 인스턴스(변수)를 만든다. 따라서, JSP 문서에서 getParameter 메쏘드를 사용하려면 다음처럼,

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

사용해야 한다. 다시 말하면, JSP는 컴파일되면 정상적인 자바 코드로 만들어진 서블릿이 되는데, 이 서블릿 코드 내에서 request는 내부적으로 사용되는 변수라는 말이다. 즉, JSP 문서 내에서는 request라는 이름의 인스턴스(변수)를 어떤 형태로든 사용할 수 없고, 프로그래머는 이미 만들어지는 request 인스턴스를 이용하여 getParameter(나중에 설명하겠지만, 쿠키를 얻기 위한 getCookies() 등과 같은 메쏘드도 포함된다) 메쏘드를 사용하면 된다. JSP가 서블릿으로 변환되면서 내부적으로 정의되는 인스턴스는 몇 가지가 더 있는데, 이는 추후에 차차 알아나가기로 하자. GET이나 POST로 전달되는 값을 처리하는 방법을 좀 더 자세히 코드를 봐 가면서 알아보자. 사용자의 이름과 비밀번호를 입력받아서 이를 확인하는 JSP를 예로 들겠다. 우선, 사용자의 이름과 비밀번호를 입력받는 Form을 사용한 HTML 문서를 만들어야 한다.
....
<form method="post" action="member.jsp">
이름 : <input type="text" name="username"><br>
비밀번호 : <input type="password" name="userpasswd"><br>
<input type="submit">
</form>
....

이 HTML문서의 이름, 비밀번호 필드에 적당한 값을 입력하고 submit 버튼을 누르면 이 값들이 member.jsp로 전달될 것이다. 이제, POST로 전달되는 값을 member.jsp에서 어떻게 받는지를 살펴보자.
<%@ page contentType="text/html; charset=EUC-KR" %>
<%
String name = request.getParameter("username");
String password = request.getParameter("userpasswd");
%>
<HTML>
<HEAD>
<TITLE>회원인가?</TITLE>
</HEAD>
<BODY>
이름은 <%= name %>이고, 비밀번호는 <%= password %>라고 입력하였습니다.
</BODY>
</HTML>

GET으로 전달받는 값들도 POST와 같은 방법으로 request.getParameter()를 사용하면 된다.

쿠키를 사용하자

웹 개발을 하다보면 쿠키를 사용할 일이 종종 있다. 쿠키에 대한 자세한 이야기는 필자가 따로이 글을 준비 중이므로 많은 기대 부탁드리며, 여기서는 간략하게 JSP에서 쿠키를 다루는 법만 소개하겠다.

먼저, 쿠키를 세팅하는 코드를 보기로 하자.

<%@ page contentType="text/html; charset=EUC-KR" %>
<%
String myEmail = "sehkone@bawi.org";
Cookie cookieEmail = new Cookie("email", myEmail);
cookieEmail.setMaxAge(-1);
response.addCookie(cookieEmail);
%>
<HTML>
<HEAD>
<TITLE>쿠키 세팅</TITLE>
</HEAD>
<BODY>
별로 하는 일은 없는 JSP 문서지만 쿠키를 세팅하는 예를 보여줍니다.
</BODY>
</HTML>

여기서, 새로운 인스턴스(변수)인 response를 만나게 된다. response는 JSP문서가 서블릿으로 변환될 때 내부적으로 사용하는 HttpServletResponse 클래스의 인스턴스(변수)로서, JSP 문서 내에서 자유롭게 사용할 수 있다. 앞서 언급한 request가 사용자의 요청에 관한 것을 다룬다면, 이 response는 사용자의 요청에 대한 JSP 문서의 응답에 관한 것을 다룬다. 초보 단계에서는 역시 자세한 메카니즘에 대한 이해는 뒤로 미루어 두고, 쿠키를 사용하기 위해서는 response 변수를 사용하여 addCookie() 메쏘드를 호출해야 한다는 사실을 알아두자. 염두에 둘 것은 request, response가 인스터스들이므로 이와 같은 이름의 다른 인스턴스를 정의하면 안 된다는 사실이다.

한 줄 한 줄 살펴보자. 자바 코드 부분의 첫번째 줄에서는 이메일 주소를 스트링 인스턴스에 넣었다. 두번째 줄은 Cookie 클래스 타입으로 새로운 쿠키를 만드는데, 그 이름은 email이고 값은 myEmail 인스턴스 값으로 한다는 뜻이다. 세번째 줄에서는 이 쿠키의 유효 기간을 설정하는 것인데, -1처럼 음의 값은 브라우저 종료 시까지 이 쿠키가 유효하도록 하는 설정이다. 0은 이 쿠키를 없애라는 설정이며, 특별히 유효 기간을 명시하고 싶으면 setMaxAge 메쏘드의 인자로 초 단위 값을 써 주면 된다.

브라우저에 쿠키를 세팅하는 방법을 살폈고, 이제 브라우저로부터 쿠키를 얻는 방법을 알아보자. JSP나 서블릿에서 쿠키를 얻을 때는 쿠키 이름을 명시하여 얻을 수 있는 방법은 없고 모든 쿠키를 다 받아서 각각의 쿠키의 이름과 값을 검사하는 방법을 사용해야 한다. 다음의 예는 쿠키 중에서 그 이름의 "id"인 것을 찾아서 그 값을 출력하는 JSP이다.

<%@ page contentType="text/html; charset=EUC-KR" %>
<HTML>
<HEAD><TITLE>id 쿠키 값 검사</TITLE></HEAD>
<BODY>
<%
Cookie[] cookies = request.getCookies();
for (int i = 0; i < cookies.length; i++) {
   Cookie thisCookie = cookies[i];
   if ("id".equals(thisCookie.getName())) {  // if문 시작
%>
아이디는 <%= thisCookie.getValue() %> 입니다.<BR>
이 부분에는 자유로운 HTML 코드가 들어갈 수 있습니다.
<%
   }  // if문의 끝
%>
</BODY>
</HTML>

for 문 두 줄 아래의 if문 내의 JSP 형태를 주의깊게 보도록 하자. <% } %>로 if 문을 닫아 주는 일을 종종 잊는 경우가 많은데 항상 신경을 쓰도록 하자.

이제, 특정한 쿠키를 찾아서 그 쿠키를 없애는 방법을 알아보자. 바로 위의 코드에 몇 줄만 추가하면 id 쿠키를 없앨 수 있다. 다음을 보자.

<%@ page contentType="text/html; charset=EUC-KR" %>
<HTML>
<HEAD><TITLE>id 쿠키 값 없애기</TITLE></HEAD>
<BODY>
<%
Cookie[] cookies = request.getCookies();
for (int i = 0; i < cookies.length; i++) {
   Cookie thisCookie = cookies[i];
   if ("id".equals(thisCookie.getName())) {  // if문 시작
%>
아이디는 <%= thisCookie.getValue() %> 입니다.<BR>
이 부분에는 자유로운 HTML 코드가 들어갈 수 있습니다.
<%
        thisCookie.setMaxAge(0);   // 쿠키를 없애라는 유효기간 설정
        response.addCookie(thisCookie);   // 다시 쿠키를 세팅
   }  // if문의 끝
%>
이제 id 쿠키는 없어졌습니다.
</BODY>
</HTML>

데이터베이스를 맘대로 - JDBC

웹 개발에서 역시 가장 중요한 부분은 데이터베이스와의 연동이다. JDBC는 필자가 별도의 쓰레드로 연재할 생각이며, 여기서는 역시 맛만 보도록 하자.

JDBC를 사용하기 위해서는 사용하는 데이터베이스의 JDBC 드라이버를 설치하여야 한다. postgreSQL의 경우는 http://www.retep.org.uk/postgres/에서 JDK 버전에 따른 드라이버를 구할 수 있다.

역시, 예제부터 보자.

<%@ page import="java.sql.*" contentType="text/html; charset=EUC-KR" %>
<%
    String userId = request.getParameter("userid");
    Connection db;
    ResultSet rs;
    PreparedStatement stmt;

    try {
        Class.forName("postgresql.Driver");
    } catch (java.lang.ClassNotFoundException e) {
        System.err.println(e.getMessage());
    }

    try {
        db = DriverManager.getConnection("jdbc:postgresql:dbname", "dbuser", "password");
        stmt = db.prepareStatement("SELECT id, name FROM member WHERE id = ?");
        stmt.setString(1, userId);
        rs = stmt.executeQuery();       
        rs.next();

        String resultId = rs.getString("id");
        String resultName = rs.getString("name");
        
        stmt.close();
        rs.close();
        db.close();
    } catch (SQLException e) {
    }
%>
<HTML>
<HEAD>
<TITLE>
JDBC 사용
</TITLE>
</HEAD>
<BODY>
<%= resultId %>의 이름은 <%= resultName %> 입니다.
</BODY>
</HTML>

JDBC를 사용하기 위해서는 JDBC 드라이버를 로드해야 하는데, 이를 위해서 다음처럼 한다.
try {
    Class.forName("postgresql.Driver");
} catch (java.lang.ClassNotFoundException e) {
    System.err.println(e.getMessage());
}

쉽게 생각하여 이 부분은 모든 JSP 문서에서 DB에 연결하기 전 공통적으로 들어간다고 보면 된다. 다음으로 DB와 연결해야 하는데, 이를 위해서 다음처럼 한다.
db = DriverManager.getConnection("jdbc:postgresql:dbname", "dbuser", "password");

첫번째 인자는 접속하고자 하는 DB 이름을 알려주는 것인데, 앞의 jdbc:postgresql은 사용되는 드라이버 이름이다. 이 부분은 개별 DBMS에 따라 다른데, 드라이버 설치 문서에 나와 있으므로 참고하여 명시하면 된다. jdbc:postgresql: 다음에는 접속하고자 하는 DB이름을 그대로 쓰면 된다. 두번째, 세번째 인자는 접속하고자 하는 DB의 사용자 아이디와 비밀번호를 써 넣으면 된다.

JDBC는 DB에 질의를 던지는 방법으로 두 가지를 제공하고 있다. Statement와 PreparedStatement 클래스가 그 두 가지 방법인데, 여기서는 PreparedStatement에 대해서 간단히 설명하겠다. 먼저, DB에 묻고자 하는 질의를 다음과 같은 방법으로 생성한다. stmt는 PreparedStatement 클래스의 인스턴스여야 하며, prepareStatement의 인자로는 SQL 구문이 들어간다.

stmt = db.prepareStatement("SELECT id, name FROM member WHERE id = ?");

여기서, ?는 정해지지 않은 값으로서 다음처럼 세팅한다.
stmt.setString(1, userId);

다음으로, 이 질의를 DB에 던지고 결과를 받는다.
rs = stmt.executeQuery();       
rs.next();

rs는 ResultSet 클래스의 인스턴스이며, next 메쏘드는 질의 결과로 얻어진 릴레이션에서 튜플 포인터를 하나씩 증가시키는 일을 한다. 쉽게 말해서, 얻어진 질의 결과를 한 줄씩 넘기는 것이라 보면 된다. 현재 가리키고 있는 튜플의 필드 값을 읽기 위해서는 getXXX 메쏘드를 사용하는데 필드의 타입이 문자열이라면 getString을 쓰면 된다.
String resultId = rs.getString("id");
String resultName = rs.getString("name");

위와 같이 하면 id, name 필드 값이 각각 resultId와 resultName 스트링에 저장되게 된다. 마지막으로 PreparesStatement, ResultSet, Connection 인스턴스들을 없애는 일을 해야 한다.
stmt.close();
rs.close();
db.close();

사실, Java는 Garbage Collection 기능이 있으므로 불필요한데, Sun에서는 외부 클래스를 사용할 경우 이 기능이 제대로 수행되지 못 할 가능성 때문에, close 메쏘드를 사용하기를 권장하고 있다.

마치며

이번 글에서는 JSP와 JDBC를 맛 보았다.

사실, 위에서 설명한 request.getParameter() 메쏘드는 beans를 사용하면 거의 사용할 일이 없다. 초기에는 beans를 지원하지 못하는 환경이 많았으나 요새는 대부분 지원이 가능하므로, 독자 여러분은 우아한 beans를 사용하여 JSP 문서를 개발하도록 하자. Beans에 대해서는 WebDox의 JSP에서 Beans 사용하기를 참고하면 자세한 사용법을 알 수 있다. Beans가 없는 JSP는 생각하기 어려우므로 꼭 살펴본다.

JDBC에 대해서는 좀 더 상세한 용법이 WebDox의 JDBC를 익히자에 있으므로 참고하면 좋겠다.

'JSP' 카테고리의 다른 글

자바빈(Java Bean) 컴포넌트  (0) 2007.06.18
JSP 공부한것 요약  (0) 2007.06.18
[JSP] 세션을 이용한 로그인 처리  (0) 2007.05.03
JSP 맛보기  (0) 2007.04.06
Posted by Real_G