Home
Course
Service
Contact
About Us

 

 

 

 

 

 

 

 

 


Standard Syntax and Semantics

หลังจากได้เห็นตัวอย่างการทำงานของ jsp กันแล้ว ในการศึกษาภาษาส่วนใหญ
่ เราคงเริ่มจากเรื่อง syntax กฏเกณฑ์ต่างๆ ในที่นี้เราจะทำโปรแกรมสั้นๆไปพร้อมกันด้วย
ให้เขียนไฟล์ accessCount.jsp ตามตัวอย่างข้างล่างนี้ แล้วดูผลที่ได้

<%-- This is comment --%>
<%@ page info="Access Count Sample" %>
<%@ page import="java.util.Date" %>
<HTML>
<HEAD><TITLE>Hello, JSP</TITLE></HEAD>
<BODY bgcolor="#ffffff">
<H1>Hello JSP</H1>
<BR>
<%! private int accessCount = 0; %>
<% accessCount++;
Date rightNow = new Date(); %>
Access Page: <%= accessCount %> times... at
<%= rightNow.toString() %>
</BODY>
</HTML>

จะเห็นว่ามี script ที่อยู่ในรูปของ <% ... %> (Directives and Scripting Elements) แตกต่างกัน 5 แบบ คือ

JSP Directives and Scripting Elements

Directives
<%@ directive %>


Declarations
<%! declaration %>


Expressions
<%= expression %>


Code Fragment/Scriptlet
<% code fragment %>


Comments
<%-- comment --%>

Directives
JSP Directives เป็นส่วนที่เรียกว่า "message" ที่ใช้ส่งไปถึง JSP Container
ในลักษณะของ <%@ ... %> โดย message นี้จะเป็นตัวบอกว่า Container
ควรจะทำอะไรกับ JSP Page ต่อไป ซึ่ง directives ในส่วนนี้จะไม่มีผลต่อหน้าตาที่ออกมา
ของ JSP Page เมื่อถูกแปลงออกมาในรูปของ html แล้ว Directives แบ่งออกเป็นสามส่วน ส่วนที่เราใช้ทั่ว ๆ ไปคือ page และ include กับส่วนที่สามซึ่งเป็น taglib
(เราจะไม่กล่าวถึงในที่นี้) ซึ่งใช้สำหรับสร้าง Tag ของเราเองใน JSP

page directive เป็นส่วนที่ปกติเราจะเห็นอยู่บนสุดของ JSP page
ซึ่งใช้ในการกำหนดค่าต่าง ๆ ที่เกี่ยวข้องกับ JSP page นั้น ๆ หรือเกี่ยวข้องกับ
การติดต่อสื่อสารกับ JSP Container ยกตัวอย่างเช่น
ถ้าเราอยากเรียกใช้คลาสที่ชื่อ java.util.Date เราก็สามารถที่จะ import คลาสนี้ได้โดยใช้
<%@ page import="java.util.Date" %>

หรือเวลาที่เกิดข้อผิดพลาดใน JSP page ของเรา แล้วเราอยากให้แสดงข้อผิดพลาด
ที่เกิดขึ้น ที่ error page ที่ชื่อ errorPage.jsp เราก็ใช้
<%@ page errorPage="errorPage.jsp" %>

หรือแม้กระทั่งเวลาที่เราอยากจะเก็บ states ของ user ในรูปของ session เราก็สามารถใช้
<%@ page session="true" %>

เพื่อบอก container ว่า JSP Page นี้สามารถเรียกใช้ HttpSession
ในการเปลี่ยนแปลงและเก็บ states ของ user ได้ เป็นต้น

include directive เป็นส่วนที่ช่วยให้เราสามารถนำไฟล์ JSP อื่น ๆ มาเป็นส่วนประกอบ
ของไฟล์ JSP ปัจจุบัน โดยใช้
<%@ include file="filename.jsp" %>

ประโยชน์ที่เห็นได้ชัดอย่างหนึ่งของการใช้ include directive คือ การง่ายต่อการเปลี่ยนแปลงและบำรุงรักษา ยกตัวอย่างเช่น

สมมุติว่าทุกหน้าของเราต้องการ header หรือ footer ที่เหมือนกัน เราก็แค่ใช้ <%@ include file="header.jsp" %> ใส่ลงไปในทุก ๆ JSP ไฟล์ หลังจากนั้น
ทุกครั้งที่เราต้องการเปลี่ยนแปลง header นี้ เราก็แค่เปลี่ยนไฟล์ที่ชื่อ header.jsp
ซึ่งไฟล์ทุกไฟล์ที่ include ไฟล์นี้เข้าไป ก็จะเปลี่ยนไปด้วยโดยอัตโนมัติ

Declarations
Declarations ใช้ในการประกาศค่าตัวแปร (variable) หรือสร้างฟังก์ชั่นต่าง ๆ
(method) เพื่อจะใช้ใน JSP page นั้น
โดยทั่วไป Declarations จะถูก initialize เมื่อ JSP page ถูก initialize ซึ่งจะทำให้ตัวแปร หรือฟังก์ชั่นใน Declarations พร้อมใช้งานได้ทันที ตัวอย่างเช่น
<%! int i = 0; %>
<%! public String f(int i) {
if (i<3) return "...";
...
}
%>

* Declarations เป็นส่วนที่ถูกประมวลผลในช่วง Translation time

Expressions
โดยการใช้ expressions สิ่งต่าง ๆ ที่อยู่ใน <%= ... %> จะถูกประมวลผล
แล้วเปลี่ยนให้อยู่ในรูปของ String และส่วนที่ได้นี้จะถูกรวมเข้าไปอยู่ใน output page
(html)
โดยตรง เช่น
<%= i %>
Container จะดึงค่า i ออกมา แล้วเปลี่ยนเป็นสตริงโดยใช้ Integer.toString(i)

<%= "Hello" %>
Container จะนำค่า Hello ใส่เข้าไปใน output page

ข้อควรจำอย่างหนึ่งคือ ห้ามทำการใส่ semicolon (;) ลงไปใน <%= ... %> ยกเว้นถ้า
semicolon นั้นเป็นส่วนหนึ่งของสตริง เช่น
<%= "Hello semicolon ;" %>

* Expressions เป็นส่วนที่ถูกประมวลผลในช่วง Translation time

Code Fragments/Scriptlets
เราสามารถใส่โค้ด หรือส่วนหนึ่งของโค้ดเข้าไปยัง JSP page ได้โดยใช้ <% ... %> โค้ดที่ใส่เข้าไปนี้จะไปอยู่ในส่วนของ service() ฟังก์ชั่นของ Servlet ซึ่งจะถูกเรียกใช้เมื่อมี
request จาก client ยกตัวอย่างเช่น

<% int userId = request.getParameter("userId");
if (userId == 9999) {
out.print("You are admin!!!");
} else {
out.print("You are who you are");
}
%>

บางทีเราอาจใส่เพียงส่วนหนึ่งของโค้ดเข้าไปในแต่ละ <% ... %> ก็ได้ เช่น

<% if (Calendar.getInstance().get(Calendar.AM_PM) == Calendar.AM)
{ %>
Good morning
<% } else { %>
Good Afternoon
<% } %>

เหตุผลที่เราสามารถทำเช่นนี้ได้เพราะถ้าเราดู code หลังจากการแปลงเป็น Servlet แล้ว
จะเป็นดังนี้
...
if (Calendar.getInstance().get(Calendar.AM_PM) == Calendar.AM)
{ // by <% ... %>
out.print("Good Morning"); // plain html will be replaced by out.print("...");
} else { // by <% ...%>
out.print("Good Afternoon"); // plain html
}
...
ซึ่งจะกลายเป็นโค้ดที่สมบูรณ์ขึ้นมา
* Code Fragments/Scriptlets เป็นส่วนที่ถูกประมวลผลในช่วง Client request time

Comments
comments ใน JSP มีอยู่สองแบบคือ
1) comment ที่ปกติถูกใช้ใน html ไฟล์ ซึ่งจะไม่ถูก skip ไปโดย JSP Container เมื่อไฟล์
JSP ถูกแปลงเป็น .class แล้ว (จะยังคงปรากฏที่ client side ในส่วนของ html source code) ตัวอย่างเช่น
<!-- This is my comment -->

บางทีเราอาจเปลี่ยนแปลง comment ที่อยู่ข้างใน <!-- ... --> ได้ โดยใช้ expression เช่น
<!-- <%= expression %> more comment -->

2) comments ที่ผู้เขียน JSP ใช้สำหรับ comment ไฟล์ JSP ที่เขียนอยู่ ซึ่งจะถูก skip
ไปโดย JSP Container ในช่วงของ Translation time ตัวอย่างเช่น
<%-- comment for server side only --%>

หลังจากที่ได้เรียนรู้เกี่ยวกับ syntax ต่าง ๆ ของ JSP แล้ว เรากลับมาที่ไฟล์ accessCount.jsp กันอีกครั้ง

1: <%-- This is comment --%>
2: <%@ page info="Access Cont Sample" %>
3: <%@ page import="java.util.Date" %>
4: <HTML>
5: <HEAD><TITLE>Hello, JSP</TITLE></HEAD>
6: <BODY bgcolor="#ffffff">
7: <H1>Hello JSP</H1>
8: <BR>
9: <%! private int accessCount = 0; %>
10: <% accessCount++;
11: Date rightNow = new Date(); %>
12: Access Page: <%= accessCount %> times... at
<%= rightNow.toString() %>
13: </BODY>
14: </HTML>

line 1: เป็นลักษะของ JSP comment ที่จะถูก skip ไปโดย JSP Container
หลังจากที่ไฟล์ JSP ถูกแปลงเป็น Servlet แล้ว
line 2: ใช้ page directive เพื่อเซ็ตค่า "Access Count Sample" ไปใส่ในฟังก์ชั่น Servlet.getServletInfo() ของไฟล์ Servlet ที่ได้จากการแปลงไฟล์
AccessCount.jsp
โดย JSP Container
line 3: เป็นการใช้ page directive เพื่อ import คลาส java.util.Date
ก่อนที่จะทำการเรียกใช้
line 4-8: เป็น HTML template ซึ่งจะถูกแปลงอยู่ในรูปของ out.print(HTML)
line 9: มีการประกาศตัวแปร private int accessCount โดยใส่เข้าไปใน Declaration เพื่อใช้ในการนับจำนวนครั้งที่เพจนี้ถูกเรียกดู ซึ่ง accessCount จะกลายเป็นส่วนหนึ่งของ
instance variable ของไฟล์ hellojsp1 ในเวอร์ชั่น Servlet
line 10: ทำการเซ็ต accessCount+1 ในทุก ๆ ครั้งที่เพจนี้ถูกเรียก
ซึ่งสามารถทำได้ในส่วนที่เป็น scriptlet (<% ... %>)
line 11: สร้าง object ใหม่ชื่อ rightNow ซึ่งมาจากคลาส java.util.Date ที่เรา import มาก่อนหน้านี้ ใช้สำหรับเรียกดูวันเวลาปัจจุบัน
line 12: ใช้ Expression เพื่อแสดงค่าของ accessCount และพิมพ์ค่าของเวลาปัจจุบัน
ที่เก็บอยู่ใน rightNow ซึ่งทั้งสองค่าจะถูกแปลงออกมาอยู่ในรูปของ String

ถ้าต้องการดูรายละเอียดเพิ่มขึ้น จะพิจารณาประกอบกับซอร์ส accesscount_jsp_x.java ที่นำไปใช้สร้างคลาสดังข้างล่าง

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;

import java.util.Date;

public class accesscount_jsp_2 extends HttpJspBase {

static char[][] _jspx_html_data = null;

// begin [file="C:\\jswdk\\myexam\\jsp\\accesscount.jsp"; from=(1,0);to=(1,42)]

public String getServletInfo() {

return "an Access Count example";

}

// end

// begin [file="C:\\jswdk\\myexam\\jsp\\accesscount.jsp"; from=(10,3);to=(10,33)]

private int accessCount = 0;

// end

public accesscount_jsp_2( ) {

}

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.jspaccesscount.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]);

out.print(_jspx_html_data[1]);

out.print(_jspx_html_data[2]);

out.print(_jspx_html_data[3]);

out.print(_jspx_html_data[4]);

// begin [file="C:\\jswdk\\myexam\\jsp\\accesscount.jsp"; from=(12,2);to=(13,32)]

accessCount++;

Date rightNow = new Date();

// end

out.print(_jspx_html_data[5]);

// begin [file="C:\\jswdk\\myexam\\jsp\\accesscount.jsp"; from=(15,16);to=(15,29)]

out.print( accessCount );

// end

out.print(_jspx_html_data[6]);

// begin [file="C:\\jswdk\\myexam\\jsp\\accesscount.jsp"; from=(15,47);to=(15,68)]

out.print( rightNow.toString() );

// end

out.print(_jspx_html_data[7]);

} catch (Throwable t) {

if (out.getBufferSize() != 0)

out.clear();

throw new JspException("Unknown exception: ", t);

} finally {

out.flush();

_jspxFactory.releasePageContext(pageContext);

}

}

}

Packages และโครงสร้างการทำงานใน JSP

 



:: ศูนย์ฝึกอบรมบางปะกง การไฟฟ้าฝ่ายผลิตแห่งประเทศไทย 8/4 หมู่ 8 ตำบลท่าข้าม อำเภอบางปะกง จังหวัดฉะเชิงเทรา 24130 ::