จาก Java Programming Bookstore Appication Series 4: Building Web Applications Using Servlets and JSP เราได้ทำการสร้าง Web Project ขึ้นมาใหม่และ setup virtual server กันแล้วต่อไปเราจะเริ่มเขียนโปรแกรมกันแล้วครับ ตามรูปที่ 1 ให้เราเริ่มสร้างไฟล์ Java servlet เพื่อทดสอบก่อนโดยการคลิกเมาส์ขวาที่โฟลเดอร์ src > New > Class จะปรากฏหน้าต่างตามรูปที่ 2
รูปที่ 1
จากรูปที่ 2 ให้ตั้งชื่อคลาสนี้ว่า HelloWorld แล้วกดปุ่ม Finish แล้วแก้ไขตาม java code ดังตัวอย่างที่ 1
รูปที่ 2
ตัวอย่างที่ 1
package bookstore;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* @author
*
*/
public class HelloWorld extends HttpServlet {
/**
*
*/
private static final long serialVersionUID = 5554359782034597552L;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse response)
throws ServletException, IOException {
try {
response.setContentType( "text/html");
PrintWriter printWriter = response.getWriter();
printWriter.println( "<h2>");
printWriter.println( "Hello World");
printWriter.println( "</h2>");
} catch (IOException ioException) {
ioException.printStackTrace();
}
}
}
จากนั้นให้แก้ไขไฟล์ web.xml ตามตัวอย่างที่ 2
ตัวอย่างที่ 2
<?xml version= "1.0" encoding ="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns= "http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
id= "WebApp_ID" version ="3.0">
<display-name> bookstore hello world</display-name >
<servlet>
<servlet-name> bookstore</servlet-name >
<servlet-class> bookstore.HelloWorld</servlet-class >
</servlet>
<servlet-mapping>
<servlet-name> bookstore</servlet-name >
<url-pattern> /hello</ url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file> index.html</welcome-file >
<welcome-file> index.htm</welcome-file >
<welcome-file> index.jsp</welcome-file >
<welcome-file> default.html</welcome-file >
<welcome-file> default.htm</welcome-file >
<welcome-file> default.jsp</welcome-file >
</welcome-file-list>
</web-app>
จากนั้นทดสอบ start Tomcat server และลองเรียก url ตามนี้ http://localhost:8080/bookstore/hello จะได้ผลตามรูปที่ 3
รูปที่ 3
เราแน่ใจได้แล้วว่าเรา setup ทุกอย่างมาถูกต้องแล้ว จากนี้ก็มาเริ่มสร้าง bookstore application กันสักทีครับ
ให้เรา copy java code จาก stand-alone java application มาที่โปรเจ็ค web ของเราครับ โดย copy ตามรูปที่ 3.1 แล้วมาวางไว้ที่ Java Web Project ที่โฟลเดอร์ src ตามรูปที่ 3.2
รูปที่ 3.1
รูปที่ 3.2
ลักษณะการทำงานจะมีด้วยกัน 6 step ตามรูปที่ 4 เราจะทำกันไปทีละ step นะครับ
รูปที่ 4
Step 1: Request
ตามตัวอย่างที่ 3 เราจะเริ่มจาก Deployment Descriptor (web.xml)
ตัวอย่างที่ 3
<?xml version= "1.0" encoding ="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns= "http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
id= "WebApp_ID" version ="3.0">
<display-name> bookstore</display-name >
<servlet>
<servlet-name> bookstore</servlet-name >
<servlet-class> bookstore.HelloWorld</servlet-class >
</servlet>
<servlet>
<servlet-name> BookServlet</servlet-name >
<servlet-class> com.apress.bookweb.controller.BookController</servlet-class >
<init-param>
<param-name> base</ param-name>
<param-value> /bookstore/books</param-value >
</init-param>
<init-param>
<param-name> imageURL</ param-name>
<param-value> /bookstore/images</param-value >
</init-param>
<load-on-startup> 1</ load-on-startup>
</servlet>
<context-param>
<param-name> param1</ param-name>
<param-value> /bookstore/books</param-value >
</context-param>
<context-param>
<param-name> imageURL</ param-name>
<param-value> /bookstore/images</param-value >
</context-param>
<servlet-mapping>
<servlet-name> BookServlet</servlet-name >
<url-pattern> /books</ url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name> bookstore</servlet-name >
<url-pattern> /hello</ url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file> index.html</welcome-file >
<welcome-file> index.htm</welcome-file >
<welcome-file> index.jsp</welcome-file >
<welcome-file> default.html</welcome-file >
<welcome-file> default.htm</welcome-file >
<welcome-file> default.jsp</welcome-file >
</welcome-file-list>
</web-app>
จากตัวอย่างที่ 3
- url-pattern/books จะถูก map กับ BookServlet ให้สังเกตใน <servlet-mapping> และ BookServlet ก็ยัง map ไปยัง BookController ใน <servlet> ดังนั้นเมื่อเราเรียก URL (http://localhost:8080/bookstore/books) ผ่าน browser url-pattern/books เป็นการเรียกใช้ BookController นั่นเองครับ
- <context-param>
Step 2: Access DB via DAO และ Step 3: Set Results
จาก step 1 เมื่อมี rquest url-pattern/books ก็เข้าสู่ส่วนของ Controller นั่นคือ BookController เมธอดแรกที่จะทำงานคือ init() Method ให้เราสร้าง BookController.java ตามรูปที่ 5
ข้อควรระวัง: ต้องแน่ใจว่า Package: ต้องตรงกันใน web.xml (com.apress.bookweb.controller) จากนั้นให้กดปุ่ม Browse... ที่ตรงกับ Superclass จะปรากฏตามรูปที่ 6
รูปที่ 5
ให้พิมพ์คลาสที่เราจะใช้เป็น Superclass ซึ่งก็คือ HttpServlet ตามรูปที่ 6 จากนั้นกดปุ่ม OK และปุ่ม Finish
รูปที่ 6
เริ่มแก้ไข BookController ตามตัวอย่างที่ 4
ตัวอย่างที่ 4
package com.apress.bookweb.controller;
import java.util.List;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import com.apress.books.dao.BookDAO;
import com.apress.books.dao.BookDAOImpl;
import com.apress.books.model.Category;
public class BookController extends HttpServlet {
private static final long serialVersionUID = 7182979735084255108L;
@Override
public void init(ServletConfig config) throws ServletException {
super.init(config);
BookDAO bookDao = new BookDAOImpl();
// calling DAO method to retrieve bookList from Database
List<Category> categoryList = bookDao.findAllCategories();
ServletContext context = config.getServletContext();
context.setAttribute( "categoryList", categoryList);
}
}
จากตัวอย่างที่ 4
- ติดต่อ database ผ่าน DAO ด้วย findAllCategories() โดยใช้ BookDAO
- set ผลลัพธ์ที่ได้ไปยัง ServletContext เพื่อส่งกลับไปยังหน้า view
Step 4: Dispatch to View ส่งกลับไปยังหน้าเพจ
เมื่อ BookController ทำงานใน init() สำเร็จ servlet container จะเรียก cycle ต่อไปคือ service() (อ่านได้ใน life-cycle ของ Servlet) เมธอด service() จะคอยดัก request ที่เรียกเข้ามาว่าเป็น GET หรือ POST ตามตัวอย่างที่ 5 ใน BookController คลาส
ตัวอย่างที่ 5
@Override
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
@Override
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
String base = "/jsp/";
String url = base + "home.jsp";
String action = request.getParameter( "action");
String category = request.getParameter( "category");
String keyWord = request.getParameter( "keyWord");
if (action != null) {
switch (action) {
case "allBooks" :
findAllBooks(request, response);
url = base + "listOfBooks.jsp";
break;
case "category" :
findAllBooks(request, response);
url = base + "category.jsp?category=" + category;
break;
case "search" :
searchBooks(request, response, keyWord);
url = base + "searchResult.jsp";
break;
}
}
RequestDispatcher requestDispatcher = getServletContext()
.getRequestDispatcher(url);
requestDispatcher.forward(request, response);
}
private void searchBooks(HttpServletRequest request,
HttpServletResponse response, String keyWord)
throws ServletException, IOException {
try {
BookDAO bookDao = new BookDAOImpl();
List<Book> bookList = bookDao.searchBooksByKeyword(keyWord);
request.setAttribute( "bookList", bookList);
} catch (Exception e) {
System. out.println(e);
}
}
private void findAllBooks(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
try {
BookDAO bookDao = new BookDAOImpl();
List<Book> bookList = bookDao.findAllBooks();
request.setAttribute( "bookList", bookList);
} catch (Exception e) {
System. out.println(e);
}
}
จากตัวอย่างที่ 5
- doPost() method จะถูกเรียกจาก doGet() method อีกที
- request.getParameter("XXX") เป็นการรับค่าจาก request ถ้าไม่พบ parameter ใดๆ ผลลัพธ์จะได้ค่า null
- requestDispatcher.forward(request, response) เป็นการเรียกไปยังหน้า page ที่ต้องการ
Step 5: View uses Model เป็นขั้นตอนการดึงข้อมูลจาก Model มาแสดงบนหน้า page
จาก step 4 controller จะทำการเรียกหน้า home.jsp โดย RequestDispatcher ให้เราทำการสร้างหน้า html ต่อไปนี้ home.jsp จะประกอบด้วย leftColumn.jsp ซึ่งเป็นส่วนเมนู และ header.jsp
จากรูปที่ 7 ให้สร้างหน้า JSP โดยการคลิกเมาส์ขวาที่โฟลเดอร์ WebContent/jsp เลือกเมนู New > JSP File จะปรากฏหน้าต่างตามรูปที่ 8
รูปที่ 7
ให้ตั้งชื่อ File name: เป็น home.jsp และกดปุ่ม Finish (ทำวิธีเดียวกันกับไฟล์ที่เหลือ) จากนั้นให้แก้ไขหน้า home.jsp ตามตัวอย่างที่ 6
รูปที่ 8
ตัวอย่างที่ 6 home.jsp
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1" %>
<%@page import= "java.util.List"%>
<%@page import= "java.util.ArrayList"%>
<%@page import= "java.util.Iterator"%>
<%@page import= "com.apress.books.model.Book" %>
<!DOCTYPE html >
<%
String imageURL=application.getInitParameter( "imageURL");
%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name= "viewport" content ="width=device-width, initial-scale=1" />
<link rel= "stylesheet" href ="css/bookstore.css" type= "text/css" />
<script type= "text/javascript" src ="js/jquery-1.9.1.js"></ script>
<script src= "js/bookstore.js"></script >
</head>
<body>
<div id= "centered">
<jsp:include page= "header.jsp" flush ="true" />
<br />
<jsp:include page= "leftColumn.jsp" flush ="true" />
<span class= "label">Featured Books </span>
<table>
<tr>
<td>< span class ="tooltip_img1">< img
src= "<%=imageURL %>/A9781430248064-small_3.png" /></ span></td >
<td>< img src=" <%=imageURL %>/A9781430239963-small_1.png" /></ td>
<td>< img src=" <%=imageURL %>/A9781430247647-small_3.png" /></ td>
<td>< img src=" <%=imageURL %>/A9781430231684-small_8.png" /></ td>
<td>< img src=" <%=imageURL %>/A9781430249474-small_1.png" /></ td>
</tr>
<tr>
<td>< img src=" <%=imageURL %>/A9781430248187-small_1.png" /></ td>
<td>< img src=" <%=imageURL %>/A9781430243779-small_2.png" /></ td>
<td>< img src=" <%=imageURL %>/A9781430247401-small_1.png" /></ td>
<td>< img src=" <%=imageURL %>/A9781430246596-small_1.png" /></ td>
<td>< img src=" <%=imageURL %>/A9781430257349-small_1.png" /></ td>
</tr>
</table>
</div>
</body>
</html>
จากตัวอย่างที่ 6
- <jsp:include> tag ช่วยให้เราสามารถเรียกใช้ไฟล์ jsp อื่นๆได้ เช่นในตัวอย่างจะเป็นการดึง jsp ที่ทำหน้าที่เมนู leftColumn.jsp ซึ่งสามารถใช้ เทคนิคนี้ในการ reuse ไฟล์ jsp ได้ลดการซ้ำซ้อนของ code ส่วนของเมนู ดูได้จากตัวอย่างที่ 7
ตัวอย่างที่ 7 leftColumn.jsp
<%@page language= "java" contentType ="text/html"%>
<%@page import= "java.util.Enumeration" %>
<%@page import= "java.util.Hashtable"%>
<%@page import= "java.util.List"%>
<%@page import= "java.util.ArrayList"%>
<%@page import= "java.util.Iterator"%>
<%@page import= "com.apress.books.model.Book" %>
<%@page import= "com.apress.books.model.Category" %>
<%
String param1 = application.getInitParameter( "param1");
%>
<link rel= "stylesheet" href ="css/bookstore.css" type= "text/css" />
<script src= "js/bookstore.js" type ="text/javascript"></ script>
<script type= "text/javascript" src ="js/jquery-1.9.1.js"></ script>
</head>
<div class= "leftbar">
<ul id= "menu">
<li>< div>
<a class= "link1" href ="<%=param1%> "> <span class="label"
style=" margin-left: 15px ;"> Home</ span>
</a>
</div></ li>
<li>< div>
<a class= "link1" href=" <%=param1 %>?action=allBooks">< span
style=" margin-left: 15px ;" class ="label"> All Books</span></ a>
</div></ li>
<li>< div>
<span class= "label" style ="margin-left : 15px;"> Categories</span >
</div>
<ul>
<%
// comment 1
List<Category> categoryList1 = (List<Category>) application
.getAttribute( "categoryList");
Iterator<Category> iterator1 = categoryList1.iterator();
// comment 2
while (iterator1.hasNext()) {
Category category1 = (Category) iterator1.next();
%>
<li>< a class ="label"
href= "<%=param1 %>?action=category&categoryId=<%= category1.getId()%>&category= <%=category1.getCategoryDescription() %>">< span
class= "label" style ="margin-left : 30px;"> <%=category1.getCategoryDescription() %></span ></a>
</li>
<%
}
%>
</ul></ li>
<li>< div>
<span class= "label" style ="margin-left : 15px;">Contact Us</span>
</div></ li>
</ul>
<form class= "search">
<input type= "hidden" name ="action" value= "search" /> < input id="text"
type= "text" name ="keyWord" size= "12" /> < span
class= "tooltip_message">?</span >
<p />
<input id= "submit" type ="submit" value= "Search" />
</form>
</div>
จากตัวอย่างที่ 7
- ให้สังเกตที่ comment 1 เราจะได้รับรายการ category มาจาก ServletContext ซึ่งส่งมาจาก step 2 นั่นเอง
- comment 2 เป็นการวนเพื่อดึงข้อมูลมาจาก model และนำผลที่ได้มาแสดงบน page
- จากตัวอย่างของตัวอย่างนี้การฝั่ง java code ใน JSP (scriptlets และ expressions) เป็นสิ่งที่ไม่ควรทำซึ่งผมจะอธิบายต่อไปในเรื่องของการใช้ JSTL และ EL
ตัวอย่างที่ 8 header.jsp
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1" %>
<div class= "header">
<h2>
<span style=" margin-left: 15px ; margin-top : 15px; " class="label" >BOOK
<span style= " color: white;"> STORE</ span></span >
</h2>
</div>
ตัวอย่างที่ 9 list.jsp
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1" %>
<%@page import= "java.util.List"%>
<%@page import= "java.util.ArrayList"%>
<%@page import= "java.util.Iterator"%>
<%@page import= "com.apress.books.model.Book" %>
<%@page import= "com.apress.books.model.Author" %>
<!DOCTYPE html >
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
</head>
<body>
<%
String category = request.getParameter( "category");
if(category != null){
%>
<div>
<span class= "label" style ="margin-left : 15px;"> List of <%= category%>
Books
</span>
</div>
<%} %>
<table id= "grid">
<thead>
<tr>
<th id= "th-title">Book Title </th>
<th id= "th-author">Author</th >
</tr>
</thead>
<tbody>
<%
List<Book> books = (List<Book>)request.getAttribute("bookList");
Iterator<Book> iterator = books.iterator();
while (iterator.hasNext()) {
Book book = (Book)iterator.next();
Long bookId = book.getId();
List<Author> authors = book.getAuthors();
%>
<tr>
<th scope= "row" id="r100" ><%=book.getBookTitle() %></th >
<% for (Author author: authors){
if ( book.getId().equals(author.getBookId())){
%><td ><%=author.getFirstName()+ " " +author.getLastName()%> </td>
<% }} %>
</tr>
<%
}
%>
</tbody>
</table>
</body>
</html>
ตัวอย่างที่ 10 listOfBooks.jsp
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1" %>
<%@page import= "java.util.List"%>
<%@page import= "java.util.ArrayList"%>
<%@page import= "java.util.Iterator"%>
<%@page import= "com.apress.books.model.Book" %>
<!DOCTYPE html >
<%
String imageURL=application.getInitParameter( "imageURL");
%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name= "viewport" content ="width=device-width, initial-scale=1" />
<script src= "js/jquery-1.9.1.js"></script >
<link rel= "stylesheet" href ="css/bookstore.css" type= "text/css" />
<script src= "js/bookstore.js" type ="text/javascript"></ script>
</head>
<body>
<div id= "centered">
<jsp:include page= "header.jsp" flush ="true" />
<br />
<jsp:include page= "leftColumn.jsp" flush ="true" />
<div>
<span class= "label" style ="margin-left : 15px;">List of All
Books </span>
</div>
<jsp:include page= "list.jsp" flush ="true" />
</div>
</body>
</html>
ตัวอย่างที่ 11 category.jsp
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1" %>
<%@page import= "java.util.List"%>
<%@page import= "java.util.ArrayList"%>
<%@page import= "java.util.Iterator"%>
<%@page import= "com.apress.books.model.Book" %>
<%@page import= "com.apress.books.model.Author" %>
<!DOCTYPE html >
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name= "viewport" content ="width=device-width, initial-scale=1" />
<script src= "js/jquery-1.9.1.js"></script >
<link rel= "stylesheet" href ="css/bookstore.css" type= "text/css" />
<script src= "js/bookstore.js"></script >
</head>
<body>
<div id= "centered">
<jsp:include page= "header.jsp" flush ="true" />
<br />
<jsp:include page= "leftColumn.jsp" flush ="true" />
<%
String category = request.getParameter( "category");
String categoryId = request.getParameter( "categoryId");
if (category != null) {
%>
<div>
<span class= "label" style ="margin-left : 15px;">List of <%=category%> Books
</span>
</div>
<%
}
%>
<table id= "grid">
<thead>
<tr>
<th id= "th-title">Book Title </th>
<th id= "th-author">Author</th >
</tr>
</thead>
<tbody>
<%
List<Book> books = (List<Book>) request.getAttribute("bookList" );
Iterator<Book> iterator = books.iterator();
while (iterator.hasNext()) {
Book book = (Book) iterator.next();
if (book.getCategoryId().toString().equals(categoryId)) {
Long bookId = book.getId();
List<Author> authors = book.getAuthors();
%>
<tr>
<th scope= "row" id="r100" ><%=book.getBookTitle() %></th >
<%
for (Author author : authors) {
if (book.getId().equals(author.getBookId())) {
%><td ><%=author.getFirstName() + " "
+ author.getLastName()%></td >
<%
}
}
%>
</tr>
<%
}
}
%>
</tbody>
</table>
</div>
</body>
</html>
ตัวอย่างที่ 12 searchResult.jsp
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1" %>
<%@page import= "java.util.List"%>
<%@page import= "java.util.ArrayList"%>
<%@page import= "java.util.Iterator"%>
<%@page import= "com.apress.books.model.Book" %>
<!DOCTYPE html >
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name= "viewport" content ="width=device-width, initial-scale=1" />
<script src= "js/jquery-1.9.1.js"></script >
<link rel= "stylesheet" href ="css/bookstore.css" type= "text/css" />
<script src= "js/bookstore.js"></script >
</head>
<body>
<div id= "centered">
<jsp:include page= "header.jsp" flush ="true" />
<br />
<jsp:include page= "leftColumn.jsp" flush ="true" />
<jsp:include page= "list.jsp" flush ="true" />
</div>
</body>
</html>
Step 6: Response ส่งกลับแสดงยัง Browser
ซึ่ง JSP เหล่านี้จะถูก render ด้วย browser นั่นเอง
หน้า Home Page
ผลลัพธ์ที่ได้ตามรูปที่ 9 (อย่าลืม copy โฟลเดอร์ css, images, js ไว้ในโฟลเดอร์ WebContent)
รูปที่ 9
เมื่อเลือกเมนู Categories จะได้ผลตามรูปที่ 10
รูปที่ 10
การค้นหาโดย Keyword
เมื่อพิมพ์ Keyword ลงใน textbox เช่นคำว่า Josh จะได้ผลตามรูปที่ 11
รูปที่ 11
เพิ่มเติม
ก่อน run ให้ copy ไฟล์ mysql-connector-java-5.1.33-bin.jar (MySQL Connector/J) ไปวางที่ Tomcat Home > โฟลเดอร์ lib
ตอนต่อไปติดตามได้ที่
Java Programming Bookstore Appication (Series 5): Building a Web Application Using Struts 2
Java Programming Bookstore Application (Series 6): Building Java Web Applications with Spring Web MVC
Java Programming Bookstore Application (Series 7): Component-Based Web Development Using JSF 2
Java Programming Bookstore Application (Series 8): Rapid Web Development with Grails
Java Programming Bookstore Application (Series 9): Play with Java and Scala
อ้างอิง
ผู้เขียน: procodeblog
ไม่มีความคิดเห็น:
แสดงความคิดเห็น