|
เริ่มลงมือ
หลักการดังกล่าว
จะใช้ได้กับ container ทั่วไป ซี่งในการเขียน web pages ด้วย JavaServer
Page ที่ต้องการใช้งานจริงคงต้องให้ทำงานบน OS ที่เป็น server เช่น
linux หรือ Windows NT, Windows 2000 และต้องใช้ container ระดับใหญ่สักหน่อย
ดังตัวย่างข้างบน เช่น tomcat เพื่อรองรับการทำงาน แต่ในที่นี้ เป็นเพียงเพื่อการศึกษา
และจะให้สามารถทดลองทำตามได้ง่ายๆ จากเครื่องคอมพิวเตอร์ที่เราใช้งานทั่วไปเช่น
Windows 9x ดังนั้นเราจะใช้ container ตัวเล็กๆคือ jswdk ซึ่ง directory
ต่างๆที่กล่าวมาเกี่ยวกับเรื่องของ web application อาจมีรายละเอียดแตกต่างไปบ้างเล็กน้อย
ซี่งการปรับสภาพแวดล้อมต่างๆสามารถทำได้ที webserver.xml โดยดูรายละเอียดได้จากตัวอย่างข้างล่าง
เริ่มแรกให้
download ไฟล์มาก่อน ซี่งจะมีทั้ง version windows และ linux ซึ่งถ้าต้องการ
รุ่นที่ล่าสุด สามารถตรวจสอบได้ที่ http://java.sun.com ในที่นี้เราจะพูดถึงเฉพาะบน
windows
หลังจากคลี่ไฟล์
jswdk_xxxx ซึ่งเลข version อาจต่างกันไปบ้าง แต่เพื่อความสะดวกเราจะตั้งชื่อเป็น
c:\jswdk ซี่งใน directory นี้ จะมี examples ของเดิมที่ SUN เตรียมไว้ให้อยู่แล้ว
แต่เพื่อไม่ให้เกิดความสับสนและจะได้ทดลองตัวอย่างของเราเอง ให้สร้างไดเรคทอรี
directory c:\jswdk\myexam และทุกตัวอย่างที่เราทำจะเก็บไว้ในไดเรคทอรีนี้
ซึ่งความจริงแล้วเราคงต้องสร้างไดเรคทอรีย่อยลงมาจาก myexam นี้ด้วย
ตามโรงสร้างของ Web Application
ก่อนลงมือทำอย่างอื่น
ให้ set properties ของ dos prompt ในส่วน memory ให้ค่า initial environment=2816
แล้วสร้าง
file c:\jswdk\jdk.bat เพื่อให้สามารถใช้จาวาได้ ดังนี้
set path=c:\jdk1.4\bin
set classpath=c:\jdk1.4\lib\tools.jar;.
set JAVA_HOME=c:\jdk1.4
c:\windows\command\doskey
ต่อไป
ให้แก้ไข file c:\jswdk\startserver.bat ตามตัวอย่างข้างล่าง
@echo
off
rem $Id:
startup.bat,v 1.19.2.5 1999/08/31 19:38:43 gonzo Exp $
rem Startup
batch file for servlet runner.
rem This
batch file written and tested under Windows NT
rem Improvements
to this file are welcome
set jsdkJars=.\webserver.jar;.\lib\jakarta.jar;.\lib\servlet.jar
set jspJars=.\lib\jsp.jar;.\lib\jspengine.jar
set beanJars=.\examples\WEB-INF\jsp\beans;.\myexam\WEB-INF\jsp\beans;
.\webpages\WEB-INF\servlets;.\webpages\WEB-INF\jsp\beans
set miscJars=.\lib\xml.jar;.\lib\moo.jar
set appJars=%jsdkJars%;%jspJars%;%beanJars%;%miscJars%
set sysJars=%JAVA_HOME%\lib\tools.jar
set appClassPath=.\classes;%appJars%
set cp=%CLASSPATH%
set CLASSPATH=%appClassPath%;%sysJars%
if "%cp%"
== "" goto next
rem else
set CLASSPATH=%CLASSPATH%;%cp%
:next
echo
Using classpath: %CLASSPATH%
java
com.sun.web.shell.Startup %1 %2 %3 %4 %5 %6 %7 %8 %9
rem java
com.sun.web.shell.Startup %1 %2 %3 %4 %5 %6 %7 %8 %9
rem clean
up
set CLASSPATH=%cp%
set port=
set host=
set test=
set jsdkJars=
set jspJars=
set beanJars=
set miscJars=
set appJars=
set appClassPath=
set cp=
rem pause
และที่ไฟล์
c:\jswdk\webserver.xml ให้แก้ไขในส่วนของ DOCTYPE ตามตัวอย่างข้างล่าง
<?xml
version="1.0" encoding="ISO-8859-1"?>
............
............
............
.
<!DOCTYPE
WebServer [
<!ELEMENT
WebServer (Service+)>
<!ATTLIST
WebServer
id ID
#REQUIRED
adminPort
NMTOKEN "">
<!ELEMENT
Service (WebApplication*)>
<!ATTLIST
Service
id ID
#REQUIRED
port
NMTOKEN "8080"
hostName
NMTOKEN ""
inet
NMTOKEN ""
docBase
CDATA "webpages"
workDir
CDATA "work"
workDirIsPersistent
(false | true) "false">
<!ELEMENT
WebApplication EMPTY>
<!ATTLIST
WebApplication
id ID
#REQUIRED
mapping
CDATA #REQUIRED
docBase
CDATA #REQUIRED
maxInactiveInterval
NMTOKEN "30">
]>
<WebServer
id="webServer">
<Service
id="service0">
<WebApplication
id="examples" mapping="/examples" docBase="examples"/>
<WebApplication
id="myexam" mapping="/myexam" docBase="myexam"/>
</Service>
</WebServer>
-->
ทีนี้เราจะเริ่มทำ
web pages กันเลย โดยเขียน code ตามตัวอย่างข้างล่าง และแยกบันทึก
เป็นไฟล์ต่างๆ ตาม directory ที่แนะนำไว้ครับ
เริ่มจาก
hello.jsp โดยบันทึกเป็น c:\jswdk\myexam\jsp\hello.jsp เสร็จแล้วทดสอบการทำงานโดยเรียกดูที่
http://localhost:8080/myexam/jsp/hello.jsp
<HTML>
<HEAD>
<TITLE>My
Hello JSP</TITLE>
</HEAD>
<BODY>
<H1>Everybody
says
<%
String str = "Hello JSP";
out.println(str);
%>
</H1>
</BODY>
</HTML>
ถ้าดูเผิน
ๆ จากทาง browser การเรียกไฟล์ JSP คงดูคล้าย ๆ กับการเรียกไฟล์ HTML
ธรรมดา ๆ แต่ความจริงแล้ว หลังจาก request จาก client ส่งมาถึงเซฟเวอร์,
JSP Container จะทำการแปลงไฟล์ JSP ให้กลายเป็น Servlet source ไฟล์
(ในกรณีที่ JSP ไฟล์ดังกล่าวถูกเรียกเป็นครั้งแรก) ซึ่งไฟล์ Servlet
source ที่ได้จะถูกคอมไพล์เป็น .class เพื่อใช้ในการประมวลผล request
ของ client แล้วส่งกลับไปให้เซฟเวอร์ในรูปของ outputStream ซึ่งถูกส่งไปที่
client ในท้ายสุด
หลังจากนั้น ถ้า JSP ไฟล์ดังกล่าวถูกเรียกอีก การแปลงไฟล์หรือคอมไพล์จะไม่เกิดขึ้น
เพราะ JSP Container จะใช้ไฟล์ .class ที่เก็บไว้แล้วประมวลผลแทน ข้อสังเกตคือ
การเรียกไฟล์ JSP ครั้งแรกจะรู้สึกว่าช้า แต่ครั้งถัดไป ๆ จะเห็นได้ว่าเร็วขึ้นมาก
เพราะได้มีการลดขั้นตอนต่าง ๆ ที่เสียเวลาไป
ใน JSP Specification 1,1 ยังมีการแนะนำให้ JSP Engine รองรับการโหลดไฟล์
JSP ขึ้นมาคอมไพล์ใหม่แบบอันโนมัติ (Reloading) ซึ่งมักจะเกิดขึ้นในกรณีที่
JSP ไฟล์ได้มีแก้ไข แล้วจะต้องมีการคอมไพล์ไฟล์ Servlet ที่กำลังใช้งานอยู่ใหม่

การแปลงและคอมไพล์ JSP ไฟล์
จากข้อความที่อธิบายข้างต้น
เราสามารถแบ่งระยะเวลาของไฟล์ JSP หนึ่ง ๆ ออกเป็นสองช่วงคือ
1) Translation Time คือช่วงเวลาที่ JSP ไฟล์ถูกแปลงให้กลายเป็น Servlet
ไฟล์และถูกคอมไพล์ให้กลายเป็น .class ไฟล์ ซึ่งจะเกิดก่อนการรับ request
จาก client ครั้งแรก
2) Client Request Time คือช่วงเวลาที่ .class ของ JSP ไฟล์ ทำการรับ
request จากแต่ละ client แล้วทำการประมวลผล
JSP Translation
จากตัวอย่างไฟล์ hello.jsp เราจะเห็นว่าโค้ดจะมีแค่สองส่วนคือ ส่วนที่เป็น
HTML code และส่วนที่เป็น Java code ซึ่งถูกบรรจุอยู่ใน <% ...
%>
ในขั้นตอนของการแปลงไฟล์จาก .jsp เป็น Servlet souce ไฟล์ (.java)
ส่วนที่เป็น HTML code จะถูกเปลี่ยนให้อยู่ในรูปที่เทียบเท่ากับ out.print("HTMLCODE");
ไฟล์ hello.jsp อาจถูกแปลงเป็น hello_jsp_1.java เก็บไว้ที่ไดเรคทอรี
work (สำหรับกรณีที่ใช้ jswdk) ดังนี้
package
myexam.jsp;
import
javax.servlet.*;
import
javax.servlet.http.*;
import
javax.servlet.jsp.*;
import
java.io.PrintWriter;
import
java.io.IOException;
import
java.io.FileInputStream;
import
java.io.ObjectInputStream;
import
java.util.Vector;
import
com.sun.jsp.runtime.*;
import
java.beans.*;
import
com.sun.jsp.JspException;
public
class hello_jsp_1 extends HttpJspBase {
static
char[][] _jspx_html_data = null;
public
hello_jsp_1( ) {
}
private
static boolean _jspx_inited = false;
public
final void _jspx_init() throws JspException {
ObjectInputStream
oin = null;
int
numStrings = 0;
try
{
FileInputStream
fin = new FileInputStream("work\\%3A8080%2Fmyexam\\myexam.jsphello.dat");
oin
= new ObjectInputStream(fin);
_jspx_html_data
= (char[][]) oin.readObject();
} catch
(Exception ex) {
throw
new JspException("Unable to open data file");
} finally
{
if (oin
!= null)
try
{ oin.close(); } catch (IOException ignore) { }
}
}
public
void _jspService(HttpServletRequest request, HttpServletResponse
response)
throws
IOException, ServletException {
JspFactory
_jspxFactory = null;
PageContext
pageContext = null;
HttpSession
session = null;
ServletContext
application = null;
ServletConfig
config = null;
JspWriter
out = null;
Object
page = this;
String
_value = null;
try
{
if (_jspx_inited
== false) {
_jspx_init();
_jspx_inited
= true;
}
_jspxFactory
= JspFactory.getDefaultFactory();
response.setContentType("text/html");
pageContext
= _jspxFactory.getPageContext(this, request, response,
"",
true, 8192, true);
application
= pageContext.getServletContext();
config
= pageContext.getServletConfig();
session
= pageContext.getSession();
out
= pageContext.getOut();
out.print(_jspx_html_data[0]);
// begin
[file="C:\\jswdk\\myexam\\jsp\\hello.jsp";from=(6,2);to=(7,23)]
String
str = "Hello JSP";
out.println(str);
// end
out.print(_jspx_html_data[1]);
// begin
[file="C:\\jswdk\\myexam\\jsp\\hello.jsp";from=(8,2);to=(9,29)]
String
secondstr = " JSP is cool !!";
out.println(secondstr);
// end
out.print(_jspx_html_data[2]);
} catch
(Throwable t) {
if (out.getBufferSize()
!= 0)
out.clear();
throw
new JspException("Unknown exception: ", t);
} finally
{
out.flush();
_jspxFactory.releasePageContext(pageContext);
}
}
}
Standard
Syntax and Semantics
|