SlideShare a Scribd company logo
1 of 20
Download to read offline
บทที่ 5 จาวาเซิร์ฟเล็ต (Java Servlet)
หากผู้อ่านรู้จักกับเทคโนโลยีของจาวามาก่อน
หรือเคยผ่านการเขียนโปรแกรมด้วยภาษาจาวามาก่อนแล้ว
การสร้างเซิร์ฟเล็ตก็ไม่ได้ต่างอะไรกับการสร้างโปรแกรมอื่นๆของภาษาจาวา
เป็นที่ทราบกันดีอยู่แล้วว่า
ภาษาจาวาเป็นภาษาที่สามารถนำมาสร้างเป็นโปรแกรมที่ทำงานบนระบบคอมพิว
เตอร์ทั่วไปโดยไม่ขึ้นอยู่กับแพลตฟอร์ม (Write Once, Run Anywhere)
หากโปรแกรมดังกล่าวทำงานในแบบทั่วไปบนเครื่องคอมพิวเตอร์
เรียกว่าจาวาแอปพลิเคชั่น (Java Application)
หากโปรแกรมดังกล่าวทำงานผ่านบนบราวเซอร์ เรียกว่าจาวาแอปเพล็ต (Java
Applet) ทั้งจาวาแอปพลิเคชั่นและจาวาแอปเพล็ต
ใช้หลักการเขียนและสร้างเหมือนกันต่างกันเพียงเรียกใช้ API (Application
Programming Interface) ที่ต่างกัน
ดังนั้นการสร้างเซิร์ฟเล็ตจึงไม่ต่างอะไรกับจาวาแอปพลิเคชั่น
หรือแอปเพล็ตที่กล่าวมา โดยที่เซิร์ฟเล็ตเป็นการสร้างโปรแกรมโดยเรียกใช้ API
สำหรับการทำงานบนเว็บเซิร์ฟเวอร์โดยเฉพาะ
ซึ่งทำให้จาวาเซิร์ฟเล็ตมีคุณสมบัติในการทำงานที่เข้าใจโพรโตคอล HTTP
นอกจากนี้แล้วภายในบทนี้ยังมีเนื้อหาอธิบายถึงการจัดสร้างเอกสารเว็บในแ
บบไดนามิก (Dynamic Content) ที่เกิดจากการทำงานของเซิร์ฟเล็ต
และการจัดการข้อมูลตัวอักษรภาษาไทยในการแสดงผลด้วย
จากที่เคยได้ให้ความหมายของคำว่าเซิร์ฟเล็ตไปแล้วว่า
โปรแกรมที่ทำงานเป็นเซิร์ฟเล็ตจะทำงานภายใต้ระบบคอมพิวเตอร์ที่ทำหน้าที่เป็นเว็บเซิร์ฟเวอร์
โดยจะเข้าไปสนับสนุนการทำงานในส่วนของการประมวลผลเพื่อให้ได้เนื้อข้อมูลก่อนถูกเว็บเซิร์ฟเวอร์ลำเลียงข้อมูลกลับไปให้ที่บราวเซ
อร์อีกที
การรับข้อมูลการร้องขอจากบราวเซอร์เกิดจากการใช้งานของผู้ใช้ ซึ่งเซิร์ฟเล็ตสามารถรับคำสั่งการร้องขอนี้ได้หลายทาง คือ
- เรียกใช้เซิร์ฟเล็ตโดยตรง เมื่อผู้ใช้ระบุข้อมูล URL ที่อ้างถึงโปรแกรมเซิร์ฟเล็ตโดยตรงในช่องกรอกแอดเดรส
หรืออ่านการคลิกลิงก์ข้อความหรือรูปภาพที่มีข้อมูลอ้างถึงโปรแกรมเซิร์ฟเล็ตซ่อนไว้
ภาพแสดงการอ้างถึงโปรแกรมเซิร์ฟเล็ตโดยตรง
- เรียกใช้งานจากการทำงานของจาวาแอปเพล็ต
โปรแกรมจาวาแอปเพล็ตอาจมีการเรียกหรืออ้างถึงแอดเดรสไปยังเซิร์ฟเล็ตบนเว็บเซิร์ฟเวอร์ เพื่อเรียกอ่านข้อมูลโดยตรง
ภาพจำลองแสดงการอ้างถึงโปรแกรมเซิร์ฟเล็ตจากจาวาแอปเพล็ต
- เรียกใช้งานผ่านฟอร์มของเว็บ การใช้งานเพื่อเรียกดูข้อมูลจากเว็บเซิร์ฟเวอร์
หากผู้ใช้ต้องการส่งข้อมูลไปให้กับเว็บเซิร์ฟเวอร์ มักจะกรอดข้อมูลผ่านฟอร์ม (Form) จากนั้นส่ง (Submit) ไปให้
หากการส่งนั้นอ้างถึงโปรแกรมเซิร์ฟเล็ต โปรแกรมดังกล่าวก็จะรับข้อมูลนั้นไว้ เพื่อนำไปประมวลผลอีกที
ภาพจำลองแสดงการส่งข้อมูลจากฟอร์มไปยังโปรแกรมเซิร์ฟเล็ต
1. โครงสร้างเซิร์ฟเล็ต
เมื่อต้องการสร้างโปรแกรมคอมพิวเตอร์ ให้มีรูปแบบการประมวลผลในแบบเซิร์ฟเล็ต
เริ่มต้นผู้เขียนโปรแกรมต้องสร้างคลาสใหม่ที่สืบทอดคุณสมบัติจากคลาส HttpServlet ด้วยการใช้คีย์เวิร์ด extends
และให้สร้างเมธอด doGet (หรือ doPost) ซึ่งรองรับคำสั่งร้องขอจากบราวเซอร์ เพื่อประมวลผลในเมธอด และส่งผลลัพธ์กลับคืน
ลองพิจารณาตัวอย่างโครงสร้างของคลาสโครงสร้างต่อไปนี้ ซึ่งเป็นรูปแบบที่จะนำไปสร้างเป็นเซิร์ฟเล็ตในคราวต่อไป
1 import java.io.*;
2 import javax.servlet.*;
3 import javax.servlet.http.*;
4
5 public class SERVLET_CLASS extends HttpServlet {
6 public void doGet (HttpServletRequest request, HttpServletResponse response)
7 throws ServletException, IOException {
8 PrintWriter out = response.getWriter();
9 //
10 }
11 }
ตัวอย่างซอร์สโค้ดแสดงโครงสร้างของเซิร์ฟเล็ต
จากโครงสร้างดังกล่าวลองมาดูรายละเอียดว่าแต่ละบรรทัดถูกใช้งานเพื่อทำหน้าที่อย่างไร ในบรรทัดที่ 1
เป็นการเรียกใช้คำสั่ง import เพื่ออิมพอร์ตกลุ่มคลาสเพื่อใช้งานในแพ็กเกจ java.io.* ที่บรรจุคลาสที่เกี่ยวกับการจัดการทางด้าน
Input และ Output ซึ่งภายในโปรแกรมมีการเรียกใช้งานคลาส PrintWriter (บรรทัดที่ 8) ที่อยู่ในแพ็กเกจดังกล่าว
เพื่อใช้งานในการจัดการรูปแบบการส่งข้อมูลกลับสู่บราวเซอร์
บรรทัดที่ 2 เป็นการอินพอร์ตกลุ่มคลาสในแพ็กเกจ javax.servlet.*
เพื่อเรียกใช้งานคลาสที่เกี่ยวข้องกับการจัดการโปรแกรมรูปแบบเซิร์ฟเล็ตคือคลาสชื่อ HttpServlet
และเช่นกันจะเห็นตัวอย่างการใช้งานจากบรรทัดที่ 5 ซึ่งเป็นการสืบทอดมาสร้างเป็นคลาสใหม่ด้วยคีย์เวิร์ด extends นั่นเอง
สำหรับคำสั่ง import ในบรรทัดถัดมาเป็นการอินพอร์ตกลุ่มคลาสในแพ็กเกจ javax.servlet.http.*
เพื่อเรียกใช้งานคลาสเกี่ยวกับการจัดการข้อมูลในโพรโตคอล HTTP ซึ่งในที่นี้คือคลาส HttpServletRequest
สำหรับตรวจสอบข้อมูลร้องขอที่ส่งมาจากบราวเซอร์ และคลาส HttpServletResponse เป็นการจัดการผลลัพธ์ที่ถูกส่งไปให้บราวเซอร์
การใช้งานคลาสทั้งสองคลาสถูกจัดเป็นอาร์กิวเม็นต์ในเมธอด goGet ในบรรทัดที่ 6
จากโครงสร้างของเซิร์ฟเล็ตที่แสดงเป็นตัวอย่าง กำหนดให้ SERVLET_CLASS
คือชื่อคลาสที่ต้องการให้มีการทำงานในแบบเซิร์ฟเล็ตที่ต้องการสร้างขึ้น
ชื่อคลาสนี้ต่อไปเมื่อต้องการใช้งานจะเป็นชื่อที่ถูกอ้างผ่านทาง URL (หรือ Address)
บนบราวเซอร์ของผู้เรียกใช้งานเมื่อต้องการสั่งให้เซิร์ฟเล็ตทำงาน
ข้อแนะนำ จากโครงสร้างตัวอย่างเนื่องจากคลาสที่ใช้สร้างเซิร์ฟเล็ตสังเกตเห็นคำว่า public นำหน้าชื่อคลาส
ดังนั้นชื่อไฟล์ซอร์สโค้ดควรตั้งชื่อเหมือนกับชื่อเซิร์ฟเล็ตทั้งหมดทั้งตัวเล็กหรือตัวใหญ่ เช่น หากชื่อคลาสเป็น MyServlet
ฃื่อไฟล์ควรตั้งเป็น MyServlet.java เป็นต้น
ในคลาสเซิร์ฟเล็ตมีเมธอดหนึ่งเมธอดคือ doGet เมธอดดังกล่าวถูกเรียกใช้งานเมื่อบราวเซอร์ส่งคำสั่งร้องขอข้อมูลด้วยคำสั่ง
GET ซึ่งเป็นหนึ่งในคำสั่งร้องขอข้อมูลของโพรโตคอล HTTP
ในเมธอดดังกล่าวมีอาร์กิวเมนต์สองตัวที่เกี่ยวกับการร้องขอข้อมูลโดยตรงคือ HttpServletRequest ซึ่งจะถูกอ้างถึงผ่านตัวแปร
request และการโต้ตอบข้อมูล HttpServletResponse ซึ่งจะถูกอ้างถึงด้วยตัวแปร response ตามลำดับ
ซึ่งอยู่ในส่วนท้ายของในบรรทัดที่ 6
ภานในเมธอด doGet มีการกำหนดรูปแบบการจัดการกับข้อมูลโต้ตอบ เมื่อเซิร์ฟเล็ตต้องการส่งข้อมูลกลับสู่บราวเซอร์
โดยมีการอ้างถึงคลาส PrintWriter เพื่อจัดการเกี่ยวกับเรื่องการกำหนดรูปแบบการส่งข้อมูลโต้ตอบ จากตัวอย่างในบรรทัดที่ 8
การจัดการด้านรูปแบบการส่งข้อมูลผ่านตัวแปรที่ชื่อ out ซึ่งได้รับอินสแตนซ์ช่องทางส่งข้อมูลกลับมาจากคำสั่ง response.getWriter()
ตัวแปรอ้างถึง out สามารถเรียกใช้งานเมธอดที่เกี่ยวข้องการการจัดการข้อมูลข้อความสองเมธอดคือ print และ println
คือการส่งข้อความทั่วไป และการส่งข้อความที่จบด้วยสัญลักษณ์ขึ้นบรรทัดใหม่ตามลำดับ
รูปแบบการใช้งานตัวแปร out
out.print("Hello"); // เมื่อต้องการส่งข้อความ Hello สู่บราวเซอร์
out.println("Hello"); // เมื่อต้องการส่งข้อความ Hello พร้อมขึ้นบรรทัดใหม่สู่บราวเซอร์
ข้อแนะนำ จากโครงสร้างเซิร์ฟเล็ตดังกล่าว มีตัวแปรที่เกิดขึ้นคือ request, response, out
ซึ่งสามารถตั้งด้วยชื่ออะไรก็ได้นอกเหนือจากนี้
แต่อย่างไรก็ตามชื่อทั้งสามชื่อเป็นชื่อที่จำจำได้ง่ายและจะถูกตั้งเป็นชื่อที่สอดคล้องที่จะใช้ในการทำงานของ JSP
ที่จะกล่าวถึงในเนื้อหาที่เกี่ยวข้องกับ JSP
2. เซิร์ฟเล็ตกับการตอบสนองข้อมูลตัวอักษร
การสร้างเซิร์ฟเล็ตเพื่อตอบสนองการทำงานหรือเพื่อส่งข้อมูลกลับไปหาบราวเซอร์
ด้วยวิธีการพื้นฐานที่สุดคือการส่งข้อมูลที่ประกอบจากตัวอักษรออกไป
และต่อไปนี้เป็นตัวอย่างซอร์สโค้ดที่จะทำการสร้างเซิร์ฟเล็ตเพื่อจุดประสงค์ในการส่งข้อมูลตัวอักษรกลับไปหาบราวเซอร์
โดยข้อมูลดังกล่าวคือคำว่า
ยินดีต้อนรับสู่การใช้งานเซิร์ฟเล็ต
Welcome! to Java Servlet
และตัวอย่างซอร์สโค้ดต่อไปนี้คือ ServletHelloWorld.java
เป็นตัวอย่างการทำงานเพื่อส่งข้อมูลตัวอักษรตามความต้องการข้างต้น ให้พิจารณาที่ละบรรทัด
1 import java.io.*;
2 import javax.servlet.*;
3 import javax.servlet.http.*;
4
5 public class ServletHelloWorld extends HttpServlet {
6 public void doGet (HttpServletRequest request, HttpServletResponse response)
7 throws ServletException, IOException {
8 PrintWriter out = response.getWriter();
9 out.println(" "); //
10 out.print("Welcome! to Java Servlet"); //
11 }
12 }
ตัวอย่างเซิร์ฟเล็ตส่งข้อมูลตัวอักษร
จากตัวอย่างซอรสโค้ดในบรรทัดที่ 9 มีการใช้งาน out โดยเรียกเมธอด println
เพื่อพิมพ์ข้อความโดยมีการขึ้นบรรทัดใหม่หลังจากสิ้นสุดข้อความ ส่วนบรรทัดที่ 10
เป็นอีกข้อความหนึ่งซึ่งถูกส่งไปหาบราวเซอร์แต่ไม่ได้ส่งรหัสขึ้นบรรทัดใหม่กลับไปด้วย
เมื่อคอมไพล์ซอร์สโค้ดดังกล่าวแล้วจะได้ไฟล์ที่ชื่อ ServletHelloWorld.class
จากบทที่แล้วที่กล่าวถึงสภาพแวดล้อมที่โปรแกรม Apache Tomcat
เป็นเว็บเซิร์ฟเวอร์ที่สนับการทำงานของเซิร์ฟเล็ตถูกติดตั้งไว้ที่
ไดเร็กทรอรี่ที่ติดตั้งโปรแกรม Apache Tomcat
C:Program FilesApache Tomcat 4.0
และมีการสร้างไดเร็กทรอรี่สำหรับการทำงานในการทดลองไว้ที่ไดเร็กทรอรี่ ejp ต่อจากไดเร็กทรอรี่ติดตั้งคือ
ไดเร็กทรอรี่ทำงาน ejp ภายใน Apache Tomcat
C:Program FilesApache Tomcat 4.0webappsejp
ในการติดตั้งเซิร์ฟเล็ตที่ได้รับการคอมไพล์แล้วจากตัวอย่างนี้คือไฟล์ ServletHelloWorld.class
ให้ทำการสำเนาไฟล์ดังกล่าวไปเก็บไว้ในไดเร็กทรอรี่ WEB-INFclasses ในไดเร็กทรอรี่ทำงาน ejp ดังนี้
ไดเร็กทรอรี่ติดตั้งเซิร์ฟเล็ตของ ejp
C:Program FilesApache Tomcat 4.0webappsejpWEB-INFclassesServletHelloWorld.class
หลักจากนั้นเมื่อต้องการทดสอบการใช้งาน ให้เปิดโปรแกรมบราวเซอร์ใดๆ เช่น Internet Explorer หรือ Netscape
Navigator ในช่องแอดเดรสให้อ้างถึง URL เพื่อเรียกใช้งานเซิร์ฟเล็ตคือ
URL ในการเรียกใช้งานเซิร์ฟเล็ต
http://localhost:8080/ejp/servlet/ServletHelloWorld
จาก URL อ้างถึงเซิร์ฟเล็ตดังกล่าวจะไม่เหมือนกับชื่อไดเร็กทรอรี่ที่ติดตั้งภายใน
เป็นการอ้างถึงตามข้อกำหนดของเซิร์ฟเล็ตบนโปรแกรม Apache Tomcat เมื่อกล่าวโดยสรุปจึงเป็นดังนี้
http คือชื่อโพรโตคอลในการใช้งาน
localhost คือชื่อปลายทางในที่นี้คือเครื่องตัวเอง สามารถเปลี่ยนเป็น 127.0.0.1 ได้
8080 คือหมายเลขพอร์ตในการทำงานของเว็บเซิร์ฟเวอร์
ejp คือชื่อเว็บแอปพลิเคชั่นที่ติดตั้งพื่อทำงานบนเว็บเซิร์ฟเวอร์
servlet คือการอ้างเพื่อใช้งานโปรแกรมเซิร์ฟเล็ต
ServletHelloWorld คือชื่อเซิร์ฟเล็ตที่เป็นชื่อไฟล์ ServletHelloWorld.class ซึ่งติดตั้งอยู่
ใน WEB-INFclasses ของเว็บแอปพลิเคชั่นอีกที
เมื่อเรียกใช้งาน ServletHelloWorld ที่สร้างจากตัวอย่างจะให้ผลลัพธ์จากการทำงานดังรูปต่อไปนี้
รูปแสดงผลลัพธ์จากเซิร์ฟเล็ต ServletHelloWorld
จากตัวอย่างผู้อ่านอาจสงสัยว่าทำไมส่วนที่เป็นภาษาไทย จึงกลายเป็นตัวอักษร ? แทน
ซึ่งจริงๆแล้วส่วนของข้อมูลดังกล่าวเป็นข้อมูลภาษาไทยครับ
แต่เนื่องจากเกิดปัญหากับระบบตัวเลขแทนรหัสตัวอักษรภาษาไทยของรหัส Unicode ดังนั้นการทำให้เกิดอักษรภาษาไทย
เซิร์ฟเล็ตจะต้องส่งข้อมูลบอกมาด้วยว่าเป็นข้อมูลในรหัสของเขตข้อมูลตัวอักษรใด ซึ่งดูได้จากหัวข้อถัดไป
ข้อความจำ
การส่งข้อมูลกลับสู่บราวเซอร์ด้วยเมธอด println จะไม่มีผลถึงการขึ้นบรรทัดใหม่ในการแสดงผลสู่ผู้ใช้โดยตรง
ซึ่งเป็นเพียงการส่งข้อมูลที่มีการแยกบรรทัดกันเท่านั้น หากต้องการแสดงข้อมูลขึ้นบรรทัดใหม่บนบราวเซอร์ให้ใช้คำสั่ง HTML คือแท็ก
BR หรือแท็ก P
3. เซิร์ฟเล็ตกับการโต้ตอบข้อมูล HTML
จากหัวข้อที่ผ่านมา ผู้เขียนได้กล่าวถึงเรื่องการสร้างเซิร์ฟเล็ตที่สามารถส่งข้อความไปสู่บราวเซอร์
เพื่อให้บราวเซอร์นำข้อมูลดังกล่าวไปแสดงผลลัพธ์บนพื้นที่ของบราวเซอร์ การนำเสนอรูปแบบดังกล่าวถูกเรียกว่า Text Plain
ซึ่งมีรูปแบบตัวอักษรหรือฟอนต์ใดฟอนต์หนึ่ง ในสีใดสีหนึ่งเท่านั้น แต่หากต้องการปรับการนำเสนอให้มีรูปแบบที่สวยงามขึ้น
ซึ่งเรียกว่า Rich Text ที่สามารถแสดงตัวอักษรรูปแบบต่างๆ ในสีที่แตกต่างกันสามารถทำให้โดยการใช้ภาษา HTML
ที่เคยกล่าวมาแล้วในบทก่อนหน้านี้ มาควบคุมตัวอักษรหรือเนื้อความ ตามตำแหน่งที่ต้องการปรับการนำเสนอ
และแน่นอนว่าภาษา HTML ก็เป็นคำสั่งที่อยู่ในรูปของตัวอักษรด้วยเช่นกัน และหากเซิร์ฟเล็ตมีการส่งคำสั่ง HTML
รวมกับข้อมูลใดๆกลับสู่บราวเซอร์ เมื่อบราวเซอร์ได้รับข้อมูลดังกล่าวกลับมา ด้วยความสามารถที่เข้าใจภาษา HTML
ที่เป็นคุณสมบัติพื้นฐานของบราวเซอร์ใดๆ ก็จะตีความคำสั่งที่บรรจุร่วมกับข้อความ
และมีการปรับรูปแบบการแสดงผลสู่ผู้ใช้ตามคำสั่ง HTML โดยเรียกข้อมูลตัวอักษรที่รวมอยู่กับคำสั่ง HTML ว่าเอกสาร HTML
ขั้นตอนการสร้างเซิร์ฟเล็ตเพื่อส่งข้อมูลที่เป็นเอกสาร HTML มีขั้นตอนตามข้อกำหนดดังนี้
ขั้นตอนที่ 1 ให้มีการกำหนดข้อมูลโต้ตอบส่วนหัว (Response Header) เพื่อระบุชนิดเอกสารว่าเป็นเอกสาร HTML
นั่นคือข้อมูลในส่วน Content Type: text/html โดยผ่านเมธอด setContentType ของคลาส HttpServletResponse
การกำหนดดังกล่าวเมื่อบราวเซอร์จะได้รับข้อมูลกร่อนที่เอกสาร HTML จะส่งกลับมา และพิจารณาว่าข้อมูลดังกล่าวเป็น text
ในแบบ html
response.setContentType("text/html ; charset=windows-874");
นอกจากนั้นแล้วหากพิจารณาข้อความต่อท้ายจากเมธอดด้านบนมีคำว่า charset=windows-874
เพื่อบอกให้บราวเซอร์ทราบเพิ่มเติมว่าการแสดงเอกสารที่จะตามมาให้ใช้ตัวอักษรในรหัส Unicode ในกลุ่มของ Windows-874
นั่นก็คือกลุ่มทีมีตัวอักษรภาษาไทยอยู่ด้วยนั่นเอง
การกำหนดดังกล่าวจะทำให้สามารถเป็นตัวอักษรภาษาไทยจากการใช้งานของผู้ใช้
ข้อแนะนำ การเรียกใช้เมธอดส่งข้อมูลนี้ควรทำก่อนที่จะส่งเอกสาร HTML
เนื่องจากลำดับการส่งข้อมูลโต้ตอบข้อมูลส่วนหัวต้องส่งก่อนข้อมูลเนื้อความ
ขั้นตอนที่ 2 ให้มีการส่งข้อมูลบ่งบอกชนิดเอกสาร HTML ว่าเป็นคำสั่ง HTML
ถูกกำหนดจากมาตรฐานอย่างไรซึ่งเป็นข้อกำหนดของเอกสาร HTML ซึ่งเป็นข้อมูลที่จะบรรจุไว้ในส่วนต้นของเอกสาร HTML
ข้อมูลบ่งบอกชนิดเอกสารที่จะใช้ในหนังสือเล่มนี้คือเอกสารที่สร้างจาก HTML เวอร์ชัน 4.0 โดยมีข้อมูลบ่งบอกชนิดเอกสาร
HTML ดังนี้คือ
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
ข้อแนะนำ สำหรับขั้นตอนการกำหนดข้อมูลบ่งบอกชนิดเอกสาร HTML นี้บางครั้งไม่จำเป็นต้องส่งก็ได้
เนื่องจากในปัจจุบันบราวเซอร์ส่วนใหญ่เข้าใจและตีความเอกสาร HTML ให้โดยอัตโนมัติ
แต่เพื่อให้เป็นมาตรฐานตรงตามข้อกำหนดของเอกสาร HTML ผู้เขียนขอแนะนำให้ส่งข้อมูลเกริ่นนำนี้ทุกครั้งที่มีการส่งเอกสาร
HTML ไปสู่บราวเซอร์ ข้อมูลบ่งบอกชนิดเอกสาร HTML ดังกล่าวอ้างถึงตามข้อกำหนดจากเอกสาร RFC ที่เว็บไซต์
(http://www.rfc-editor.org/)
ตัวอย่างต่อไปนี้แสดงการส่งเอกสาร HTML
สู่บราวเซอร์ที่บรรจุข้อความเดียวกันกับเซิร์ฟเล็ตตัวอย่างการส่งข้อมูลตัวอักษรก่อนหน้านี้ ไฟล์ในตัวอย่างคือไฟล์
HTMLDocument.java
1 import java.io.*;
2 import javax.servlet.*;
3 import javax.servlet.http.*;
4
5 public class HTMLDocument extends HttpServlet {
6 public void doGet (HttpServletRequest request, HttpServletResponse response)
7 throws ServletException, IOException {
8 //
9 response.setContentType("text/html ; charset=windows-874");
10 PrintWriter out = response.getWriter();
11 // HTML
12 out.println("<!DOCTYPE HTML PUBLIC "- //W3C//DTD HTML 4.0
Transitional//EN">");
13 // HTML
14 out.print("<HTML>n");
15 out.print("<HEAD><TITLE>HTML Document</TITLE></HEAD>n");
16 out.print("<BODY>");
17 out.print("<P> </P>");
18 out.print("<P>Welcome! to Java Servlet</P>");
19 out.print("</BODY>");
20 out.print("</HTML>n");
21 }
22 }
ซอร์สโค้ดที่ใช้สร้างเซิร์ฟเล็ต HTMLDocument เพื่อส่งเอกสาร HTML กลับสู่บราวเซอร์
ข้อแนะนำ ข้อมูลบ่งบอกชนิดเอกสาร HTML ในการแสดงตัวอักษร " ซึ่งเป็นตัวอักษรในการเปิดปิดท้ายข้อความในภาษาจาวา
จึงต้องใช้เครื่องหมาย  วางไว้ส่วนหน้าเพื่อให้เป็นส่วนหนึ่งของข้อความ
จากตัวอย่างเมื่อคอมไพล์และติดตั้งเซิร์ฟเล็ต HTMLDocument ลงในเว็บแอปพลิเคชั่น ejp และอ้างเซิร์ฟเล็ตจาก
http://localhost:8080/ejp/servlet/ServletHelloWorld ในบราวเซอร์จะได้ผลลัพธ์ดังนี้
รูปแสดงผลลัพธ์จากเซิร์ฟเล็ต HTMLDocument บนพื้นที่แสดงผลของบราวเซอร์
ข้อแนะนำ ในการแสดงข้อมูลที่เป็นตัวอักษรภาษาไทย จำเป็นต้องระบุกลุ่มของตัวอักษร (Character Set)
ในส่วนที่สนับสนุนภาษาไทย จากตัวอย่างคือ Windows-874
4. การอ่านข้อมูลจากพารามิเตอร์
เซิร์ฟเล็ตสามารถรับข้อมูลมาเพื่อประมวลผลได้
จากการทำงานของระบบเว็บเป็นการสื่อสารโดยการทำงานระหว่างบราวเซอร์และเว็บเซิร์ฟเวอร์
โดยบราวเซอร์รับผิดชอบในส่วนการแสดงผลและติดต่อกับผู้ใช้ในการรับข้อมูล
ส่วนเว็บเซิร์ฟเวอร์ที่ติดตั้งเซิร์ฟเล็ตอยู่ก็จะรับผิดชอบในส่วนของการประมวลผลหลัก ทั้งสองส่วนต้องทำงานประสานกัน
เพื่อให้ระบบเว็บเกิดเป็นบริการให้กับผู้ใช้งาน
ซึ่งบริการจะเกิดขึ้นได้นั้นเราจำเป็นต้องทำความเข้าใจว่าผู้ใช้จะสามารถส่งข้อมูลไปสู่การประมวลผลที่เซิร์ฟเล็ตได้อย่างไร
จากรูปแบบการทำงานของเว็บโดยทั่วไป บราวเซอร์สามารถส่งข้อมูลได้ 2 วิธีหลักๆ คือการส่งผ่าน URL
และผ่านข้อมูลร้องขอส่วนหัว (Request Header)
การส่งข้อมูลหรือส่งพารามิเตอร์ผ่านทาง URL ในการอ้างถึงเอกสาร HTML
หรือเซิร์ฟเล็ตสามารถส่งข้อมูลพารามิเตอร์ได้ด้วยรูปแบบดังนี้
รูปแบบ
http://host_name:port_number/web_app/servlet/Servlet?Param1=Value1&Param2=Value2, …
เมื่อ
host_name คือชื่อเครื่องที่ติดตั้งเว็บเซิร์ฟเวอร์ไว้ หากเป็นการทดสอบภายในเครื่องตนเอง ให้ใช้ localhost หรือ
127.0.0.1 แทนได้
port_number คือหมายเลขพอร์ตที่ผู้บริหารเว็บกำหนดไว้สำหรับการทำงาน หมายเลขทั่วไปที่ที่ใช้กับเว็บคือ 80
แต่หมายเลขทั่วไปของ Tomcat คือ 8080 สามารถเปลี่ยนแปลงได้
web_app คือชื่อส่วนการทำงานของเว็บแอปพลิเคชั่นบนเว็บเซิร์ฟเวอร์
Servlet คือชื่อโปรแกรมเซิร์ฟเล็ต
Param1, Param2 คือชื่อพารามิเตอร์
Value1, Value2 คือข้อมูลที่สอดคล้องกับพารามิเตอร์แต่ละตัว
สัญลักษณ์ ? สำหรับบอกเซิร์ฟเล็ตว่ามีข้อมูลพารามิเตอร์ซึ่งอยู่ด้านหลัง (วางอยู่หลังชื่อเซิร์ฟเล็ต)
สัญลักษณ์ & สำหรับการแยกพารามิเตอร์แต่ละตัวออกจากกัน (ใช้กรณีมีพารามิเตอร์มากกว่า 2 ตัว)
ตัวอย่าง
http://localhost:8080/ejp/servlet/GetParameter?name=Rungrote&surname=Phonkam
จากตัวอย่างคือการอ้างถึงเซิร์ฟเล็ตที่ชื่อ GetParameter โดยรับข้อมูลพารามิเตอร์จำนวนสองตัว ตัวแรกคือพารามิเตอร์ชื่อ name
มีข้อมูล Rungrote อยู่และพารามิเตอร์ชื่อ surname มีข้อมูล Phonkam บรรจุอยู่
การส่งข้อมูลผ่านทาง URL นี้เป็นการร้องข้อข้อมูลในแบบคำสั่ง GET ในโพรโตคอล HTTP
ซึ่งมีข้อจำกัดที่ข้อมูลไม่ควรมีความยากเกิน 255 ตัวนับรวมข้อมูลทั้งหมด (รวมทั้ง URL และพารามิเตอร์)
และก็เป็นการเสียเวลาของผู้ใช้ที่ต้องพิมพ์ข้อมูลลงไปที่ URL โดยตรง
เมื่อต้องการสร้างเซิร์ฟเล็ตที่สามารถอ่านข้อมูลพารามิเตอร์จากการเรียกใช้งานเซิร์ฟเล็ต
สามารถทำได้โดยง่ายโดยการเรียกใช้งานเมธอดที่อยู่ของคลาส HttpServletRequest คือเมธอดชื่อ getParameter
ดังมีรูปแบบการทำงานดังนี้
รูปแบบ
public String getParameter(String parameter_name)
เมื่อ
Parameter_Name คือชื่อพารามิเตอร์ที่ต้องการอ่านค่า
ลองพิจารณาจากตัวอย่างไฟล์ GetParameters.java
ต่อไปนี้ซึ่งเป็นซอร์สโค้ดสำหรับการอ่านข้อมูลพารามิเตอร์จากการใช้งานของบราวเซอร์ โดยเรียกใช้เมธอด getParametes จากคลาส
HttpServletRequest ดังนี้
1 import java.io.*;
2 import javax.servlet.*;
3 import javax.servlet.http.*;
4
5 public class GetParameters extends HttpServlet {
6 public void doGet (HttpServletRequest request, HttpServletResponse response)
7 throws ServletException, IOException {
8 response.setContentType("text/html; charset=windows-874");
9 PrintWriter out = response.getWriter();
10 out.println("<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">");
11 out.print("<HTML>n");
12 out.print("<HEAD><TITLE> </TITLE></HEAD>n");
13 out.print("<BODY>");
14 out.print("<P>Name ( ) = " +
request.getParameter("name") + "</P>");
15 out.print("<P>Surname ( ) = " +
request.getParameter("surname") +
16 "</P>");
17 out.print("</BODY>");
18 out.print("</HTML >n");
19 }
20 }
ตัวอย่างเซิร์ฟเล็ตเพื่ออ่านข้อมูลพารามิเตอร์มีการเรียกใช้เมธอด getParameter ในบรรทัดที่ 14 และ 15
เพื่ออ่านข้อมูลจากพารามิเตอร์ที่ชื่อ name และ surname ตามลำดับ
ในการอ่านข้อมูลแต่ละครั้งมีการนำข้อมูลดังกล่าวมาแสดงร่วมกับเอกาสร HTML ที่ถูกส่งไปสู่บราวเซอร์ผ่านเมธอด print
ข้อแนะนำ ชื่อพารามิเตอร์ที่ใช้ใน URL หากกำหนดด้วยตัวอักษรเล็กหรือใหญ่นั่น เมื่อต้องการอ่านจากเมธอด getParameter
ชื่อพารามิเตอร์ในอาร์กิวเม็นต์ควรใช้เหมือนกันทั้งตัวเล็กหรือใหญ่
เนื่องจากโปรแกรมเซิร์ฟเล็ตต้องสามารถนำไปใช้งานกับคอมพิวเตอร์ทุกระบบ มีเพียงวินโดว์เท่านั้นซึ่งตัวอักษรเล็กและใหญ่มีค่าเท่ากัน
สำหรับยูนิกส์หรือลีนุ๊กซ์จำเป็นต้องอ้างให้ถูกต้องว่าตัวเล็กหรือตัวใหญ่
ดังนั้นเพื่อหลีกเลี่ยงปัญหาที่อาจจะเกิดขึ้นเซิร์ฟเล็ตจึงกำหนดให้ใช้ตัวอักษรให้เหมือนกันด้วยทั้งตัวเล็กและตัวใหญ่
หลังจากการคอมไพล์แล้วได้ไฟล์ GetParameters.class เมื่อนำไปติดตั้งตามตำแหน่งที่ถูกต้องแล้วเริ่มทดสอบด้วยการอ้างผ่าน URL
ต่อไปนี้ในครั้งแรก ซึ่งเป็นการอ้างถึงเซิร์ฟเล็ตโดยไม่ส่งข้อมูลพารามิเตอร์ไปกับการร้องขอ
ตัวอย่าง 1 การอ้างถึงเซิร์ฟเล็ต GetParameters โดยไม่ส่งข้อมูลพารามิเตอร์
http://localhost:8080/ejp/servlet/GetParameters
รูปแสดงผลลัพธ์จากการทำงานของเซิร์ฟเล็ต GetParameters โดยไม่ป้อนพารามิเตอร์เมื่อใช้ผ่าน URL
จากรูปเป็นตัวอย่างของผลลัพธ์จากเซิร์ฟเล็ต GetParameters แต่เนื่องจาก URL
ที่เรียกใช้เซิร์ฟเล็ตดังกล่าวไม่ได้ส่งพารามิเตอร์ไปพร้อมกับ URL ดังนั้นผลลัพธ์ที่ได้จึงปรากฏข้อความ null
ขึ้นมาต่อท้ายข้อความในตำแหน่งที่มีการอ้างถึงเมธอด getParameter เนื่องจากพารามิเตอร์ที่อ่านได้จากเซิร์ฟเล็ตไม่ปรากฏค่าใดๆ
การทดสอบครั้งต่อไปมีการอ้างถึงเซิร์ฟเล็ตแต่กำหนดพารามิเตอร์ที่มีข้อมูลเป็นภาษาอังกฤษดังนี้
ตัวอย่าง 2 การอ้างถึงเซิร์ฟเล็ต GetParameters พร้อมพารามิเตอร์
http://localhost:8080/ejp/servlet/GetParameters?name=Rungrote&surname=Phonkam
รูปแสดงผลลัพธ์จากการทำงานของเซิร์ฟเล็ต GetParameters โดยป้อนพารามิเตอร์เมื่อใช้ผ่าน URL
แต่หากเมื่อมีการเรียกใช้เซิร์ฟเล็ตผ่าน URL โดยมีการส่งข้อมูลพารามิเตอร์ไปด้วย
ซึ่งเซิร์ฟเล็ตจะสามารถอ่านข้อมูลพารามิเตอร์ได้จากชื่อพารามิเตอร์ และจากทำงานของเซิร์ฟเล็ต GetParameters
ทำให้ผลลัพธ์ที่ได้แสดงออกมาดังที่เห็นได้จากรูปด้านบน คือพารามิเตอร์ตัวแรกชื่อ name ปรากฏข้อความ Rungrote
ส่วนพารามิเตอร์ตัวที่สองชื่อ surname ปรากฏข้อความ Phonkam ที่นี้ลองมาทดสอบในครั้งต่อไปด้วยข้อมูลภาษาไทยกันดูบ้าง
การอ่านข้อมูลพารามิเตอร์ภาษาไทย
ในตัวอย่างการทดสอบครั้งต่อไปเป็นการเรียกใช้งานพารามิเตอร์ที่มีการส่งข้อมูลพารามิเตอร์ที่เป็นตัวอักษรภาษาไทย
ไปพร้อมกับข้อมูลพารามิเตอร์ ซึ่งสังเกตได้จากการอ้างถึงด้วย URL ดังต่อไปนี้
ตัวอย่าง 3 การอ้างถึงเซิร์ฟเล็ต GetParameters พร้อมข้อมูลพารามิเตอร์ภาษาไทย
http://localhost:8080/ejp/servlet/GetParameters?name=รุ่งโรจน์&surname=โพนคำ
จาก URL ข้างต้น ทำให้ได้ผลลัพธ์ในพื้นที่แสดงผลของบราวเซอร์ดังนี้ คือ
หากสังเกตดูให้ดีจากรูปจะเห็นว่าข้อมูลพารามิเตอร์ที่ได้ไม่แสดงตัวอักษรภาษาไทยที่ส่งไป แต่กลับเป็นตัวอักษร ????
ที่เคยพบในตัวอย่างของการเรียกใช้งานเซิร์ฟเล็ต ServletHelloWorld
ผู้อ่านคงเกิดอาการสงสัยแล้วซิว่าเกิดอะไรขึ้นกับตัวอักษรภาษาไทย เซิร์ฟเล็ตสนับสนุนการทำงานภาษาไทยหรือไม่
ลองมาดูเหตุผลกันก่อนที่จะสรุปผลนะครับ จากตัวอย่างซอร์สโค้ด GetParameters มีคำสั่งในการกำหนดค่า charset=windows-874
แล้วซึ่งใช้บอกบราวเซอร์ให้ใช้ตัวอักษรในกลุ่มภาษาไทยในการแสดงผล แต่เนื่องจากข้อมูล URL
ที่ป้อนจากบราวเซอร์เพื่อส่งไปให้เว็บเซิร์ฟเวอร์ ตามรูปแบบการส่งข้อมูลซึ่งอาศัยการส่งแบบกลุ่มตัวอักษร UTF-8
ซึ่งเป็นการแทนตัวอักษรแต่ละตัวด้วยข้อมูลขนาด 8 บิต
และการส่งข้อมูลลักษณะเช่นนี้หากเป็นภาษาไทยก็คือการนำเอารหัสตัวอักษรที่ใช้ในรหัส ASCII มาใช้งาน ซึ่งเริ่มต้นตั้งแต่ค่า A1 ถึง FB
(ฐานสิบคือ 161 ถึง 251) คือ 'ก' เป็นต้นไป ในขณะที่ระบบปฏิบัติการคอมพิวเตอร์ในปัจจุบันสนับสนุนการเก็บข้อมูลในรูปแบบ
Unicode และภาษาไทยของรหัส Unicode ก็ไม่ได้ใช้รหัสเดียวกันกับที่ใช้ใน ASCII ซึ่งภาษาไทยที่ใช้ใน Unicode ตามกลุ่ม Windows-
874 มีค่าอยู่ระหว่าง E01 ถึง E5B ลองพิจารณาตารางการแสดงข้อมูลตัวอักษรภาษาไทยเปรียบเทียบกันระหว่าง ASCII และ Windows-
874
รูปแสดงการแทนรหัส ASCII (ฐานสิบหก) ในช่วงอักษรภาษาไทย
รูปแสดงการแทนรหัส Unicode (ฐานสิบหก) ในช่วงอักษรภาษาไทย ตามข้อกำหนด Windows-874
ข้อแนะนำ รายละเอียดของข้อมูล Unicode ศึกษาเพิ่มเติมได้จาก www.Unicode.org
ทางแก้ไขปัญหานี้คือการสร้างส่วนการทำงานที่สามารถสลับกันไปมาระหว่างข้อมูล ASCII และข้อมูล Unicode ให้ได้
ดังนั้นจึงสร้างคลาสที่มีเมธอดสนับสนุนในเรื่องตัวอักษรภาษาไทย ดังตัวอย่างต่อไปนี้ในไฟล์ ThaiUtilities.java
1 package EJP;
2
3 public class ThaiUtilities {
4 public static String Unicode2ASCII(String unicode) { // Unicode ASCII
5 if (Unicode==null)
6 return null;
7 StringBuffer ascii = new StringBuffer(unicode); //
8 int code;
9 for(int i =0; i < unicode.length(); i++) { //
10 code = (int)unicode.charAt(i); //
11 if ((0xE01<=code) && (code <=0xE5B )) //
Unicode
12 ascii.setCharAt( i, (char)(code – 0xD60)); //
ASCII
13 }
14 return ascii.toString(); // String
15 }
16
17 public static String ASCII2Unicode(String ascii) {
18 if (ascii==null)
19 return null;
20 StringBuffer unicode = new StringBuffer(ascii);
21 int code;
22 for(int i =0; i < ascii.length(); i++) {
23 code = (int)ascii.charAt(i);
24 if ((0xA1 <= code) && (code <= 0xFB)) //
ASCII
25 unicode.setCharAt( i, (char)(code + 0xD60)); //
Unicode
26 }
27 return unicode.toString(); // String
28 }
29 }
ซอร์สโค้ดในคลาส ThaiUtilities มีการสร้างเมธอด 2 เมธอด โดยเมธอดแรกชื่อ Unicode2ASCII
ที่ใช้สำหรับแปลงกลุ่มตัวอักษรภาษาไทยจากรหัส ASCII ไปเป็น Unicode กลุ่ม Windows-874 ในขณะที่เมธอดที่สองชื่อ
ASCII2Unicode ใช้สำหรับแปลงกลุ่มตัวอักษรภาษาไทยจากรหัส Unicode ไปเป็น ASCII และจากซอร์สโค้ดบรรทัดที่ 1
ป็นการสร้างคลาสในแพ็กเกจที่ชื่อ EJP (มาจาก Enterprise Java Programming) ดังนั้นในการคอมไพล์จึงต้องระบุออปชั่น –d
เอาไว้ด้วย ซึ่งมีรูปแบบดังนี้
คำสั่งคอมไพล์ซอร์สโค้ด ThaiUtilities.java ในแบบแพ็กเกจ
javac.exe -d . ThaiUtilities.java
หลังจากคอมไพล์เรียบร้อยแล้ว ในขั้นตอนต่อไปเป็นการปรับปรุงคลาส GetParameter ไปเป็นคลาสใหม่คือ GetThaiParameter
เพื่อสนับสนุนการหากมีการเรียกใช้งานเซิร์ฟเล็ตแล้วมีค่าพารามิเตอร์ที่ตัวอักษรภาษาไทย ดังไฟล์ GetThaiParametes.java ดังนี้
1 import java.io.*;
2 import javax.servlet.*;
3 import javax.servlet.http.*;
4 import EJP.ThaiUtilities;
5
6 public class GetThaiParameters extends HttpServlet {
7 public void doGet (HttpServletRequest request, HttpServletResponse response)
8 throws ServletException, IOException {
9 response.setContentType("text/html; charset=windows-874");
10 PrintWriter out = response.getWriter();
11 out.println("<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">");
12 out.print("<HTML>n");
13 out.print("<HEAD><TITLE> </TITLE></HEAD>n");
14 out.print("<BODY>");
15 String paramName = ThaiUtilities.ASCII2Unicode(request.getParameter("name"));
16 out.print("<P>Name ( ) = " + paramName + "</P>");
17 String paramSurname = ThaiUtilities.ASCII2Unicode(request.getParameter("surname"));
18 out.print("<P>Surname ( ) = " + paramSurname +
"</P>");
19 out.print("</BODY>");
20 out.print("</BODY>n");
21 }
22 }
จากซอร์สโค้ดมีการกำหนดการอิมพอร์ตแพ็กเกจ EJP ในบรรทัดที่ 4 เพื่อให้สามารถใช้งานคลาส ThaiUtilities ได้ และในบรรทัดที่
15 และ 17 มีการเรียกใช้งานเมธอด ASCII2Unicode โดยมีอาร์กิวเม็นต์เป็นข้อมูลพารามิเตอร์ของทั้ง name และ surname
ซึ่งเป็นตัวอักษรภาษาไทยในระบบ ASCII ดังนั้นผลลัพธ์ที่ได้คือรับคือจากเมธอด ASCII2Unicode
จึงเป็นตัวอักษรเดียวกันแต่เป็นระบบของ Unicode แทน จากนั้นนำเอามารวมไว้ในตัวแปร prramName และ paramSurname
สำหรับพารามิเตอร์ name และ surname ตามลำดับ เมื่อคอมไพล์ไฟล์ซอร์สโค้ดและนำมาติดตั้งนตำแหน่งที่ถูกต้อง
จากนั้นทดสอบการใช้งานของเซิร์ฟเล็ต GetThaiParameters ด้วย URL ดังนี้
http://localhost:8080/ejp/servlet/GetThaiParameters?name=รุ่งโรจน์&surname=โพนคำ
ซึ่งทำให้ได้ผลลัพธ์ที่จากการอ่านพารามิเตอร์ที่บรรจุข้อมูลตัวอักษรภาษาไทยได้อย่างถูกต้อง
ตามรูปที่ปรากฎบนพื้นที่ของบราวเซอร์ดังนี้
รูปแสดงผลลัพธ์จากการทำงานของเซิร์ฟเล็ต GetParameters โดยป้อนพารามิเตอร์เมื่อใช้ผ่าน URL ที่เป็นภาษาไทย
การส่งข้อมูล URL นอกจากจะสามารถระบุด้วยการพิมพ์ตัวอักษรจากคีย์บอร์ดไปโดยตรงแล้ว
ยังสามารถระบุได้ด้วยการกำหนดค่าฐานสิบหกของรหัสในรูปแบบ UTF-8 ด้วยเช่นกัน โดยพิมพ์ค่าฐานสิบหกต่อจากเครื่องหมาย %
เช่นหากต้องการส่งข้อมูล "ก" ก็พิมพ์ข้อมูล %A1 ซึ่งการส่งลักษณะนี้เรียกว่าการส่งข้อมูลในแบบการเข้ารหัส หรือเอ็นโค้ด (Encode)
ลองทสดสอบการส่งข้อมูลพารามิเตอร์ที่เข้ารหัสภาษาไทยไว้ โดยให้พารามิเตอร์ name บรรจุตัวอักษรคำว่า "ภาษา" และ
surname บรรจุตัวอักษรภาษาไทยคำว่า "จาวา" ด้วย URL ดังนี้
ตัวอย่าง 4 การอ้างถึงเซิร์ฟเล็ต GetThaiParameters พร้อมข้อมูลพารามิเตอร์ภาษาไทยที่เข้ารหัสไว้
http://localhost:8080/examples/servlet/GetThaiParameters?name=%C0%D2%C9%D2&surname=%A8%D2%C7%D2
เมื่อ
คำว่า ภาษา คือค่า %C0%D2%C9%D2
คำว่า จาวา คือค่า %A8%D2%C7%D2
จากการทดสอบการทำงานกับคลาส GetThaiParameters
ซึ่งก็สามารถเข้าใจรหัสที่ได้รับการเข้ารหัสไว้ว่าเป็นข้อมูลตัวอักษรในกลุ่ม ASCII ดังนั้นจึงถูกแปลงไปเป็น Windows-874 ด้วยเมธอด
ASCII2Unicode เหมือนกับพารามิเตอร์ที่เป็นตัวอักษรภาษาไทยปกติที่ไม่ได้เข้ารหัส ดังนั้นผลลัพธ์ของการทำงานจึงเป็นดังนี้
รูปแสดงผลลัพธ์จากการทำงานของเซิร์ฟเล็ต GetThaiParameters จาก URL ที่มีพารามิเตอร์ภาษาไทยที่เข้ารหัสไว้
การอ่านค่าพารามิเตอร์หลายค่า
จากรูปแบบการใช้งานเซิร์ฟเล็ตผ่าน URL เพื่อป้อนข้อมูลพารามิเตอร์นั้นอาจทำให้เกิดความไม่สะดวกขึ้น
เนื่องจากหากต้องการป้อนข้อมูลพารามิเตอร์มีความยาวมากๆทำให้เกิดความยุ่งยากในการพิมพ์ตัวอักษรซึ่งอาจผิดพลาดได้
ดังนั้นการร้องขอในแบบ GET ผ่านทาง URL สามารถใช้ลักษณะของการทำงานของเอกสาร HTML ที่เรียกกันว่าฟอร์ม (FORM)
โดยสร้างฟอร์มที่บรรจุช่องกรอกข้อมูล (Text Field) สำหรับพารามิเตอร์แต่ละตัว
หรืออาจจะสร้างรูปแบบการกรอกข้อมูลแบบอื่นๆประกอบกันในฟอร์มก็ได้ เช่น กล่องข้อความขนาดใหญ่ (Text Area)
กล่องเลือกทั้งแบบ Radio Box และ Check Box ปุ่มกด (Button) เป็นต้น
1 <html>
2 <head>
3 <title>User Profile</title>
4 <meta http-equiv="Content-Type" content="text/html; charset=windows-874">
5 </head>
6
7 <body bgcolor="#FFFFFF">
8 <form name="frmUserProfile" method="get"
9 action="http://localhost:8080/examples/servlet/GetMoreParameters">
10 <p> <input type="text" name="name">
11 <input type="text" name="surname"></p>
12 <p> <input type="radio" name="gender" value="Male">
13 <input type="radio" name="gender" value="Female"> </p>
14 <p> <input type="text" name="dd" size="2" maxlength="2"> /
15 <input type="text" name="mm" size="2" maxlength="2"> /
16 <input type="text" name="yyyy" size="4" maxlength="4">
( / / )</p>
17 <p> <textarea name="address" cols="70" rows="6"></textarea></p>
18 <p><input type="submit" name="Submit" value="Submit"></p>
19 </form>
20 </body>
21 </html>
จากตัวอย่างด้านบนคือเอกสาร HTML ในไฟล์เอกสารใดๆก็ได้แต่ให้มีนามสกุล html หรือ htm เช่น TestFarameterForm.htm
ซึ่งเป็นการสร้างเอกสารที่เป็นฟอร์มกรอกข้อมูลโดยบรรจุส่วนในการบันทึกข้อมูลที่สามารถใส่ได้จากผู้ใช้
โดยมีการแบ่งเป็นพารามิเตอร์ดังนี้
ชนิด ชื่อพารามิเตอร์ ปรากฏในบรรทัดที่
Text Field name 10
Text Field surname 11
Radio Box gender 12 และ 13
Text Field dd 14
Text Field mm 15
Text Field yyyy 16
Text Area address 17
Button Submit 18
สำหรับฟิลด์ Submit นี้สำหรับเพื่อให้ผู้ใช้กดเพื่อส่งข้อมูลไปยังเซิร์ฟเล็ตที่อ้างจากแอตทริบิวต์ action
ในแท็กฟอร์มที่ปรากฏในบรรทัดที่ 9 ข้อสังเกตอีกข้อหนึ่งในบรรทัดที่ 8 เป็นการกำหนดรูปแบบการส่งข้อมูลด้วยคำสั่ง get
จากแอตทริบิวต์ method ในโพรโตคอล HTTP
จากการเปิดใช้งานฟอร์มในบราวเซอร์ สามารถแสดงผลได้ดังนี้ คือ
รูปแสดงฟอร์มที่เกิดจากเอกสาร HTML
หากเซิร์ฟเล็ตแต่หากมีพารามิเตอร์หลายตัว และอาจเป็นพารามิเตอร์ที่ไม่สามารถคาดเดาได้ว่ามีชื่ออะไร
เซิร์ฟเล็ตสามารถจัดการกับพารามิเตอร์ได้ในคราวละหลายๆตัว โดยอาศัยเมธรดที่อยู่ใน HttpServletRequest ดังนี้
รูปแบบ
public Enumeration getParameterNames()
เมื่อ
Enumeration คือคลาสที่ใช้ในการเก็บข้อมูลเป็นลีสต์ (List)
เมธอด getParameterNames จะส่งข้อมูลรายการพารามิเตอร์ทั้งหมดเก็บไว้ในรูปแบบ Enumeration จากแบบฟอร์มอกสาร
HTML ในส่วนต้นนั้น เมื่อผู้ใช้กรอกข้อมูลลงในแต่ละฟิลด์และแต่ละฟิลด์คือพารามิเตอร์แต่ละตัวซึ่งแต่ละตัวจะถึงส่งไปให้เซิร์ฟเล็ต
ดังนั้นการอ่านข้อมูลพารามิเตอร์ที่สามารถอ่านทั้งชื่อพารามิเตอร์มาใช้งาน จึงสามารถอ่านได้จากข้อมูลรูปแบบ Enumeration
ที่ได้รับมาจากเมธอด getParameterNames ดังแสดงให้เห็นจากตัวอย่างซอร์สโค้ด GetMoreParameters.java ต่อไปนี้
1 import java.io.*;
2 import java.util.*; // Enumeration
3 import javax.servlet.*;
4 import javax.servlet.http.*;
5
6 public class GetMoreParameters extends HttpServlet {
7 public void doGet (HttpServletRequest request, HttpServletResponse response)
8 throws ServletException, IOException {
9 response.setContentType("text/html; charset=windows-874");
10 PrintWriter out = response.getWriter();
11 out.println("<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">");
12 out.print("<HTML>n");
13
out.print("<HEAD><TITLE> </TITLE></H
EAD>n");
14 out.print("<BODY>");
15
16 Enumeration enumParams = request.getParameterNames(); //
17 while (enumParams.hasMoreElements()) { //
18 //
String
19 String paramName = (String)enumParams.nextElement();
20 out.print("<P>Parameter Name: <B>" + paramName + "</B>");
21 out.print(" Parameter Value: <B>" +
22 ThaiUtilities.ASCII2Unicode(request.getParameter(paramName)) + "</B>");
23 }
24 out.print("</BODY>");
25 out.print("</HTML>n");
26 }
27 }
จากตัวอย่างในบรรทัดที่ 16 เป็นการอ่านพารามิเตอร์มาเก็บไว้ในตัวแปร enumParams
จากนั้นมีการวนลูปผ่านเมธอดเพื่อตรวจสอบว่ายังคงมีพารามิเตอร์อยู่ใน enumParams หรือไม่ซึ่งเป็นคำสั่งในบรรทัดที่ 17
ในแต่ละลูปในบรรทัดที่ 19 มีการอ่านชื่อพารามิเตอร์ผ่านเมธอด nextElement และแปลงออปเจ็คที่ได้ให้เป็น String
เก็บไว้ในตัวแปร paramName ซึ่งข้อมูลที่ได้คือชื่อของพารามิเตอร์แต่ละตัว ในบรรทัดที่ 22 เป็นการนำเอาชื่อที่บรรจุในตัวแปร
paramName มาใช้งานในการอ่านข้อมูลพารามิเตอร์ผ่านเมธอด getParameter เพื่อแสดงต่อไป
รูปแสดงข้อมูลที่ป้อนให้กับฟอร์มเพื่อส่งไปให้เซิร์ฟเล็ต GetMoreParameters
จากรูปด้านบนแสดงการกรอกข้อมูลลงในฟอร์มของเอกสาร HTML จากนั้นกดที่ปุ่ม Submit ด้านล่างของเอกสาร
ข้อมูลทั้งหมดถูกเก็บเป็นพารามิเตอร์ส่งให้กับเซิร์ฟเล็ต getMoreParameters และหลังจากกดปุ่มข้อมูลในช่อง URL
ของบราวเซอร์เปลี่ยนเป็นดังนี้
http://localhost:8080/examples/servlet/GetMoreParameters?name=%E3%B9%B9%E9%D3%C1%D5%BB%C5%D2&surname=
%E3%B9%B9%D2%C1%D5%A2%E9%D2%C7&gender=Male&dd=27&mm=9&yyyy=2513&address=%BE%D7%E9%B9%B7%
D5%E8%CD%D1%B9%CD%D8%B4%C1%CA%C1%BA%D9%C3%B3%EC+%E1%CB%E8%A7%CB%B9%D6%E8%A7%E3%B9
%E0%C1%D7%CD%A7%E4%B7%C2&Submit=Submit
หากสังเกตจากข้อมูล URL พบว่าข้อมูลพารามิเตอร์ที่ป้อนเป็นตัวอักษรภาษาไทยได้ถูกเข้ารหัสเรียบร้อยแล้ว
ซึ่งการทดสอบผู้ใช้ทดสอบจากบราวเซอร์ที่ชื่อ Internet Explorer
ที่ตั้งข้อกำหนดไว้ว่าให้ส่งข้อมูลที่นอกเหนือจากตัวอักษรภาษาอังกฤษเป็นตัวอักษรที่เข้ารหัสตัวอักษรไว้
ข้อแนะนำ สำหรับเว็บบราวเซอร์ชื่อ Internet Explorer สามารถกำหนดรูปแบบการเข้ารหัส URL ได้จากเมนู Tools -> Internet
Options คลิกที่แท็บ Advanced และเลือกที่รายการ Always send URLs and UTF-8
ส่วนในพื้นที่การแสดงผลหลังจากกดปุ่ม Submit ซึ่งเกิดจากการทำงานของเซิร์ฟเล็ต GetMoreParameters เป็นดังนี้
รูปแสดงการทำงานของเซิร์ฟเล็ต GetMoreParameters ที่ถูกเรียกผ่านฟอร์มเอกสาร HTML
การส่งข้อมูลด้วยเว็บรูปแบบ POST ด้วยฟอร์ม HTML
จากข้อมูลที่นำเสนอแก่ผู้อ่าน ข้อมูลส่วนใหญ่ที่ส่งข้อมูลพารามิเตอร์จากบราวเซอร์ไปยังเว็บเซิร์ฟเวอร์เป็นรูปแบบ GET
สังเกตจากข้อมูลปรากฏที่ URL ด้วยหรือแม้จาส่งด้วยการกรอกฟอร์มก็ตาม ในแท็ก FORM ของภาษา HTML ก็ระบุแอตทริบิวต์
METHOD = "GET" ซึ่งข้อเสียแน่นอนว่าผู้อื่นสามารถมองเห็นข้อมูลที่ช่อง Address ของบราวเซอร์โดยตรง
ในการที่จะหลีกเลี่ยงปัญหานี้จำเป็นต้องกำหนดรูปแบบการส่งข้อมูลเป็นแบบใหม่คือแบบ POST
ซึ่งการส่งรูปแบบนี้เป็นการส่งข้อมูลพารามิเตอร์ไปยังส่วนหัวของข้อมูลร้องขอ ซึ่งข้อมูลพารามิเตอร์ในแบบ POST นี้จะไม่อยู่รวมกับ
URL เหมือนในแบบ GET ที่เห็นได้จากช่องแอดเดรสของบราวเซอร์ทั่วไป (ในแบบ GET
ข้อมูลพารามิเตอร์ถือเป็นส่วนหนึ่งของคำสั่งร้องข้อ) การส่งพารามิเตอร์แบบ POST นี้จำเป็นต้องอาศัยรูปแบบการสร้างฟอร์มของภาษา
HTML โดยระบุส่วนแอตทริบิวต์ METHOD = "POST" ในแท็ก FORM ดังนี้
<FORM METHOD="POST" ACION="……." >
…
</FORM>
นอกจากมีการแก้ไขเอกสาร HTML แล้วยังต้องแก้ไขซอร์สโค้ดของเซิร์ฟเล็ตร่วมด้วย ซึ่งศึกษาได้จากเนื้อหาในส่วนต่อไปนี้
เซิร์ฟเล็ตที่สนับสนุนคำสั่งรูปแบบ POST
โปรแกรมเซิร์ฟเล็ตที่สร้างกันมาตั้งแต่ต้นนั้นสนับสนุนการทำงานเมื่อบราวเซอร์ร้องข้อในรูปแบบ GET เท่านั้น
สังเกตได้จากในซอร์สโค้ดมีการสร้างสเตจเม็นต์ส่วนการประมวลผลไว้ในเมธอด doGet ทั้งหมด
แน่นอนว่าหากต้องการสร้างเซิร์ฟเล็ตที่สนับสนุนการร้องขอในแบบ POST ด้วยแล้วต้องสร้างคำสั่งไว้ในเมธอด doPost แทน
นั่นก็คือให้ย้ายสเตจเม็นต์จาก doGet ไปใส่ไว้ใน doPost นั่นเอง
รูปแบบ
public void doPost (HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
…
}
ผู้อ่านอาจจะมีคำถามในใจว่าแล้วอย่างนี้หากต้องการสร้างเซิร์ฟเล็ตที่รอบรับทั้งรูปแบบ GET และรูปแบบ POST
ภายในเซิร์ฟเล็ตตัวเดียวกันนั้น ก็ต้องสร้างสเตจเม็นต์เอาไว้ทั้งเมธอด doGet และ doPost หรือไม่? แน่นอนครับว่าควรจะเป็นแบบนั้น
แต่ในการสร้างเซิร์ฟเล็ตลักษณะนี้จะทำให้โปรแกรมมีขนาดใหญ่และคลาสมีมีความซ้ำซ้อนขึ้นตามไปด้วย
วิธีการแก้ปัญหานี้ก็คคือให้สร้างสเตจเม็นต์ไว้ในเมธอดใดเมธอดหนึ่งระหว่าง doGet หรือ doPost
จากนั้นใช้เมธอดที่เหลือเรียกเมธอดนั่น เช่น เมื่อสร้างสเตจเม็นต์เอาไว้ในเมธอด doGet ก็ให้เมธอด doPost เรียกใช้งานเมธอด doGet
หรือในทางกลับกันหากสร้างสเตจเม็นต์ไว้ในเมธอด doPost แล้วก็ให้เมธอด doGet เรียกใช้งานเมธอด doPost แทน
เพื่อให้เกิดความเข้าใจให้พิจารณาจากซอร์สโค้ดต่อไปนี้
ต่อไปนี้เป็นการปรับปรุงเซิร์ฟเล็ตที่ชื่อ GetMoreParameters เป็นเซิร์ฟเล็ตตัวใหม่ชื่อ PostParameters
เพื่อให้สามารถรองรับข้อมูลได้ทั้งจากการร้องขอในแบบ POST และแบบ GET ในไฟล์ ReadParameters ดังนี้
1 import java.io.*;
2 import java.util.*;
3 import javax.servlet.*;
4 import javax.servlet.http.*;
5 import EJP.ThaiUtilities;
6
7 public class ReadParameters extends HttpServlet {
8 public void doGet (HttpServletRequest request, HttpServletResponse response)
9 throws ServletException, IOException {
10 response.setContentType("text/html; charset=windows-874");
11 PrintWriter out = response.getWriter();
12 out.println("<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">");
13 out.print("<HTML>n");
14 out.print("<HEAD><TITLE>
GET POST</TITLE></HEAD>n");
15 out.print("<BODY>");
16
17 Enumeration enumParams = request.getParameterNames();
18 while (enumParams.hasMoreElements()) {
19 String paramName = (String)enumParams.nextElement();
20 out.print("<P>Parameter Name: <B>" + paramName + "</B>");
21 out.print(" Parameter Value: <B>" +
22 ThaiUtilities.ASCII2Unicode(request.getParameter(paramName)) + "</B>");
23 }
24 out.print("</BODY>");
25 out.print("</HTML>n");
26 }
27 public void doPost (HttpServletRequest request, HttpServletResponse response)
28 throws ServletException, IOException {
29 doGet(request, response);
30 }
31 }
หากสังเกตจากซอร์สโค้ดจะพบว่าคลาส ReadParameters มีการสร้างเมธอด doGet ในบรรทัดที่ 8-26
ซึ่งบรรจุสเตจเม็นต์รองรับการทำงานทั้งหมดของเซิร์ฟเล็ต และเมธอด goPost ในบรรทัดที่ 17-30 ที่มีเพียงสเตจเม็นในบรรทัดที่ 29
ที่เป็นการเรียกใช้เมธอด doGet โดยผ่านอาร์กิวเม็นต์ที่ตัวเองได้รับคือทั้ง request และ response ตามไปด้วย
ลองมาทดสอบการทำงานของเซิร์ฟเล็ต ReadParameters ด้วยตัวอย่างของเอกสาร HTML
ที่ส่งข้อมูลพารามิเตอร์ไปในรูปแบบ POST ดังนี้
1 <html>
2 <head>
3 <title>POST Form</title>
4 <meta http-equiv="Content-Type" content="text/html; charset=windows-874">
5 </head>
6
7 <body bgcolor="#FFFFFF">
8 <form name="frmPOST" method="POST"
9 action="http://localhost:8080/examples/servlet/ReadParameters">
10 <p> ?
11 <input type="text" name="SPORT">
12 </p>
13 <input type="submit" name="" value=" ">
14 </form>
15 </body>
16 </html>
จากเอกสาร HTML ข้างต้นเป็นการสร้างฟอร์มเพื่อส่งในแบบ POST จากบรรทัดที่ 8 ซึ่งระบุแอตทริบิวต์ method="POST"
ไปยังเซิร์ฟเล็ต ReadParameters จากแอตทริบิวต์ action ในบรรทัดที่ 9 ในฟอร์มมีช่องกรอกข้อมูลพารามิเตอร์ชื่อ SPORT
กับปุ่มส่งข้อมูลในบรรทัดที่ 11 และ 13 ตามลำดัง ซึ่งเมื่อเปิดเอกสารจากบราวเซอร์จะปรากฏผลลัพธ์และข้อมูลผลลพธ์ดังนี้
ก) ป้อนข้อมูลลงในเอกสาร HTML ไฟล์
ข) ผลลัพธ์จากการทำงานของเซิร์ฟเล็ต ReadParamaters
รูปแสดงการทำงานเอกสาร HTML และเซิร์ฟเล็ต ReadParameter
คลาส HTMLUtilities ช่วยสร้างเว็บเพจ
ก่อนที่จะข้ามไปสู่เนื้อหาในบทต่อไป ผู้เขียนขอแนะนำคลาสในกลุ่มของ Utility คือคลาส HTMLUtilities
ที่ช่วยในการเสริมการทำงานในการสร้างเอกสาร HTML ในการทำงานของเซิร์ฟเล็ต โดยในคลาสประกอบด้วยเมธอด createHTMLStart
ใช้ในการกำหนดข้อมูลส่วนต้นๆของเอสการ HTML นั่นคือแท็กเปิดของ HTML, HEAD และ BODY
รวมถึงการกำหนดชื่อเอกสารในแท็ก TITLE ด้วยอาร์กิวเม็นต์ที่ผ่านเข้ามา
ส่วนเมธอดที่สองคือ createHTMLend ซึ่งเป็นการสร้างเอกสารส่วนท้ายคือแท็กปิดต่างๆ ทั้ง BODY และ HTML
ดังซอร์สโค้ดต่อไปนี้
1 package EJP;
2 import java.io.*;
3 import javax.servlet.*;
4 import javax.servlet.http.*;
5
6 public class HTMLUtilities {
7 public static void createHTMLStart (PrintWriter out, String title) {
8 out.println("<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">");
9 out.print("<HTML>n");
10 out.print("<HEAD><TITLE>" + title + "</TITLE></HEAD>n");
11 out.print("<BODY>");
12 }
13 public static void createHTMLEnd (PrintWriter out) {
14 out.print("</BODY>");
15 out.print("</BODY>n");
16 }
17 }
คลาส HTMUtilities บรรจุอยู่ในแพ็กเกจ EJP และจะถูกใช้ในการสร้างเซิร์ฟเล็ตที่จะนำเสนอในบทต่อไป
ในบทต่อไปจะมีเนื้อหาที่เพิ่มศักย
ภาพในการทำงานของเซิร์ฟเล็ตให้
เพิ่มขึ้น
โดยมีการพิจาณาข้อมูลร้องขอที่ส่
งมาจากบราวเซอร์ว่าจะสามารถอ่
านรายละเอียดที่ได้รับนอกเหนือจ
ากพารามิเตอร์ที่ได้กล่าวไว้ในบท
นี้ได้อย่างไร
นอกจากนั้นยังรวมถึงวิธีการทำให้เ
ซิร์ฟเล็ตสามารถจัดการกับข้อมูลโ
ต้ตอบซึ่งมีทั้งสถานะรหัสโต้ตออบ
และข้อมูลโต้ตอบส่วนหัว
ซึ่งจะทำให้เซิร์ฟเล็ตสามารถทำงา
นได้อย่างหลากหลายขึ้นกว่าที่ได้เ
รียนรู้ในบทนี้

More Related Content

What's hot

ความรู้เบื้องต้นเกี่ยวกับภาษาPhp
ความรู้เบื้องต้นเกี่ยวกับภาษาPhpความรู้เบื้องต้นเกี่ยวกับภาษาPhp
ความรู้เบื้องต้นเกี่ยวกับภาษาPhpKwanJai Cherubstar
 
Book sru
Book sruBook sru
Book sruphochai
 
บทที่ 5 พื้นฐานภาษาซี
บทที่ 5 พื้นฐานภาษาซีบทที่ 5 พื้นฐานภาษาซี
บทที่ 5 พื้นฐานภาษาซีNattawut Kathaisong
 
คู่มือJavascript and Python
คู่มือJavascript and Pythonคู่มือJavascript and Python
คู่มือJavascript and PythonBongkotporn Jachernram
 
การเขียนโปรแกรมด้วย Visual basic
การเขียนโปรแกรมด้วย Visual basicการเขียนโปรแกรมด้วย Visual basic
การเขียนโปรแกรมด้วย Visual basicSarun Kitcharoen
 
พื้นฐานการเขียนโปรแกรม Visual Basic 6.0
พื้นฐานการเขียนโปรแกรมVisual Basic 6.0พื้นฐานการเขียนโปรแกรมVisual Basic 6.0
พื้นฐานการเขียนโปรแกรม Visual Basic 6.0Bass Bass
 
บทที่ 4 การเขียนโปรแกรมภาษาแอสแซมบลี
บทที่ 4 การเขียนโปรแกรมภาษาแอสแซมบลีบทที่ 4 การเขียนโปรแกรมภาษาแอสแซมบลี
บทที่ 4 การเขียนโปรแกรมภาษาแอสแซมบลีNattawut Kathaisong
 
Introduction to Java Programming
Introduction to Java ProgrammingIntroduction to Java Programming
Introduction to Java ProgrammingBhusit Net
 
การเขียนโปรแกรมบนเว็บ
การเขียนโปรแกรมบนเว็บการเขียนโปรแกรมบนเว็บ
การเขียนโปรแกรมบนเว็บKhon Kaen University
 
Phptraining
PhptrainingPhptraining
Phptrainingphochai
 
คลาสและการเขียนโปรแกรมเชิงวัตถุเบื้องต้น 1
คลาสและการเขียนโปรแกรมเชิงวัตถุเบื้องต้น 1คลาสและการเขียนโปรแกรมเชิงวัตถุเบื้องต้น 1
คลาสและการเขียนโปรแกรมเชิงวัตถุเบื้องต้น 1Ja Phenpitcha
 

What's hot (20)

Php beginner
Php beginnerPhp beginner
Php beginner
 
lesson2 JSP
lesson2 JSPlesson2 JSP
lesson2 JSP
 
Lab Computer Programming 1
Lab Computer Programming 1Lab Computer Programming 1
Lab Computer Programming 1
 
ภาษา Jsp
ภาษา Jspภาษา Jsp
ภาษา Jsp
 
ความรู้เบื้องต้นเกี่ยวกับภาษาPhp
ความรู้เบื้องต้นเกี่ยวกับภาษาPhpความรู้เบื้องต้นเกี่ยวกับภาษาPhp
ความรู้เบื้องต้นเกี่ยวกับภาษาPhp
 
Book sru
Book sruBook sru
Book sru
 
Php
PhpPhp
Php
 
บทที่ 5 พื้นฐานภาษาซี
บทที่ 5 พื้นฐานภาษาซีบทที่ 5 พื้นฐานภาษาซี
บทที่ 5 พื้นฐานภาษาซี
 
คู่มือJavascript and Python
คู่มือJavascript and Pythonคู่มือJavascript and Python
คู่มือJavascript and Python
 
การเขียนโปรแกรมด้วย Visual basic
การเขียนโปรแกรมด้วย Visual basicการเขียนโปรแกรมด้วย Visual basic
การเขียนโปรแกรมด้วย Visual basic
 
พื้นฐานการเขียนโปรแกรม Visual Basic 6.0
พื้นฐานการเขียนโปรแกรมVisual Basic 6.0พื้นฐานการเขียนโปรแกรมVisual Basic 6.0
พื้นฐานการเขียนโปรแกรม Visual Basic 6.0
 
Web browser คืออะไร
Web browser คืออะไรWeb browser คืออะไร
Web browser คืออะไร
 
Php training
Php trainingPhp training
Php training
 
บทที่ 4 การเขียนโปรแกรมภาษาแอสแซมบลี
บทที่ 4 การเขียนโปรแกรมภาษาแอสแซมบลีบทที่ 4 การเขียนโปรแกรมภาษาแอสแซมบลี
บทที่ 4 การเขียนโปรแกรมภาษาแอสแซมบลี
 
lesson5 JSP
lesson5 JSPlesson5 JSP
lesson5 JSP
 
Introduction to Java Programming
Introduction to Java ProgrammingIntroduction to Java Programming
Introduction to Java Programming
 
การเขียนโปรแกรมบนเว็บ
การเขียนโปรแกรมบนเว็บการเขียนโปรแกรมบนเว็บ
การเขียนโปรแกรมบนเว็บ
 
Unit6
Unit6Unit6
Unit6
 
Phptraining
PhptrainingPhptraining
Phptraining
 
คลาสและการเขียนโปรแกรมเชิงวัตถุเบื้องต้น 1
คลาสและการเขียนโปรแกรมเชิงวัตถุเบื้องต้น 1คลาสและการเขียนโปรแกรมเชิงวัตถุเบื้องต้น 1
คลาสและการเขียนโปรแกรมเชิงวัตถุเบื้องต้น 1
 

Similar to Javacentrix com chap05-0

พื้นฐานภาษาจาวา
พื้นฐานภาษาจาวาพื้นฐานภาษาจาวา
พื้นฐานภาษาจาวาAeew Autaporn
 
การพัฒนาโปรแกรม วิชญา
การพัฒนาโปรแกรม วิชญาการพัฒนาโปรแกรม วิชญา
การพัฒนาโปรแกรม วิชญาwinewic199
 
Phptraining
PhptrainingPhptraining
Phptrainingphochai
 
การพัฒนาโปรแกรม วิชญา เลขที่ 26.2
การพัฒนาโปรแกรม วิชญา เลขที่ 26.2การพัฒนาโปรแกรม วิชญา เลขที่ 26.2
การพัฒนาโปรแกรม วิชญา เลขที่ 26.2winewic199
 
Java Programming [1/12] : Introduction
Java Programming [1/12] : IntroductionJava Programming [1/12] : Introduction
Java Programming [1/12] : IntroductionIMC Institute
 
Java Programming [10/12]: Java Applet
Java Programming [10/12]: Java AppletJava Programming [10/12]: Java Applet
Java Programming [10/12]: Java AppletIMC Institute
 
Unit 2 Java Programming
Unit 2 Java ProgrammingUnit 2 Java Programming
Unit 2 Java ProgrammingIrinApat
 
การพัฒนาโปรแกรม วิชญา เลขที่ 26.2
การพัฒนาโปรแกรม วิชญา เลขที่ 26.2การพัฒนาโปรแกรม วิชญา เลขที่ 26.2
การพัฒนาโปรแกรม วิชญา เลขที่ 26.2winewic199
 
พื้นฐานภาษาจาวา
พื้นฐานภาษาจาวาพื้นฐานภาษาจาวา
พื้นฐานภาษาจาวาSarocha Makranit
 
Java Programming [12/12] : Thread
Java Programming [12/12] : ThreadJava Programming [12/12] : Thread
Java Programming [12/12] : ThreadIMC Institute
 
ความรู้เบื้องต้นภาษาจาวา
ความรู้เบื้องต้นภาษาจาวาความรู้เบื้องต้นภาษาจาวา
ความรู้เบื้องต้นภาษาจาวาThanachart Numnonda
 
Javacentrix com chap04-0
Javacentrix com chap04-0Javacentrix com chap04-0
Javacentrix com chap04-0Theeravaj Tum
 

Similar to Javacentrix com chap05-0 (20)

พื้นฐานภาษาจาวา
พื้นฐานภาษาจาวาพื้นฐานภาษาจาวา
พื้นฐานภาษาจาวา
 
การพัฒนาโปรแกรม วิชญา
การพัฒนาโปรแกรม วิชญาการพัฒนาโปรแกรม วิชญา
การพัฒนาโปรแกรม วิชญา
 
Phptraining
PhptrainingPhptraining
Phptraining
 
การพัฒนาโปรแกรม วิชญา เลขที่ 26.2
การพัฒนาโปรแกรม วิชญา เลขที่ 26.2การพัฒนาโปรแกรม วิชญา เลขที่ 26.2
การพัฒนาโปรแกรม วิชญา เลขที่ 26.2
 
lesson2 JSP
lesson2 JSPlesson2 JSP
lesson2 JSP
 
joomla-2-5-install-appserv
joomla-2-5-install-appservjoomla-2-5-install-appserv
joomla-2-5-install-appserv
 
Java Programming [1/12] : Introduction
Java Programming [1/12] : IntroductionJava Programming [1/12] : Introduction
Java Programming [1/12] : Introduction
 
Java Programming [10/12]: Java Applet
Java Programming [10/12]: Java AppletJava Programming [10/12]: Java Applet
Java Programming [10/12]: Java Applet
 
Doc1
Doc1Doc1
Doc1
 
Unit 2 Java Programming
Unit 2 Java ProgrammingUnit 2 Java Programming
Unit 2 Java Programming
 
Computer Programming 1
Computer Programming 1Computer Programming 1
Computer Programming 1
 
Java 7&12 6 2
Java 7&12 6 2Java 7&12 6 2
Java 7&12 6 2
 
Wordpress 3.5 -install-appserv
Wordpress 3.5 -install-appservWordpress 3.5 -install-appserv
Wordpress 3.5 -install-appserv
 
Software
SoftwareSoftware
Software
 
การพัฒนาโปรแกรม วิชญา เลขที่ 26.2
การพัฒนาโปรแกรม วิชญา เลขที่ 26.2การพัฒนาโปรแกรม วิชญา เลขที่ 26.2
การพัฒนาโปรแกรม วิชญา เลขที่ 26.2
 
พื้นฐานภาษาจาวา
พื้นฐานภาษาจาวาพื้นฐานภาษาจาวา
พื้นฐานภาษาจาวา
 
Java Programming [12/12] : Thread
Java Programming [12/12] : ThreadJava Programming [12/12] : Thread
Java Programming [12/12] : Thread
 
ความรู้เบื้องต้นภาษาจาวา
ความรู้เบื้องต้นภาษาจาวาความรู้เบื้องต้นภาษาจาวา
ความรู้เบื้องต้นภาษาจาวา
 
Javacentrix com chap04-0
Javacentrix com chap04-0Javacentrix com chap04-0
Javacentrix com chap04-0
 
โครงงาน
โครงงานโครงงาน
โครงงาน
 

More from Theeravaj Tum

Javacentrix com chap11-2
Javacentrix com chap11-2Javacentrix com chap11-2
Javacentrix com chap11-2Theeravaj Tum
 
Javacentrix com chap11-1
Javacentrix com chap11-1Javacentrix com chap11-1
Javacentrix com chap11-1Theeravaj Tum
 
Javacentrix com chap10-0
Javacentrix com chap10-0Javacentrix com chap10-0
Javacentrix com chap10-0Theeravaj Tum
 
Javacentrix com chap09-0
Javacentrix com chap09-0Javacentrix com chap09-0
Javacentrix com chap09-0Theeravaj Tum
 
Javacentrix com chap07-0
Javacentrix com chap07-0Javacentrix com chap07-0
Javacentrix com chap07-0Theeravaj Tum
 
Javacentrix com chap06-0
Javacentrix com chap06-0Javacentrix com chap06-0
Javacentrix com chap06-0Theeravaj Tum
 
Javacentrix com chap03-0
Javacentrix com chap03-0Javacentrix com chap03-0
Javacentrix com chap03-0Theeravaj Tum
 
Javacentrix com chap02-0
Javacentrix com chap02-0Javacentrix com chap02-0
Javacentrix com chap02-0Theeravaj Tum
 
Javacentrix com chap01-0
Javacentrix com chap01-0Javacentrix com chap01-0
Javacentrix com chap01-0Theeravaj Tum
 
บทที่ 13 การดักจับเ
บทที่ 13 การดักจับเบทที่ 13 การดักจับเ
บทที่ 13 การดักจับเTheeravaj Tum
 
บทที่ 12 กราฟฟิก
บทที่ 12 กราฟฟิกบทที่ 12 กราฟฟิก
บทที่ 12 กราฟฟิกTheeravaj Tum
 
บทที่ 11 การดักจับข
บทที่ 11 การดักจับขบทที่ 11 การดักจับข
บทที่ 11 การดักจับขTheeravaj Tum
 
บทที่ 10 ตัวแปรสตริ
บทที่ 10 ตัวแปรสตริบทที่ 10 ตัวแปรสตริ
บทที่ 10 ตัวแปรสตริTheeravaj Tum
 
บทที่ 9 การพ้องรูป
บทที่ 9 การพ้องรูปบทที่ 9 การพ้องรูป
บทที่ 9 การพ้องรูปTheeravaj Tum
 
บทที่ 8 คุณสมบัติก
บทที่ 8 คุณสมบัติกบทที่ 8 คุณสมบัติก
บทที่ 8 คุณสมบัติกTheeravaj Tum
 
บทที่ 7 แพ็คเกจ
บทที่ 7 แพ็คเกจบทที่ 7 แพ็คเกจ
บทที่ 7 แพ็คเกจTheeravaj Tum
 
บทที่ 6 อาร์เรย์
บทที่ 6 อาร์เรย์บทที่ 6 อาร์เรย์
บทที่ 6 อาร์เรย์Theeravaj Tum
 
บทที่ 5 คลาส
บทที่ 5 คลาสบทที่ 5 คลาส
บทที่ 5 คลาสTheeravaj Tum
 
บทที่ 4 แอทริบิวท์
บทที่ 4 แอทริบิวท์บทที่ 4 แอทริบิวท์
บทที่ 4 แอทริบิวท์Theeravaj Tum
 
บทที่ 3 คำสั่งควบค
บทที่ 3 คำสั่งควบคบทที่ 3 คำสั่งควบค
บทที่ 3 คำสั่งควบคTheeravaj Tum
 

More from Theeravaj Tum (20)

Javacentrix com chap11-2
Javacentrix com chap11-2Javacentrix com chap11-2
Javacentrix com chap11-2
 
Javacentrix com chap11-1
Javacentrix com chap11-1Javacentrix com chap11-1
Javacentrix com chap11-1
 
Javacentrix com chap10-0
Javacentrix com chap10-0Javacentrix com chap10-0
Javacentrix com chap10-0
 
Javacentrix com chap09-0
Javacentrix com chap09-0Javacentrix com chap09-0
Javacentrix com chap09-0
 
Javacentrix com chap07-0
Javacentrix com chap07-0Javacentrix com chap07-0
Javacentrix com chap07-0
 
Javacentrix com chap06-0
Javacentrix com chap06-0Javacentrix com chap06-0
Javacentrix com chap06-0
 
Javacentrix com chap03-0
Javacentrix com chap03-0Javacentrix com chap03-0
Javacentrix com chap03-0
 
Javacentrix com chap02-0
Javacentrix com chap02-0Javacentrix com chap02-0
Javacentrix com chap02-0
 
Javacentrix com chap01-0
Javacentrix com chap01-0Javacentrix com chap01-0
Javacentrix com chap01-0
 
บทที่ 13 การดักจับเ
บทที่ 13 การดักจับเบทที่ 13 การดักจับเ
บทที่ 13 การดักจับเ
 
บทที่ 12 กราฟฟิก
บทที่ 12 กราฟฟิกบทที่ 12 กราฟฟิก
บทที่ 12 กราฟฟิก
 
บทที่ 11 การดักจับข
บทที่ 11 การดักจับขบทที่ 11 การดักจับข
บทที่ 11 การดักจับข
 
บทที่ 10 ตัวแปรสตริ
บทที่ 10 ตัวแปรสตริบทที่ 10 ตัวแปรสตริ
บทที่ 10 ตัวแปรสตริ
 
บทที่ 9 การพ้องรูป
บทที่ 9 การพ้องรูปบทที่ 9 การพ้องรูป
บทที่ 9 การพ้องรูป
 
บทที่ 8 คุณสมบัติก
บทที่ 8 คุณสมบัติกบทที่ 8 คุณสมบัติก
บทที่ 8 คุณสมบัติก
 
บทที่ 7 แพ็คเกจ
บทที่ 7 แพ็คเกจบทที่ 7 แพ็คเกจ
บทที่ 7 แพ็คเกจ
 
บทที่ 6 อาร์เรย์
บทที่ 6 อาร์เรย์บทที่ 6 อาร์เรย์
บทที่ 6 อาร์เรย์
 
บทที่ 5 คลาส
บทที่ 5 คลาสบทที่ 5 คลาส
บทที่ 5 คลาส
 
บทที่ 4 แอทริบิวท์
บทที่ 4 แอทริบิวท์บทที่ 4 แอทริบิวท์
บทที่ 4 แอทริบิวท์
 
บทที่ 3 คำสั่งควบค
บทที่ 3 คำสั่งควบคบทที่ 3 คำสั่งควบค
บทที่ 3 คำสั่งควบค
 

Javacentrix com chap05-0

  • 1. บทที่ 5 จาวาเซิร์ฟเล็ต (Java Servlet) หากผู้อ่านรู้จักกับเทคโนโลยีของจาวามาก่อน หรือเคยผ่านการเขียนโปรแกรมด้วยภาษาจาวามาก่อนแล้ว การสร้างเซิร์ฟเล็ตก็ไม่ได้ต่างอะไรกับการสร้างโปรแกรมอื่นๆของภาษาจาวา เป็นที่ทราบกันดีอยู่แล้วว่า ภาษาจาวาเป็นภาษาที่สามารถนำมาสร้างเป็นโปรแกรมที่ทำงานบนระบบคอมพิว เตอร์ทั่วไปโดยไม่ขึ้นอยู่กับแพลตฟอร์ม (Write Once, Run Anywhere) หากโปรแกรมดังกล่าวทำงานในแบบทั่วไปบนเครื่องคอมพิวเตอร์ เรียกว่าจาวาแอปพลิเคชั่น (Java Application) หากโปรแกรมดังกล่าวทำงานผ่านบนบราวเซอร์ เรียกว่าจาวาแอปเพล็ต (Java Applet) ทั้งจาวาแอปพลิเคชั่นและจาวาแอปเพล็ต ใช้หลักการเขียนและสร้างเหมือนกันต่างกันเพียงเรียกใช้ API (Application Programming Interface) ที่ต่างกัน ดังนั้นการสร้างเซิร์ฟเล็ตจึงไม่ต่างอะไรกับจาวาแอปพลิเคชั่น หรือแอปเพล็ตที่กล่าวมา โดยที่เซิร์ฟเล็ตเป็นการสร้างโปรแกรมโดยเรียกใช้ API สำหรับการทำงานบนเว็บเซิร์ฟเวอร์โดยเฉพาะ ซึ่งทำให้จาวาเซิร์ฟเล็ตมีคุณสมบัติในการทำงานที่เข้าใจโพรโตคอล HTTP นอกจากนี้แล้วภายในบทนี้ยังมีเนื้อหาอธิบายถึงการจัดสร้างเอกสารเว็บในแ บบไดนามิก (Dynamic Content) ที่เกิดจากการทำงานของเซิร์ฟเล็ต และการจัดการข้อมูลตัวอักษรภาษาไทยในการแสดงผลด้วย
  • 2. จากที่เคยได้ให้ความหมายของคำว่าเซิร์ฟเล็ตไปแล้วว่า โปรแกรมที่ทำงานเป็นเซิร์ฟเล็ตจะทำงานภายใต้ระบบคอมพิวเตอร์ที่ทำหน้าที่เป็นเว็บเซิร์ฟเวอร์ โดยจะเข้าไปสนับสนุนการทำงานในส่วนของการประมวลผลเพื่อให้ได้เนื้อข้อมูลก่อนถูกเว็บเซิร์ฟเวอร์ลำเลียงข้อมูลกลับไปให้ที่บราวเซ อร์อีกที การรับข้อมูลการร้องขอจากบราวเซอร์เกิดจากการใช้งานของผู้ใช้ ซึ่งเซิร์ฟเล็ตสามารถรับคำสั่งการร้องขอนี้ได้หลายทาง คือ - เรียกใช้เซิร์ฟเล็ตโดยตรง เมื่อผู้ใช้ระบุข้อมูล URL ที่อ้างถึงโปรแกรมเซิร์ฟเล็ตโดยตรงในช่องกรอกแอดเดรส หรืออ่านการคลิกลิงก์ข้อความหรือรูปภาพที่มีข้อมูลอ้างถึงโปรแกรมเซิร์ฟเล็ตซ่อนไว้ ภาพแสดงการอ้างถึงโปรแกรมเซิร์ฟเล็ตโดยตรง - เรียกใช้งานจากการทำงานของจาวาแอปเพล็ต โปรแกรมจาวาแอปเพล็ตอาจมีการเรียกหรืออ้างถึงแอดเดรสไปยังเซิร์ฟเล็ตบนเว็บเซิร์ฟเวอร์ เพื่อเรียกอ่านข้อมูลโดยตรง ภาพจำลองแสดงการอ้างถึงโปรแกรมเซิร์ฟเล็ตจากจาวาแอปเพล็ต - เรียกใช้งานผ่านฟอร์มของเว็บ การใช้งานเพื่อเรียกดูข้อมูลจากเว็บเซิร์ฟเวอร์ หากผู้ใช้ต้องการส่งข้อมูลไปให้กับเว็บเซิร์ฟเวอร์ มักจะกรอดข้อมูลผ่านฟอร์ม (Form) จากนั้นส่ง (Submit) ไปให้ หากการส่งนั้นอ้างถึงโปรแกรมเซิร์ฟเล็ต โปรแกรมดังกล่าวก็จะรับข้อมูลนั้นไว้ เพื่อนำไปประมวลผลอีกที ภาพจำลองแสดงการส่งข้อมูลจากฟอร์มไปยังโปรแกรมเซิร์ฟเล็ต 1. โครงสร้างเซิร์ฟเล็ต เมื่อต้องการสร้างโปรแกรมคอมพิวเตอร์ ให้มีรูปแบบการประมวลผลในแบบเซิร์ฟเล็ต เริ่มต้นผู้เขียนโปรแกรมต้องสร้างคลาสใหม่ที่สืบทอดคุณสมบัติจากคลาส HttpServlet ด้วยการใช้คีย์เวิร์ด extends และให้สร้างเมธอด doGet (หรือ doPost) ซึ่งรองรับคำสั่งร้องขอจากบราวเซอร์ เพื่อประมวลผลในเมธอด และส่งผลลัพธ์กลับคืน ลองพิจารณาตัวอย่างโครงสร้างของคลาสโครงสร้างต่อไปนี้ ซึ่งเป็นรูปแบบที่จะนำไปสร้างเป็นเซิร์ฟเล็ตในคราวต่อไป 1 import java.io.*; 2 import javax.servlet.*; 3 import javax.servlet.http.*; 4 5 public class SERVLET_CLASS extends HttpServlet { 6 public void doGet (HttpServletRequest request, HttpServletResponse response) 7 throws ServletException, IOException { 8 PrintWriter out = response.getWriter(); 9 // 10 } 11 } ตัวอย่างซอร์สโค้ดแสดงโครงสร้างของเซิร์ฟเล็ต จากโครงสร้างดังกล่าวลองมาดูรายละเอียดว่าแต่ละบรรทัดถูกใช้งานเพื่อทำหน้าที่อย่างไร ในบรรทัดที่ 1 เป็นการเรียกใช้คำสั่ง import เพื่ออิมพอร์ตกลุ่มคลาสเพื่อใช้งานในแพ็กเกจ java.io.* ที่บรรจุคลาสที่เกี่ยวกับการจัดการทางด้าน
  • 3. Input และ Output ซึ่งภายในโปรแกรมมีการเรียกใช้งานคลาส PrintWriter (บรรทัดที่ 8) ที่อยู่ในแพ็กเกจดังกล่าว เพื่อใช้งานในการจัดการรูปแบบการส่งข้อมูลกลับสู่บราวเซอร์ บรรทัดที่ 2 เป็นการอินพอร์ตกลุ่มคลาสในแพ็กเกจ javax.servlet.* เพื่อเรียกใช้งานคลาสที่เกี่ยวข้องกับการจัดการโปรแกรมรูปแบบเซิร์ฟเล็ตคือคลาสชื่อ HttpServlet และเช่นกันจะเห็นตัวอย่างการใช้งานจากบรรทัดที่ 5 ซึ่งเป็นการสืบทอดมาสร้างเป็นคลาสใหม่ด้วยคีย์เวิร์ด extends นั่นเอง สำหรับคำสั่ง import ในบรรทัดถัดมาเป็นการอินพอร์ตกลุ่มคลาสในแพ็กเกจ javax.servlet.http.* เพื่อเรียกใช้งานคลาสเกี่ยวกับการจัดการข้อมูลในโพรโตคอล HTTP ซึ่งในที่นี้คือคลาส HttpServletRequest สำหรับตรวจสอบข้อมูลร้องขอที่ส่งมาจากบราวเซอร์ และคลาส HttpServletResponse เป็นการจัดการผลลัพธ์ที่ถูกส่งไปให้บราวเซอร์ การใช้งานคลาสทั้งสองคลาสถูกจัดเป็นอาร์กิวเม็นต์ในเมธอด goGet ในบรรทัดที่ 6 จากโครงสร้างของเซิร์ฟเล็ตที่แสดงเป็นตัวอย่าง กำหนดให้ SERVLET_CLASS คือชื่อคลาสที่ต้องการให้มีการทำงานในแบบเซิร์ฟเล็ตที่ต้องการสร้างขึ้น ชื่อคลาสนี้ต่อไปเมื่อต้องการใช้งานจะเป็นชื่อที่ถูกอ้างผ่านทาง URL (หรือ Address) บนบราวเซอร์ของผู้เรียกใช้งานเมื่อต้องการสั่งให้เซิร์ฟเล็ตทำงาน ข้อแนะนำ จากโครงสร้างตัวอย่างเนื่องจากคลาสที่ใช้สร้างเซิร์ฟเล็ตสังเกตเห็นคำว่า public นำหน้าชื่อคลาส ดังนั้นชื่อไฟล์ซอร์สโค้ดควรตั้งชื่อเหมือนกับชื่อเซิร์ฟเล็ตทั้งหมดทั้งตัวเล็กหรือตัวใหญ่ เช่น หากชื่อคลาสเป็น MyServlet ฃื่อไฟล์ควรตั้งเป็น MyServlet.java เป็นต้น ในคลาสเซิร์ฟเล็ตมีเมธอดหนึ่งเมธอดคือ doGet เมธอดดังกล่าวถูกเรียกใช้งานเมื่อบราวเซอร์ส่งคำสั่งร้องขอข้อมูลด้วยคำสั่ง GET ซึ่งเป็นหนึ่งในคำสั่งร้องขอข้อมูลของโพรโตคอล HTTP ในเมธอดดังกล่าวมีอาร์กิวเมนต์สองตัวที่เกี่ยวกับการร้องขอข้อมูลโดยตรงคือ HttpServletRequest ซึ่งจะถูกอ้างถึงผ่านตัวแปร request และการโต้ตอบข้อมูล HttpServletResponse ซึ่งจะถูกอ้างถึงด้วยตัวแปร response ตามลำดับ ซึ่งอยู่ในส่วนท้ายของในบรรทัดที่ 6 ภานในเมธอด doGet มีการกำหนดรูปแบบการจัดการกับข้อมูลโต้ตอบ เมื่อเซิร์ฟเล็ตต้องการส่งข้อมูลกลับสู่บราวเซอร์ โดยมีการอ้างถึงคลาส PrintWriter เพื่อจัดการเกี่ยวกับเรื่องการกำหนดรูปแบบการส่งข้อมูลโต้ตอบ จากตัวอย่างในบรรทัดที่ 8 การจัดการด้านรูปแบบการส่งข้อมูลผ่านตัวแปรที่ชื่อ out ซึ่งได้รับอินสแตนซ์ช่องทางส่งข้อมูลกลับมาจากคำสั่ง response.getWriter() ตัวแปรอ้างถึง out สามารถเรียกใช้งานเมธอดที่เกี่ยวข้องการการจัดการข้อมูลข้อความสองเมธอดคือ print และ println คือการส่งข้อความทั่วไป และการส่งข้อความที่จบด้วยสัญลักษณ์ขึ้นบรรทัดใหม่ตามลำดับ รูปแบบการใช้งานตัวแปร out out.print("Hello"); // เมื่อต้องการส่งข้อความ Hello สู่บราวเซอร์ out.println("Hello"); // เมื่อต้องการส่งข้อความ Hello พร้อมขึ้นบรรทัดใหม่สู่บราวเซอร์ ข้อแนะนำ จากโครงสร้างเซิร์ฟเล็ตดังกล่าว มีตัวแปรที่เกิดขึ้นคือ request, response, out ซึ่งสามารถตั้งด้วยชื่ออะไรก็ได้นอกเหนือจากนี้ แต่อย่างไรก็ตามชื่อทั้งสามชื่อเป็นชื่อที่จำจำได้ง่ายและจะถูกตั้งเป็นชื่อที่สอดคล้องที่จะใช้ในการทำงานของ JSP ที่จะกล่าวถึงในเนื้อหาที่เกี่ยวข้องกับ JSP 2. เซิร์ฟเล็ตกับการตอบสนองข้อมูลตัวอักษร การสร้างเซิร์ฟเล็ตเพื่อตอบสนองการทำงานหรือเพื่อส่งข้อมูลกลับไปหาบราวเซอร์ ด้วยวิธีการพื้นฐานที่สุดคือการส่งข้อมูลที่ประกอบจากตัวอักษรออกไป
  • 4. และต่อไปนี้เป็นตัวอย่างซอร์สโค้ดที่จะทำการสร้างเซิร์ฟเล็ตเพื่อจุดประสงค์ในการส่งข้อมูลตัวอักษรกลับไปหาบราวเซอร์ โดยข้อมูลดังกล่าวคือคำว่า ยินดีต้อนรับสู่การใช้งานเซิร์ฟเล็ต Welcome! to Java Servlet และตัวอย่างซอร์สโค้ดต่อไปนี้คือ ServletHelloWorld.java เป็นตัวอย่างการทำงานเพื่อส่งข้อมูลตัวอักษรตามความต้องการข้างต้น ให้พิจารณาที่ละบรรทัด 1 import java.io.*; 2 import javax.servlet.*; 3 import javax.servlet.http.*; 4 5 public class ServletHelloWorld extends HttpServlet { 6 public void doGet (HttpServletRequest request, HttpServletResponse response) 7 throws ServletException, IOException { 8 PrintWriter out = response.getWriter(); 9 out.println(" "); // 10 out.print("Welcome! to Java Servlet"); // 11 } 12 } ตัวอย่างเซิร์ฟเล็ตส่งข้อมูลตัวอักษร จากตัวอย่างซอรสโค้ดในบรรทัดที่ 9 มีการใช้งาน out โดยเรียกเมธอด println เพื่อพิมพ์ข้อความโดยมีการขึ้นบรรทัดใหม่หลังจากสิ้นสุดข้อความ ส่วนบรรทัดที่ 10 เป็นอีกข้อความหนึ่งซึ่งถูกส่งไปหาบราวเซอร์แต่ไม่ได้ส่งรหัสขึ้นบรรทัดใหม่กลับไปด้วย เมื่อคอมไพล์ซอร์สโค้ดดังกล่าวแล้วจะได้ไฟล์ที่ชื่อ ServletHelloWorld.class จากบทที่แล้วที่กล่าวถึงสภาพแวดล้อมที่โปรแกรม Apache Tomcat เป็นเว็บเซิร์ฟเวอร์ที่สนับการทำงานของเซิร์ฟเล็ตถูกติดตั้งไว้ที่ ไดเร็กทรอรี่ที่ติดตั้งโปรแกรม Apache Tomcat C:Program FilesApache Tomcat 4.0 และมีการสร้างไดเร็กทรอรี่สำหรับการทำงานในการทดลองไว้ที่ไดเร็กทรอรี่ ejp ต่อจากไดเร็กทรอรี่ติดตั้งคือ ไดเร็กทรอรี่ทำงาน ejp ภายใน Apache Tomcat C:Program FilesApache Tomcat 4.0webappsejp ในการติดตั้งเซิร์ฟเล็ตที่ได้รับการคอมไพล์แล้วจากตัวอย่างนี้คือไฟล์ ServletHelloWorld.class ให้ทำการสำเนาไฟล์ดังกล่าวไปเก็บไว้ในไดเร็กทรอรี่ WEB-INFclasses ในไดเร็กทรอรี่ทำงาน ejp ดังนี้ ไดเร็กทรอรี่ติดตั้งเซิร์ฟเล็ตของ ejp C:Program FilesApache Tomcat 4.0webappsejpWEB-INFclassesServletHelloWorld.class หลักจากนั้นเมื่อต้องการทดสอบการใช้งาน ให้เปิดโปรแกรมบราวเซอร์ใดๆ เช่น Internet Explorer หรือ Netscape Navigator ในช่องแอดเดรสให้อ้างถึง URL เพื่อเรียกใช้งานเซิร์ฟเล็ตคือ URL ในการเรียกใช้งานเซิร์ฟเล็ต http://localhost:8080/ejp/servlet/ServletHelloWorld
  • 5. จาก URL อ้างถึงเซิร์ฟเล็ตดังกล่าวจะไม่เหมือนกับชื่อไดเร็กทรอรี่ที่ติดตั้งภายใน เป็นการอ้างถึงตามข้อกำหนดของเซิร์ฟเล็ตบนโปรแกรม Apache Tomcat เมื่อกล่าวโดยสรุปจึงเป็นดังนี้ http คือชื่อโพรโตคอลในการใช้งาน localhost คือชื่อปลายทางในที่นี้คือเครื่องตัวเอง สามารถเปลี่ยนเป็น 127.0.0.1 ได้ 8080 คือหมายเลขพอร์ตในการทำงานของเว็บเซิร์ฟเวอร์ ejp คือชื่อเว็บแอปพลิเคชั่นที่ติดตั้งพื่อทำงานบนเว็บเซิร์ฟเวอร์ servlet คือการอ้างเพื่อใช้งานโปรแกรมเซิร์ฟเล็ต ServletHelloWorld คือชื่อเซิร์ฟเล็ตที่เป็นชื่อไฟล์ ServletHelloWorld.class ซึ่งติดตั้งอยู่ ใน WEB-INFclasses ของเว็บแอปพลิเคชั่นอีกที เมื่อเรียกใช้งาน ServletHelloWorld ที่สร้างจากตัวอย่างจะให้ผลลัพธ์จากการทำงานดังรูปต่อไปนี้ รูปแสดงผลลัพธ์จากเซิร์ฟเล็ต ServletHelloWorld จากตัวอย่างผู้อ่านอาจสงสัยว่าทำไมส่วนที่เป็นภาษาไทย จึงกลายเป็นตัวอักษร ? แทน ซึ่งจริงๆแล้วส่วนของข้อมูลดังกล่าวเป็นข้อมูลภาษาไทยครับ แต่เนื่องจากเกิดปัญหากับระบบตัวเลขแทนรหัสตัวอักษรภาษาไทยของรหัส Unicode ดังนั้นการทำให้เกิดอักษรภาษาไทย เซิร์ฟเล็ตจะต้องส่งข้อมูลบอกมาด้วยว่าเป็นข้อมูลในรหัสของเขตข้อมูลตัวอักษรใด ซึ่งดูได้จากหัวข้อถัดไป ข้อความจำ การส่งข้อมูลกลับสู่บราวเซอร์ด้วยเมธอด println จะไม่มีผลถึงการขึ้นบรรทัดใหม่ในการแสดงผลสู่ผู้ใช้โดยตรง ซึ่งเป็นเพียงการส่งข้อมูลที่มีการแยกบรรทัดกันเท่านั้น หากต้องการแสดงข้อมูลขึ้นบรรทัดใหม่บนบราวเซอร์ให้ใช้คำสั่ง HTML คือแท็ก BR หรือแท็ก P 3. เซิร์ฟเล็ตกับการโต้ตอบข้อมูล HTML จากหัวข้อที่ผ่านมา ผู้เขียนได้กล่าวถึงเรื่องการสร้างเซิร์ฟเล็ตที่สามารถส่งข้อความไปสู่บราวเซอร์ เพื่อให้บราวเซอร์นำข้อมูลดังกล่าวไปแสดงผลลัพธ์บนพื้นที่ของบราวเซอร์ การนำเสนอรูปแบบดังกล่าวถูกเรียกว่า Text Plain ซึ่งมีรูปแบบตัวอักษรหรือฟอนต์ใดฟอนต์หนึ่ง ในสีใดสีหนึ่งเท่านั้น แต่หากต้องการปรับการนำเสนอให้มีรูปแบบที่สวยงามขึ้น
  • 6. ซึ่งเรียกว่า Rich Text ที่สามารถแสดงตัวอักษรรูปแบบต่างๆ ในสีที่แตกต่างกันสามารถทำให้โดยการใช้ภาษา HTML ที่เคยกล่าวมาแล้วในบทก่อนหน้านี้ มาควบคุมตัวอักษรหรือเนื้อความ ตามตำแหน่งที่ต้องการปรับการนำเสนอ และแน่นอนว่าภาษา HTML ก็เป็นคำสั่งที่อยู่ในรูปของตัวอักษรด้วยเช่นกัน และหากเซิร์ฟเล็ตมีการส่งคำสั่ง HTML รวมกับข้อมูลใดๆกลับสู่บราวเซอร์ เมื่อบราวเซอร์ได้รับข้อมูลดังกล่าวกลับมา ด้วยความสามารถที่เข้าใจภาษา HTML ที่เป็นคุณสมบัติพื้นฐานของบราวเซอร์ใดๆ ก็จะตีความคำสั่งที่บรรจุร่วมกับข้อความ และมีการปรับรูปแบบการแสดงผลสู่ผู้ใช้ตามคำสั่ง HTML โดยเรียกข้อมูลตัวอักษรที่รวมอยู่กับคำสั่ง HTML ว่าเอกสาร HTML ขั้นตอนการสร้างเซิร์ฟเล็ตเพื่อส่งข้อมูลที่เป็นเอกสาร HTML มีขั้นตอนตามข้อกำหนดดังนี้ ขั้นตอนที่ 1 ให้มีการกำหนดข้อมูลโต้ตอบส่วนหัว (Response Header) เพื่อระบุชนิดเอกสารว่าเป็นเอกสาร HTML นั่นคือข้อมูลในส่วน Content Type: text/html โดยผ่านเมธอด setContentType ของคลาส HttpServletResponse การกำหนดดังกล่าวเมื่อบราวเซอร์จะได้รับข้อมูลกร่อนที่เอกสาร HTML จะส่งกลับมา และพิจารณาว่าข้อมูลดังกล่าวเป็น text ในแบบ html response.setContentType("text/html ; charset=windows-874"); นอกจากนั้นแล้วหากพิจารณาข้อความต่อท้ายจากเมธอดด้านบนมีคำว่า charset=windows-874 เพื่อบอกให้บราวเซอร์ทราบเพิ่มเติมว่าการแสดงเอกสารที่จะตามมาให้ใช้ตัวอักษรในรหัส Unicode ในกลุ่มของ Windows-874 นั่นก็คือกลุ่มทีมีตัวอักษรภาษาไทยอยู่ด้วยนั่นเอง การกำหนดดังกล่าวจะทำให้สามารถเป็นตัวอักษรภาษาไทยจากการใช้งานของผู้ใช้ ข้อแนะนำ การเรียกใช้เมธอดส่งข้อมูลนี้ควรทำก่อนที่จะส่งเอกสาร HTML เนื่องจากลำดับการส่งข้อมูลโต้ตอบข้อมูลส่วนหัวต้องส่งก่อนข้อมูลเนื้อความ ขั้นตอนที่ 2 ให้มีการส่งข้อมูลบ่งบอกชนิดเอกสาร HTML ว่าเป็นคำสั่ง HTML ถูกกำหนดจากมาตรฐานอย่างไรซึ่งเป็นข้อกำหนดของเอกสาร HTML ซึ่งเป็นข้อมูลที่จะบรรจุไว้ในส่วนต้นของเอกสาร HTML ข้อมูลบ่งบอกชนิดเอกสารที่จะใช้ในหนังสือเล่มนี้คือเอกสารที่สร้างจาก HTML เวอร์ชัน 4.0 โดยมีข้อมูลบ่งบอกชนิดเอกสาร HTML ดังนี้คือ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> ข้อแนะนำ สำหรับขั้นตอนการกำหนดข้อมูลบ่งบอกชนิดเอกสาร HTML นี้บางครั้งไม่จำเป็นต้องส่งก็ได้ เนื่องจากในปัจจุบันบราวเซอร์ส่วนใหญ่เข้าใจและตีความเอกสาร HTML ให้โดยอัตโนมัติ แต่เพื่อให้เป็นมาตรฐานตรงตามข้อกำหนดของเอกสาร HTML ผู้เขียนขอแนะนำให้ส่งข้อมูลเกริ่นนำนี้ทุกครั้งที่มีการส่งเอกสาร HTML ไปสู่บราวเซอร์ ข้อมูลบ่งบอกชนิดเอกสาร HTML ดังกล่าวอ้างถึงตามข้อกำหนดจากเอกสาร RFC ที่เว็บไซต์ (http://www.rfc-editor.org/) ตัวอย่างต่อไปนี้แสดงการส่งเอกสาร HTML สู่บราวเซอร์ที่บรรจุข้อความเดียวกันกับเซิร์ฟเล็ตตัวอย่างการส่งข้อมูลตัวอักษรก่อนหน้านี้ ไฟล์ในตัวอย่างคือไฟล์ HTMLDocument.java 1 import java.io.*; 2 import javax.servlet.*; 3 import javax.servlet.http.*; 4 5 public class HTMLDocument extends HttpServlet { 6 public void doGet (HttpServletRequest request, HttpServletResponse response) 7 throws ServletException, IOException { 8 // 9 response.setContentType("text/html ; charset=windows-874"); 10 PrintWriter out = response.getWriter(); 11 // HTML
  • 7. 12 out.println("<!DOCTYPE HTML PUBLIC "- //W3C//DTD HTML 4.0 Transitional//EN">"); 13 // HTML 14 out.print("<HTML>n"); 15 out.print("<HEAD><TITLE>HTML Document</TITLE></HEAD>n"); 16 out.print("<BODY>"); 17 out.print("<P> </P>"); 18 out.print("<P>Welcome! to Java Servlet</P>"); 19 out.print("</BODY>"); 20 out.print("</HTML>n"); 21 } 22 } ซอร์สโค้ดที่ใช้สร้างเซิร์ฟเล็ต HTMLDocument เพื่อส่งเอกสาร HTML กลับสู่บราวเซอร์ ข้อแนะนำ ข้อมูลบ่งบอกชนิดเอกสาร HTML ในการแสดงตัวอักษร " ซึ่งเป็นตัวอักษรในการเปิดปิดท้ายข้อความในภาษาจาวา จึงต้องใช้เครื่องหมาย วางไว้ส่วนหน้าเพื่อให้เป็นส่วนหนึ่งของข้อความ จากตัวอย่างเมื่อคอมไพล์และติดตั้งเซิร์ฟเล็ต HTMLDocument ลงในเว็บแอปพลิเคชั่น ejp และอ้างเซิร์ฟเล็ตจาก http://localhost:8080/ejp/servlet/ServletHelloWorld ในบราวเซอร์จะได้ผลลัพธ์ดังนี้ รูปแสดงผลลัพธ์จากเซิร์ฟเล็ต HTMLDocument บนพื้นที่แสดงผลของบราวเซอร์ ข้อแนะนำ ในการแสดงข้อมูลที่เป็นตัวอักษรภาษาไทย จำเป็นต้องระบุกลุ่มของตัวอักษร (Character Set) ในส่วนที่สนับสนุนภาษาไทย จากตัวอย่างคือ Windows-874 4. การอ่านข้อมูลจากพารามิเตอร์ เซิร์ฟเล็ตสามารถรับข้อมูลมาเพื่อประมวลผลได้ จากการทำงานของระบบเว็บเป็นการสื่อสารโดยการทำงานระหว่างบราวเซอร์และเว็บเซิร์ฟเวอร์ โดยบราวเซอร์รับผิดชอบในส่วนการแสดงผลและติดต่อกับผู้ใช้ในการรับข้อมูล ส่วนเว็บเซิร์ฟเวอร์ที่ติดตั้งเซิร์ฟเล็ตอยู่ก็จะรับผิดชอบในส่วนของการประมวลผลหลัก ทั้งสองส่วนต้องทำงานประสานกัน เพื่อให้ระบบเว็บเกิดเป็นบริการให้กับผู้ใช้งาน ซึ่งบริการจะเกิดขึ้นได้นั้นเราจำเป็นต้องทำความเข้าใจว่าผู้ใช้จะสามารถส่งข้อมูลไปสู่การประมวลผลที่เซิร์ฟเล็ตได้อย่างไร จากรูปแบบการทำงานของเว็บโดยทั่วไป บราวเซอร์สามารถส่งข้อมูลได้ 2 วิธีหลักๆ คือการส่งผ่าน URL และผ่านข้อมูลร้องขอส่วนหัว (Request Header) การส่งข้อมูลหรือส่งพารามิเตอร์ผ่านทาง URL ในการอ้างถึงเอกสาร HTML หรือเซิร์ฟเล็ตสามารถส่งข้อมูลพารามิเตอร์ได้ด้วยรูปแบบดังนี้ รูปแบบ http://host_name:port_number/web_app/servlet/Servlet?Param1=Value1&Param2=Value2, … เมื่อ host_name คือชื่อเครื่องที่ติดตั้งเว็บเซิร์ฟเวอร์ไว้ หากเป็นการทดสอบภายในเครื่องตนเอง ให้ใช้ localhost หรือ
  • 8. 127.0.0.1 แทนได้ port_number คือหมายเลขพอร์ตที่ผู้บริหารเว็บกำหนดไว้สำหรับการทำงาน หมายเลขทั่วไปที่ที่ใช้กับเว็บคือ 80 แต่หมายเลขทั่วไปของ Tomcat คือ 8080 สามารถเปลี่ยนแปลงได้ web_app คือชื่อส่วนการทำงานของเว็บแอปพลิเคชั่นบนเว็บเซิร์ฟเวอร์ Servlet คือชื่อโปรแกรมเซิร์ฟเล็ต Param1, Param2 คือชื่อพารามิเตอร์ Value1, Value2 คือข้อมูลที่สอดคล้องกับพารามิเตอร์แต่ละตัว สัญลักษณ์ ? สำหรับบอกเซิร์ฟเล็ตว่ามีข้อมูลพารามิเตอร์ซึ่งอยู่ด้านหลัง (วางอยู่หลังชื่อเซิร์ฟเล็ต) สัญลักษณ์ & สำหรับการแยกพารามิเตอร์แต่ละตัวออกจากกัน (ใช้กรณีมีพารามิเตอร์มากกว่า 2 ตัว) ตัวอย่าง http://localhost:8080/ejp/servlet/GetParameter?name=Rungrote&surname=Phonkam จากตัวอย่างคือการอ้างถึงเซิร์ฟเล็ตที่ชื่อ GetParameter โดยรับข้อมูลพารามิเตอร์จำนวนสองตัว ตัวแรกคือพารามิเตอร์ชื่อ name มีข้อมูล Rungrote อยู่และพารามิเตอร์ชื่อ surname มีข้อมูล Phonkam บรรจุอยู่ การส่งข้อมูลผ่านทาง URL นี้เป็นการร้องข้อข้อมูลในแบบคำสั่ง GET ในโพรโตคอล HTTP ซึ่งมีข้อจำกัดที่ข้อมูลไม่ควรมีความยากเกิน 255 ตัวนับรวมข้อมูลทั้งหมด (รวมทั้ง URL และพารามิเตอร์) และก็เป็นการเสียเวลาของผู้ใช้ที่ต้องพิมพ์ข้อมูลลงไปที่ URL โดยตรง เมื่อต้องการสร้างเซิร์ฟเล็ตที่สามารถอ่านข้อมูลพารามิเตอร์จากการเรียกใช้งานเซิร์ฟเล็ต สามารถทำได้โดยง่ายโดยการเรียกใช้งานเมธอดที่อยู่ของคลาส HttpServletRequest คือเมธอดชื่อ getParameter ดังมีรูปแบบการทำงานดังนี้ รูปแบบ public String getParameter(String parameter_name) เมื่อ Parameter_Name คือชื่อพารามิเตอร์ที่ต้องการอ่านค่า ลองพิจารณาจากตัวอย่างไฟล์ GetParameters.java ต่อไปนี้ซึ่งเป็นซอร์สโค้ดสำหรับการอ่านข้อมูลพารามิเตอร์จากการใช้งานของบราวเซอร์ โดยเรียกใช้เมธอด getParametes จากคลาส HttpServletRequest ดังนี้ 1 import java.io.*; 2 import javax.servlet.*; 3 import javax.servlet.http.*; 4 5 public class GetParameters extends HttpServlet { 6 public void doGet (HttpServletRequest request, HttpServletResponse response) 7 throws ServletException, IOException { 8 response.setContentType("text/html; charset=windows-874"); 9 PrintWriter out = response.getWriter(); 10 out.println("<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">"); 11 out.print("<HTML>n"); 12 out.print("<HEAD><TITLE> </TITLE></HEAD>n"); 13 out.print("<BODY>");
  • 9. 14 out.print("<P>Name ( ) = " + request.getParameter("name") + "</P>"); 15 out.print("<P>Surname ( ) = " + request.getParameter("surname") + 16 "</P>"); 17 out.print("</BODY>"); 18 out.print("</HTML >n"); 19 } 20 } ตัวอย่างเซิร์ฟเล็ตเพื่ออ่านข้อมูลพารามิเตอร์มีการเรียกใช้เมธอด getParameter ในบรรทัดที่ 14 และ 15 เพื่ออ่านข้อมูลจากพารามิเตอร์ที่ชื่อ name และ surname ตามลำดับ ในการอ่านข้อมูลแต่ละครั้งมีการนำข้อมูลดังกล่าวมาแสดงร่วมกับเอกาสร HTML ที่ถูกส่งไปสู่บราวเซอร์ผ่านเมธอด print ข้อแนะนำ ชื่อพารามิเตอร์ที่ใช้ใน URL หากกำหนดด้วยตัวอักษรเล็กหรือใหญ่นั่น เมื่อต้องการอ่านจากเมธอด getParameter ชื่อพารามิเตอร์ในอาร์กิวเม็นต์ควรใช้เหมือนกันทั้งตัวเล็กหรือใหญ่ เนื่องจากโปรแกรมเซิร์ฟเล็ตต้องสามารถนำไปใช้งานกับคอมพิวเตอร์ทุกระบบ มีเพียงวินโดว์เท่านั้นซึ่งตัวอักษรเล็กและใหญ่มีค่าเท่ากัน สำหรับยูนิกส์หรือลีนุ๊กซ์จำเป็นต้องอ้างให้ถูกต้องว่าตัวเล็กหรือตัวใหญ่ ดังนั้นเพื่อหลีกเลี่ยงปัญหาที่อาจจะเกิดขึ้นเซิร์ฟเล็ตจึงกำหนดให้ใช้ตัวอักษรให้เหมือนกันด้วยทั้งตัวเล็กและตัวใหญ่ หลังจากการคอมไพล์แล้วได้ไฟล์ GetParameters.class เมื่อนำไปติดตั้งตามตำแหน่งที่ถูกต้องแล้วเริ่มทดสอบด้วยการอ้างผ่าน URL ต่อไปนี้ในครั้งแรก ซึ่งเป็นการอ้างถึงเซิร์ฟเล็ตโดยไม่ส่งข้อมูลพารามิเตอร์ไปกับการร้องขอ ตัวอย่าง 1 การอ้างถึงเซิร์ฟเล็ต GetParameters โดยไม่ส่งข้อมูลพารามิเตอร์ http://localhost:8080/ejp/servlet/GetParameters รูปแสดงผลลัพธ์จากการทำงานของเซิร์ฟเล็ต GetParameters โดยไม่ป้อนพารามิเตอร์เมื่อใช้ผ่าน URL จากรูปเป็นตัวอย่างของผลลัพธ์จากเซิร์ฟเล็ต GetParameters แต่เนื่องจาก URL ที่เรียกใช้เซิร์ฟเล็ตดังกล่าวไม่ได้ส่งพารามิเตอร์ไปพร้อมกับ URL ดังนั้นผลลัพธ์ที่ได้จึงปรากฏข้อความ null ขึ้นมาต่อท้ายข้อความในตำแหน่งที่มีการอ้างถึงเมธอด getParameter เนื่องจากพารามิเตอร์ที่อ่านได้จากเซิร์ฟเล็ตไม่ปรากฏค่าใดๆ การทดสอบครั้งต่อไปมีการอ้างถึงเซิร์ฟเล็ตแต่กำหนดพารามิเตอร์ที่มีข้อมูลเป็นภาษาอังกฤษดังนี้ ตัวอย่าง 2 การอ้างถึงเซิร์ฟเล็ต GetParameters พร้อมพารามิเตอร์ http://localhost:8080/ejp/servlet/GetParameters?name=Rungrote&surname=Phonkam
  • 10. รูปแสดงผลลัพธ์จากการทำงานของเซิร์ฟเล็ต GetParameters โดยป้อนพารามิเตอร์เมื่อใช้ผ่าน URL แต่หากเมื่อมีการเรียกใช้เซิร์ฟเล็ตผ่าน URL โดยมีการส่งข้อมูลพารามิเตอร์ไปด้วย ซึ่งเซิร์ฟเล็ตจะสามารถอ่านข้อมูลพารามิเตอร์ได้จากชื่อพารามิเตอร์ และจากทำงานของเซิร์ฟเล็ต GetParameters ทำให้ผลลัพธ์ที่ได้แสดงออกมาดังที่เห็นได้จากรูปด้านบน คือพารามิเตอร์ตัวแรกชื่อ name ปรากฏข้อความ Rungrote ส่วนพารามิเตอร์ตัวที่สองชื่อ surname ปรากฏข้อความ Phonkam ที่นี้ลองมาทดสอบในครั้งต่อไปด้วยข้อมูลภาษาไทยกันดูบ้าง การอ่านข้อมูลพารามิเตอร์ภาษาไทย ในตัวอย่างการทดสอบครั้งต่อไปเป็นการเรียกใช้งานพารามิเตอร์ที่มีการส่งข้อมูลพารามิเตอร์ที่เป็นตัวอักษรภาษาไทย ไปพร้อมกับข้อมูลพารามิเตอร์ ซึ่งสังเกตได้จากการอ้างถึงด้วย URL ดังต่อไปนี้ ตัวอย่าง 3 การอ้างถึงเซิร์ฟเล็ต GetParameters พร้อมข้อมูลพารามิเตอร์ภาษาไทย http://localhost:8080/ejp/servlet/GetParameters?name=รุ่งโรจน์&surname=โพนคำ จาก URL ข้างต้น ทำให้ได้ผลลัพธ์ในพื้นที่แสดงผลของบราวเซอร์ดังนี้ คือ หากสังเกตดูให้ดีจากรูปจะเห็นว่าข้อมูลพารามิเตอร์ที่ได้ไม่แสดงตัวอักษรภาษาไทยที่ส่งไป แต่กลับเป็นตัวอักษร ???? ที่เคยพบในตัวอย่างของการเรียกใช้งานเซิร์ฟเล็ต ServletHelloWorld ผู้อ่านคงเกิดอาการสงสัยแล้วซิว่าเกิดอะไรขึ้นกับตัวอักษรภาษาไทย เซิร์ฟเล็ตสนับสนุนการทำงานภาษาไทยหรือไม่ ลองมาดูเหตุผลกันก่อนที่จะสรุปผลนะครับ จากตัวอย่างซอร์สโค้ด GetParameters มีคำสั่งในการกำหนดค่า charset=windows-874 แล้วซึ่งใช้บอกบราวเซอร์ให้ใช้ตัวอักษรในกลุ่มภาษาไทยในการแสดงผล แต่เนื่องจากข้อมูล URL ที่ป้อนจากบราวเซอร์เพื่อส่งไปให้เว็บเซิร์ฟเวอร์ ตามรูปแบบการส่งข้อมูลซึ่งอาศัยการส่งแบบกลุ่มตัวอักษร UTF-8 ซึ่งเป็นการแทนตัวอักษรแต่ละตัวด้วยข้อมูลขนาด 8 บิต และการส่งข้อมูลลักษณะเช่นนี้หากเป็นภาษาไทยก็คือการนำเอารหัสตัวอักษรที่ใช้ในรหัส ASCII มาใช้งาน ซึ่งเริ่มต้นตั้งแต่ค่า A1 ถึง FB (ฐานสิบคือ 161 ถึง 251) คือ 'ก' เป็นต้นไป ในขณะที่ระบบปฏิบัติการคอมพิวเตอร์ในปัจจุบันสนับสนุนการเก็บข้อมูลในรูปแบบ Unicode และภาษาไทยของรหัส Unicode ก็ไม่ได้ใช้รหัสเดียวกันกับที่ใช้ใน ASCII ซึ่งภาษาไทยที่ใช้ใน Unicode ตามกลุ่ม Windows-
  • 11. 874 มีค่าอยู่ระหว่าง E01 ถึง E5B ลองพิจารณาตารางการแสดงข้อมูลตัวอักษรภาษาไทยเปรียบเทียบกันระหว่าง ASCII และ Windows- 874 รูปแสดงการแทนรหัส ASCII (ฐานสิบหก) ในช่วงอักษรภาษาไทย รูปแสดงการแทนรหัส Unicode (ฐานสิบหก) ในช่วงอักษรภาษาไทย ตามข้อกำหนด Windows-874
  • 12. ข้อแนะนำ รายละเอียดของข้อมูล Unicode ศึกษาเพิ่มเติมได้จาก www.Unicode.org ทางแก้ไขปัญหานี้คือการสร้างส่วนการทำงานที่สามารถสลับกันไปมาระหว่างข้อมูล ASCII และข้อมูล Unicode ให้ได้ ดังนั้นจึงสร้างคลาสที่มีเมธอดสนับสนุนในเรื่องตัวอักษรภาษาไทย ดังตัวอย่างต่อไปนี้ในไฟล์ ThaiUtilities.java 1 package EJP; 2 3 public class ThaiUtilities { 4 public static String Unicode2ASCII(String unicode) { // Unicode ASCII 5 if (Unicode==null) 6 return null; 7 StringBuffer ascii = new StringBuffer(unicode); // 8 int code; 9 for(int i =0; i < unicode.length(); i++) { // 10 code = (int)unicode.charAt(i); // 11 if ((0xE01<=code) && (code <=0xE5B )) // Unicode 12 ascii.setCharAt( i, (char)(code – 0xD60)); // ASCII 13 } 14 return ascii.toString(); // String 15 } 16 17 public static String ASCII2Unicode(String ascii) { 18 if (ascii==null) 19 return null; 20 StringBuffer unicode = new StringBuffer(ascii); 21 int code; 22 for(int i =0; i < ascii.length(); i++) { 23 code = (int)ascii.charAt(i); 24 if ((0xA1 <= code) && (code <= 0xFB)) // ASCII 25 unicode.setCharAt( i, (char)(code + 0xD60)); // Unicode 26 } 27 return unicode.toString(); // String 28 } 29 } ซอร์สโค้ดในคลาส ThaiUtilities มีการสร้างเมธอด 2 เมธอด โดยเมธอดแรกชื่อ Unicode2ASCII ที่ใช้สำหรับแปลงกลุ่มตัวอักษรภาษาไทยจากรหัส ASCII ไปเป็น Unicode กลุ่ม Windows-874 ในขณะที่เมธอดที่สองชื่อ ASCII2Unicode ใช้สำหรับแปลงกลุ่มตัวอักษรภาษาไทยจากรหัส Unicode ไปเป็น ASCII และจากซอร์สโค้ดบรรทัดที่ 1 ป็นการสร้างคลาสในแพ็กเกจที่ชื่อ EJP (มาจาก Enterprise Java Programming) ดังนั้นในการคอมไพล์จึงต้องระบุออปชั่น –d เอาไว้ด้วย ซึ่งมีรูปแบบดังนี้ คำสั่งคอมไพล์ซอร์สโค้ด ThaiUtilities.java ในแบบแพ็กเกจ javac.exe -d . ThaiUtilities.java หลังจากคอมไพล์เรียบร้อยแล้ว ในขั้นตอนต่อไปเป็นการปรับปรุงคลาส GetParameter ไปเป็นคลาสใหม่คือ GetThaiParameter เพื่อสนับสนุนการหากมีการเรียกใช้งานเซิร์ฟเล็ตแล้วมีค่าพารามิเตอร์ที่ตัวอักษรภาษาไทย ดังไฟล์ GetThaiParametes.java ดังนี้ 1 import java.io.*; 2 import javax.servlet.*; 3 import javax.servlet.http.*; 4 import EJP.ThaiUtilities;
  • 13. 5 6 public class GetThaiParameters extends HttpServlet { 7 public void doGet (HttpServletRequest request, HttpServletResponse response) 8 throws ServletException, IOException { 9 response.setContentType("text/html; charset=windows-874"); 10 PrintWriter out = response.getWriter(); 11 out.println("<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">"); 12 out.print("<HTML>n"); 13 out.print("<HEAD><TITLE> </TITLE></HEAD>n"); 14 out.print("<BODY>"); 15 String paramName = ThaiUtilities.ASCII2Unicode(request.getParameter("name")); 16 out.print("<P>Name ( ) = " + paramName + "</P>"); 17 String paramSurname = ThaiUtilities.ASCII2Unicode(request.getParameter("surname")); 18 out.print("<P>Surname ( ) = " + paramSurname + "</P>"); 19 out.print("</BODY>"); 20 out.print("</BODY>n"); 21 } 22 } จากซอร์สโค้ดมีการกำหนดการอิมพอร์ตแพ็กเกจ EJP ในบรรทัดที่ 4 เพื่อให้สามารถใช้งานคลาส ThaiUtilities ได้ และในบรรทัดที่ 15 และ 17 มีการเรียกใช้งานเมธอด ASCII2Unicode โดยมีอาร์กิวเม็นต์เป็นข้อมูลพารามิเตอร์ของทั้ง name และ surname ซึ่งเป็นตัวอักษรภาษาไทยในระบบ ASCII ดังนั้นผลลัพธ์ที่ได้คือรับคือจากเมธอด ASCII2Unicode จึงเป็นตัวอักษรเดียวกันแต่เป็นระบบของ Unicode แทน จากนั้นนำเอามารวมไว้ในตัวแปร prramName และ paramSurname สำหรับพารามิเตอร์ name และ surname ตามลำดับ เมื่อคอมไพล์ไฟล์ซอร์สโค้ดและนำมาติดตั้งนตำแหน่งที่ถูกต้อง จากนั้นทดสอบการใช้งานของเซิร์ฟเล็ต GetThaiParameters ด้วย URL ดังนี้ http://localhost:8080/ejp/servlet/GetThaiParameters?name=รุ่งโรจน์&surname=โพนคำ ซึ่งทำให้ได้ผลลัพธ์ที่จากการอ่านพารามิเตอร์ที่บรรจุข้อมูลตัวอักษรภาษาไทยได้อย่างถูกต้อง ตามรูปที่ปรากฎบนพื้นที่ของบราวเซอร์ดังนี้ รูปแสดงผลลัพธ์จากการทำงานของเซิร์ฟเล็ต GetParameters โดยป้อนพารามิเตอร์เมื่อใช้ผ่าน URL ที่เป็นภาษาไทย การส่งข้อมูล URL นอกจากจะสามารถระบุด้วยการพิมพ์ตัวอักษรจากคีย์บอร์ดไปโดยตรงแล้ว ยังสามารถระบุได้ด้วยการกำหนดค่าฐานสิบหกของรหัสในรูปแบบ UTF-8 ด้วยเช่นกัน โดยพิมพ์ค่าฐานสิบหกต่อจากเครื่องหมาย % เช่นหากต้องการส่งข้อมูล "ก" ก็พิมพ์ข้อมูล %A1 ซึ่งการส่งลักษณะนี้เรียกว่าการส่งข้อมูลในแบบการเข้ารหัส หรือเอ็นโค้ด (Encode) ลองทสดสอบการส่งข้อมูลพารามิเตอร์ที่เข้ารหัสภาษาไทยไว้ โดยให้พารามิเตอร์ name บรรจุตัวอักษรคำว่า "ภาษา" และ surname บรรจุตัวอักษรภาษาไทยคำว่า "จาวา" ด้วย URL ดังนี้ ตัวอย่าง 4 การอ้างถึงเซิร์ฟเล็ต GetThaiParameters พร้อมข้อมูลพารามิเตอร์ภาษาไทยที่เข้ารหัสไว้ http://localhost:8080/examples/servlet/GetThaiParameters?name=%C0%D2%C9%D2&surname=%A8%D2%C7%D2 เมื่อ คำว่า ภาษา คือค่า %C0%D2%C9%D2 คำว่า จาวา คือค่า %A8%D2%C7%D2
  • 14. จากการทดสอบการทำงานกับคลาส GetThaiParameters ซึ่งก็สามารถเข้าใจรหัสที่ได้รับการเข้ารหัสไว้ว่าเป็นข้อมูลตัวอักษรในกลุ่ม ASCII ดังนั้นจึงถูกแปลงไปเป็น Windows-874 ด้วยเมธอด ASCII2Unicode เหมือนกับพารามิเตอร์ที่เป็นตัวอักษรภาษาไทยปกติที่ไม่ได้เข้ารหัส ดังนั้นผลลัพธ์ของการทำงานจึงเป็นดังนี้ รูปแสดงผลลัพธ์จากการทำงานของเซิร์ฟเล็ต GetThaiParameters จาก URL ที่มีพารามิเตอร์ภาษาไทยที่เข้ารหัสไว้ การอ่านค่าพารามิเตอร์หลายค่า จากรูปแบบการใช้งานเซิร์ฟเล็ตผ่าน URL เพื่อป้อนข้อมูลพารามิเตอร์นั้นอาจทำให้เกิดความไม่สะดวกขึ้น เนื่องจากหากต้องการป้อนข้อมูลพารามิเตอร์มีความยาวมากๆทำให้เกิดความยุ่งยากในการพิมพ์ตัวอักษรซึ่งอาจผิดพลาดได้ ดังนั้นการร้องขอในแบบ GET ผ่านทาง URL สามารถใช้ลักษณะของการทำงานของเอกสาร HTML ที่เรียกกันว่าฟอร์ม (FORM) โดยสร้างฟอร์มที่บรรจุช่องกรอกข้อมูล (Text Field) สำหรับพารามิเตอร์แต่ละตัว หรืออาจจะสร้างรูปแบบการกรอกข้อมูลแบบอื่นๆประกอบกันในฟอร์มก็ได้ เช่น กล่องข้อความขนาดใหญ่ (Text Area) กล่องเลือกทั้งแบบ Radio Box และ Check Box ปุ่มกด (Button) เป็นต้น 1 <html> 2 <head> 3 <title>User Profile</title> 4 <meta http-equiv="Content-Type" content="text/html; charset=windows-874"> 5 </head> 6 7 <body bgcolor="#FFFFFF"> 8 <form name="frmUserProfile" method="get" 9 action="http://localhost:8080/examples/servlet/GetMoreParameters"> 10 <p> <input type="text" name="name"> 11 <input type="text" name="surname"></p> 12 <p> <input type="radio" name="gender" value="Male"> 13 <input type="radio" name="gender" value="Female"> </p> 14 <p> <input type="text" name="dd" size="2" maxlength="2"> / 15 <input type="text" name="mm" size="2" maxlength="2"> / 16 <input type="text" name="yyyy" size="4" maxlength="4"> ( / / )</p> 17 <p> <textarea name="address" cols="70" rows="6"></textarea></p> 18 <p><input type="submit" name="Submit" value="Submit"></p> 19 </form> 20 </body> 21 </html> จากตัวอย่างด้านบนคือเอกสาร HTML ในไฟล์เอกสารใดๆก็ได้แต่ให้มีนามสกุล html หรือ htm เช่น TestFarameterForm.htm ซึ่งเป็นการสร้างเอกสารที่เป็นฟอร์มกรอกข้อมูลโดยบรรจุส่วนในการบันทึกข้อมูลที่สามารถใส่ได้จากผู้ใช้ โดยมีการแบ่งเป็นพารามิเตอร์ดังนี้ ชนิด ชื่อพารามิเตอร์ ปรากฏในบรรทัดที่ Text Field name 10 Text Field surname 11 Radio Box gender 12 และ 13
  • 15. Text Field dd 14 Text Field mm 15 Text Field yyyy 16 Text Area address 17 Button Submit 18 สำหรับฟิลด์ Submit นี้สำหรับเพื่อให้ผู้ใช้กดเพื่อส่งข้อมูลไปยังเซิร์ฟเล็ตที่อ้างจากแอตทริบิวต์ action ในแท็กฟอร์มที่ปรากฏในบรรทัดที่ 9 ข้อสังเกตอีกข้อหนึ่งในบรรทัดที่ 8 เป็นการกำหนดรูปแบบการส่งข้อมูลด้วยคำสั่ง get จากแอตทริบิวต์ method ในโพรโตคอล HTTP จากการเปิดใช้งานฟอร์มในบราวเซอร์ สามารถแสดงผลได้ดังนี้ คือ รูปแสดงฟอร์มที่เกิดจากเอกสาร HTML หากเซิร์ฟเล็ตแต่หากมีพารามิเตอร์หลายตัว และอาจเป็นพารามิเตอร์ที่ไม่สามารถคาดเดาได้ว่ามีชื่ออะไร เซิร์ฟเล็ตสามารถจัดการกับพารามิเตอร์ได้ในคราวละหลายๆตัว โดยอาศัยเมธรดที่อยู่ใน HttpServletRequest ดังนี้ รูปแบบ public Enumeration getParameterNames() เมื่อ Enumeration คือคลาสที่ใช้ในการเก็บข้อมูลเป็นลีสต์ (List) เมธอด getParameterNames จะส่งข้อมูลรายการพารามิเตอร์ทั้งหมดเก็บไว้ในรูปแบบ Enumeration จากแบบฟอร์มอกสาร HTML ในส่วนต้นนั้น เมื่อผู้ใช้กรอกข้อมูลลงในแต่ละฟิลด์และแต่ละฟิลด์คือพารามิเตอร์แต่ละตัวซึ่งแต่ละตัวจะถึงส่งไปให้เซิร์ฟเล็ต ดังนั้นการอ่านข้อมูลพารามิเตอร์ที่สามารถอ่านทั้งชื่อพารามิเตอร์มาใช้งาน จึงสามารถอ่านได้จากข้อมูลรูปแบบ Enumeration ที่ได้รับมาจากเมธอด getParameterNames ดังแสดงให้เห็นจากตัวอย่างซอร์สโค้ด GetMoreParameters.java ต่อไปนี้ 1 import java.io.*; 2 import java.util.*; // Enumeration 3 import javax.servlet.*; 4 import javax.servlet.http.*;
  • 16. 5 6 public class GetMoreParameters extends HttpServlet { 7 public void doGet (HttpServletRequest request, HttpServletResponse response) 8 throws ServletException, IOException { 9 response.setContentType("text/html; charset=windows-874"); 10 PrintWriter out = response.getWriter(); 11 out.println("<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">"); 12 out.print("<HTML>n"); 13 out.print("<HEAD><TITLE> </TITLE></H EAD>n"); 14 out.print("<BODY>"); 15 16 Enumeration enumParams = request.getParameterNames(); // 17 while (enumParams.hasMoreElements()) { // 18 // String 19 String paramName = (String)enumParams.nextElement(); 20 out.print("<P>Parameter Name: <B>" + paramName + "</B>"); 21 out.print(" Parameter Value: <B>" + 22 ThaiUtilities.ASCII2Unicode(request.getParameter(paramName)) + "</B>"); 23 } 24 out.print("</BODY>"); 25 out.print("</HTML>n"); 26 } 27 } จากตัวอย่างในบรรทัดที่ 16 เป็นการอ่านพารามิเตอร์มาเก็บไว้ในตัวแปร enumParams จากนั้นมีการวนลูปผ่านเมธอดเพื่อตรวจสอบว่ายังคงมีพารามิเตอร์อยู่ใน enumParams หรือไม่ซึ่งเป็นคำสั่งในบรรทัดที่ 17 ในแต่ละลูปในบรรทัดที่ 19 มีการอ่านชื่อพารามิเตอร์ผ่านเมธอด nextElement และแปลงออปเจ็คที่ได้ให้เป็น String เก็บไว้ในตัวแปร paramName ซึ่งข้อมูลที่ได้คือชื่อของพารามิเตอร์แต่ละตัว ในบรรทัดที่ 22 เป็นการนำเอาชื่อที่บรรจุในตัวแปร paramName มาใช้งานในการอ่านข้อมูลพารามิเตอร์ผ่านเมธอด getParameter เพื่อแสดงต่อไป
  • 17. รูปแสดงข้อมูลที่ป้อนให้กับฟอร์มเพื่อส่งไปให้เซิร์ฟเล็ต GetMoreParameters จากรูปด้านบนแสดงการกรอกข้อมูลลงในฟอร์มของเอกสาร HTML จากนั้นกดที่ปุ่ม Submit ด้านล่างของเอกสาร ข้อมูลทั้งหมดถูกเก็บเป็นพารามิเตอร์ส่งให้กับเซิร์ฟเล็ต getMoreParameters และหลังจากกดปุ่มข้อมูลในช่อง URL ของบราวเซอร์เปลี่ยนเป็นดังนี้ http://localhost:8080/examples/servlet/GetMoreParameters?name=%E3%B9%B9%E9%D3%C1%D5%BB%C5%D2&surname= %E3%B9%B9%D2%C1%D5%A2%E9%D2%C7&gender=Male&dd=27&mm=9&yyyy=2513&address=%BE%D7%E9%B9%B7% D5%E8%CD%D1%B9%CD%D8%B4%C1%CA%C1%BA%D9%C3%B3%EC+%E1%CB%E8%A7%CB%B9%D6%E8%A7%E3%B9 %E0%C1%D7%CD%A7%E4%B7%C2&Submit=Submit หากสังเกตจากข้อมูล URL พบว่าข้อมูลพารามิเตอร์ที่ป้อนเป็นตัวอักษรภาษาไทยได้ถูกเข้ารหัสเรียบร้อยแล้ว ซึ่งการทดสอบผู้ใช้ทดสอบจากบราวเซอร์ที่ชื่อ Internet Explorer ที่ตั้งข้อกำหนดไว้ว่าให้ส่งข้อมูลที่นอกเหนือจากตัวอักษรภาษาอังกฤษเป็นตัวอักษรที่เข้ารหัสตัวอักษรไว้ ข้อแนะนำ สำหรับเว็บบราวเซอร์ชื่อ Internet Explorer สามารถกำหนดรูปแบบการเข้ารหัส URL ได้จากเมนู Tools -> Internet Options คลิกที่แท็บ Advanced และเลือกที่รายการ Always send URLs and UTF-8 ส่วนในพื้นที่การแสดงผลหลังจากกดปุ่ม Submit ซึ่งเกิดจากการทำงานของเซิร์ฟเล็ต GetMoreParameters เป็นดังนี้ รูปแสดงการทำงานของเซิร์ฟเล็ต GetMoreParameters ที่ถูกเรียกผ่านฟอร์มเอกสาร HTML การส่งข้อมูลด้วยเว็บรูปแบบ POST ด้วยฟอร์ม HTML จากข้อมูลที่นำเสนอแก่ผู้อ่าน ข้อมูลส่วนใหญ่ที่ส่งข้อมูลพารามิเตอร์จากบราวเซอร์ไปยังเว็บเซิร์ฟเวอร์เป็นรูปแบบ GET สังเกตจากข้อมูลปรากฏที่ URL ด้วยหรือแม้จาส่งด้วยการกรอกฟอร์มก็ตาม ในแท็ก FORM ของภาษา HTML ก็ระบุแอตทริบิวต์ METHOD = "GET" ซึ่งข้อเสียแน่นอนว่าผู้อื่นสามารถมองเห็นข้อมูลที่ช่อง Address ของบราวเซอร์โดยตรง ในการที่จะหลีกเลี่ยงปัญหานี้จำเป็นต้องกำหนดรูปแบบการส่งข้อมูลเป็นแบบใหม่คือแบบ POST ซึ่งการส่งรูปแบบนี้เป็นการส่งข้อมูลพารามิเตอร์ไปยังส่วนหัวของข้อมูลร้องขอ ซึ่งข้อมูลพารามิเตอร์ในแบบ POST นี้จะไม่อยู่รวมกับ URL เหมือนในแบบ GET ที่เห็นได้จากช่องแอดเดรสของบราวเซอร์ทั่วไป (ในแบบ GET ข้อมูลพารามิเตอร์ถือเป็นส่วนหนึ่งของคำสั่งร้องข้อ) การส่งพารามิเตอร์แบบ POST นี้จำเป็นต้องอาศัยรูปแบบการสร้างฟอร์มของภาษา HTML โดยระบุส่วนแอตทริบิวต์ METHOD = "POST" ในแท็ก FORM ดังนี้
  • 18. <FORM METHOD="POST" ACION="……." > … </FORM> นอกจากมีการแก้ไขเอกสาร HTML แล้วยังต้องแก้ไขซอร์สโค้ดของเซิร์ฟเล็ตร่วมด้วย ซึ่งศึกษาได้จากเนื้อหาในส่วนต่อไปนี้ เซิร์ฟเล็ตที่สนับสนุนคำสั่งรูปแบบ POST โปรแกรมเซิร์ฟเล็ตที่สร้างกันมาตั้งแต่ต้นนั้นสนับสนุนการทำงานเมื่อบราวเซอร์ร้องข้อในรูปแบบ GET เท่านั้น สังเกตได้จากในซอร์สโค้ดมีการสร้างสเตจเม็นต์ส่วนการประมวลผลไว้ในเมธอด doGet ทั้งหมด แน่นอนว่าหากต้องการสร้างเซิร์ฟเล็ตที่สนับสนุนการร้องขอในแบบ POST ด้วยแล้วต้องสร้างคำสั่งไว้ในเมธอด doPost แทน นั่นก็คือให้ย้ายสเตจเม็นต์จาก doGet ไปใส่ไว้ใน doPost นั่นเอง รูปแบบ public void doPost (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { … } ผู้อ่านอาจจะมีคำถามในใจว่าแล้วอย่างนี้หากต้องการสร้างเซิร์ฟเล็ตที่รอบรับทั้งรูปแบบ GET และรูปแบบ POST ภายในเซิร์ฟเล็ตตัวเดียวกันนั้น ก็ต้องสร้างสเตจเม็นต์เอาไว้ทั้งเมธอด doGet และ doPost หรือไม่? แน่นอนครับว่าควรจะเป็นแบบนั้น แต่ในการสร้างเซิร์ฟเล็ตลักษณะนี้จะทำให้โปรแกรมมีขนาดใหญ่และคลาสมีมีความซ้ำซ้อนขึ้นตามไปด้วย วิธีการแก้ปัญหานี้ก็คคือให้สร้างสเตจเม็นต์ไว้ในเมธอดใดเมธอดหนึ่งระหว่าง doGet หรือ doPost จากนั้นใช้เมธอดที่เหลือเรียกเมธอดนั่น เช่น เมื่อสร้างสเตจเม็นต์เอาไว้ในเมธอด doGet ก็ให้เมธอด doPost เรียกใช้งานเมธอด doGet หรือในทางกลับกันหากสร้างสเตจเม็นต์ไว้ในเมธอด doPost แล้วก็ให้เมธอด doGet เรียกใช้งานเมธอด doPost แทน เพื่อให้เกิดความเข้าใจให้พิจารณาจากซอร์สโค้ดต่อไปนี้ ต่อไปนี้เป็นการปรับปรุงเซิร์ฟเล็ตที่ชื่อ GetMoreParameters เป็นเซิร์ฟเล็ตตัวใหม่ชื่อ PostParameters เพื่อให้สามารถรองรับข้อมูลได้ทั้งจากการร้องขอในแบบ POST และแบบ GET ในไฟล์ ReadParameters ดังนี้ 1 import java.io.*; 2 import java.util.*; 3 import javax.servlet.*; 4 import javax.servlet.http.*; 5 import EJP.ThaiUtilities; 6 7 public class ReadParameters extends HttpServlet { 8 public void doGet (HttpServletRequest request, HttpServletResponse response) 9 throws ServletException, IOException { 10 response.setContentType("text/html; charset=windows-874"); 11 PrintWriter out = response.getWriter(); 12 out.println("<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">"); 13 out.print("<HTML>n"); 14 out.print("<HEAD><TITLE> GET POST</TITLE></HEAD>n"); 15 out.print("<BODY>"); 16 17 Enumeration enumParams = request.getParameterNames(); 18 while (enumParams.hasMoreElements()) { 19 String paramName = (String)enumParams.nextElement(); 20 out.print("<P>Parameter Name: <B>" + paramName + "</B>"); 21 out.print(" Parameter Value: <B>" +
  • 19. 22 ThaiUtilities.ASCII2Unicode(request.getParameter(paramName)) + "</B>"); 23 } 24 out.print("</BODY>"); 25 out.print("</HTML>n"); 26 } 27 public void doPost (HttpServletRequest request, HttpServletResponse response) 28 throws ServletException, IOException { 29 doGet(request, response); 30 } 31 } หากสังเกตจากซอร์สโค้ดจะพบว่าคลาส ReadParameters มีการสร้างเมธอด doGet ในบรรทัดที่ 8-26 ซึ่งบรรจุสเตจเม็นต์รองรับการทำงานทั้งหมดของเซิร์ฟเล็ต และเมธอด goPost ในบรรทัดที่ 17-30 ที่มีเพียงสเตจเม็นในบรรทัดที่ 29 ที่เป็นการเรียกใช้เมธอด doGet โดยผ่านอาร์กิวเม็นต์ที่ตัวเองได้รับคือทั้ง request และ response ตามไปด้วย ลองมาทดสอบการทำงานของเซิร์ฟเล็ต ReadParameters ด้วยตัวอย่างของเอกสาร HTML ที่ส่งข้อมูลพารามิเตอร์ไปในรูปแบบ POST ดังนี้ 1 <html> 2 <head> 3 <title>POST Form</title> 4 <meta http-equiv="Content-Type" content="text/html; charset=windows-874"> 5 </head> 6 7 <body bgcolor="#FFFFFF"> 8 <form name="frmPOST" method="POST" 9 action="http://localhost:8080/examples/servlet/ReadParameters"> 10 <p> ? 11 <input type="text" name="SPORT"> 12 </p> 13 <input type="submit" name="" value=" "> 14 </form> 15 </body> 16 </html> จากเอกสาร HTML ข้างต้นเป็นการสร้างฟอร์มเพื่อส่งในแบบ POST จากบรรทัดที่ 8 ซึ่งระบุแอตทริบิวต์ method="POST" ไปยังเซิร์ฟเล็ต ReadParameters จากแอตทริบิวต์ action ในบรรทัดที่ 9 ในฟอร์มมีช่องกรอกข้อมูลพารามิเตอร์ชื่อ SPORT กับปุ่มส่งข้อมูลในบรรทัดที่ 11 และ 13 ตามลำดัง ซึ่งเมื่อเปิดเอกสารจากบราวเซอร์จะปรากฏผลลัพธ์และข้อมูลผลลพธ์ดังนี้ ก) ป้อนข้อมูลลงในเอกสาร HTML ไฟล์ ข) ผลลัพธ์จากการทำงานของเซิร์ฟเล็ต ReadParamaters รูปแสดงการทำงานเอกสาร HTML และเซิร์ฟเล็ต ReadParameter คลาส HTMLUtilities ช่วยสร้างเว็บเพจ ก่อนที่จะข้ามไปสู่เนื้อหาในบทต่อไป ผู้เขียนขอแนะนำคลาสในกลุ่มของ Utility คือคลาส HTMLUtilities ที่ช่วยในการเสริมการทำงานในการสร้างเอกสาร HTML ในการทำงานของเซิร์ฟเล็ต โดยในคลาสประกอบด้วยเมธอด createHTMLStart
  • 20. ใช้ในการกำหนดข้อมูลส่วนต้นๆของเอสการ HTML นั่นคือแท็กเปิดของ HTML, HEAD และ BODY รวมถึงการกำหนดชื่อเอกสารในแท็ก TITLE ด้วยอาร์กิวเม็นต์ที่ผ่านเข้ามา ส่วนเมธอดที่สองคือ createHTMLend ซึ่งเป็นการสร้างเอกสารส่วนท้ายคือแท็กปิดต่างๆ ทั้ง BODY และ HTML ดังซอร์สโค้ดต่อไปนี้ 1 package EJP; 2 import java.io.*; 3 import javax.servlet.*; 4 import javax.servlet.http.*; 5 6 public class HTMLUtilities { 7 public static void createHTMLStart (PrintWriter out, String title) { 8 out.println("<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">"); 9 out.print("<HTML>n"); 10 out.print("<HEAD><TITLE>" + title + "</TITLE></HEAD>n"); 11 out.print("<BODY>"); 12 } 13 public static void createHTMLEnd (PrintWriter out) { 14 out.print("</BODY>"); 15 out.print("</BODY>n"); 16 } 17 } คลาส HTMUtilities บรรจุอยู่ในแพ็กเกจ EJP และจะถูกใช้ในการสร้างเซิร์ฟเล็ตที่จะนำเสนอในบทต่อไป ในบทต่อไปจะมีเนื้อหาที่เพิ่มศักย ภาพในการทำงานของเซิร์ฟเล็ตให้ เพิ่มขึ้น โดยมีการพิจาณาข้อมูลร้องขอที่ส่ งมาจากบราวเซอร์ว่าจะสามารถอ่ านรายละเอียดที่ได้รับนอกเหนือจ ากพารามิเตอร์ที่ได้กล่าวไว้ในบท นี้ได้อย่างไร นอกจากนั้นยังรวมถึงวิธีการทำให้เ ซิร์ฟเล็ตสามารถจัดการกับข้อมูลโ ต้ตอบซึ่งมีทั้งสถานะรหัสโต้ตออบ และข้อมูลโต้ตอบส่วนหัว ซึ่งจะทำให้เซิร์ฟเล็ตสามารถทำงา นได้อย่างหลากหลายขึ้นกว่าที่ได้เ รียนรู้ในบทนี้