Chủ Nhật, 2 tháng 10, 2016

JSP trong MVC 1 và Servlet

JSP

1. JSP là gì
JSP là một công nghệ cho phép chúng ta dễ dàng viết các trang web động (chúng ta cũng có thể viết các trang web tĩnh với JSP). Cụ thể, một trang JSP là một trang HTML (hay XML) trong đó có thể trộn các mã Java, tức các thành phần JSP, cho phép thực hiện nội dung động. Trang JSP có phần mở rộng .jsp. Một trang jsp có thể là một hoặc bao gồm nhiều tập tin, mà các tập tin này có thể là một trang jsp hoàn chỉnh hay những đoạn (fragment) của một trang jsp. Những đoạn jsp này có phần mở rộng là .jspf

Như ta đã biết, nếu việc viết nội dung html trả lời trong servlet bằng cách dùng các lệnh out.println() là một việc tốn nhiều công sức, đặc biệt khi nội dung html trả lời càng phức tạp. Việc này còn tệ hơn khi ta muốn bảo trì hay thay đổi nội dung trả lời. Trong khi JSP đem lại một giải pháp tiện lợi hơn khi cho phép chèn nội dung động vào trang web, nó còn cho phép việc tách bạch phần trình bày và logic xử lý nội dung. Với servlet thì ta chèn mã html để phát sinh trong lớp java còn JSP thì ngược lại, ta chèn mã java trong trang html.

2. Vòng đời JSP
lập trình java web

Có thể xem JSP là một mức trừu tượng cao hơn Java servlet vì thực chất khi chạy (runtime) một trang JSP sẽ được chuyển thành một servlet. Bản chất như sau : khi một truy vấn được ánh xạ vào một trang JSP, vì mỗi servlet của một trang JSP được trữ (cache) và được tái sử dụng lại khi nào mà trang JSP gốc không thay đổi, web container sẽ kiểm tra servlet của trang JSP đó có cũ hơn trang JSP đó không. Nếu servlet cũ hơn thì web container sẽ dịch trang JSP ra một lớp servlet và biên dịch lớp này.
Khi ta dùng Tomcat, các trang jsp sẽ được dịch thành các lớp servlet và được lưu trong thư mục work, và các biên dịch của chúng cũng nằm cùng thư mục.
Sau khi trang jsp được biên dịch (compile), thì servlet của jsp này có vòng đời như vòng đời Servlet thông thường
2.1. Nếu trong web container chưa có một hiện thể (instance) nào của servlet của trang jsp thì web container sẽ :
a. Tải lớp servlet của trang jsp vào
b. Tạo một hiện thể của lớp servlet này.
c. Khởi tạo hiện thể của lớp này bằng cách gọi hàm jspInit.
2.2. Bộ chứa gọi hàm _jspService, và truyền vào tham số là hai đối tượng truy vấn và trả lời.
Nếu web container muốn loại bỏ servlet của trang jsp này, nó sẽ gọi hàm jspDestroy.

Khởi tạo và kết thúc một trang JSP

Ta có thể cá nhân hoá (customize) việc khởi tạo và kết thúc một trang jsp bằng cách ghi đè (override) các hàm jspInit và jspDestroy của mặt giao javax.servlet.jsp.JspPage . Chẳng hạn khởi tạo (initialize) một tài nguyên trong hàm jspInit để dùng trong toàn bộ trang jsp, rồi giải phóng (release) tài nguyên này trong hàm jspDestroy. Việc ghi đè này ta thực hiện trong thẻ khai báo, sẽ được trình bày dưới đây.

Hàm _jspService() tương ứng với nội dung trang jsp, được tự động định nghĩa bởi trình xử lý JSP (JSP processor) và người viết trang jsp đừng bao giờ định nghĩa hàm này.

3. Các thành phần JSP
a. Chỉ thị JSP (JSP directives)
Chỉ thị JSP có dạng sau :

<%@ directive attribute=value ...%>
Ví dụ :
<%@page contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"
        import="java.util.List, java.util.Date"
        language="java" %>
Mã:
<%@ page import="java.io.IOException" %>
Mã:
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
Mã:
<%@ include file="../includes/header.jspf"%>

   * Chỉ thị page có nhiều tuỳ chọn, trong đó có :

- import : nhập một gói (package) java. Chỉ thị này sẽ được chuyển thành chỉ dẫn import trong servlet.
- contentType : định nghĩa loại nội dung của trang sẽ được phát sinh.
- pageEncoding : định nghĩa chuẩn mã hoá trang phát sinh sử dụng.
- language : định nghĩa ngôn ngữ sử dụng.
...
Cách khai báo khác (JSP 2.0):

Mã:
<jsp:directive.page  contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"
        import="java.util.List, java.util.Date"
        language="java" />
* Chỉ thị include : chỉ định cho trình biên dịch gộp tập tin vào trang. Cách khai báo khác (JSP 2.0) bằng cách dùng hành động include (action include):
Mã:
<jsp:include page="../includes/header.jspf" />
Hai cách này tuy đưa lại kết quả như nhau nhưng chúng có sự khác biệt tế nhị sau :
- chỉ thị include <%@ include ...%> sẽ gộp tập tin khi trang jsp được chuyển thành servlet. Nếu tập tin được gộp không hay thay đổi thì ta nên dùng phương pháp này vì nó sẽ nhanh hơn về mặt hiệu năng (performance).
- hành động include <jsp:include ... /> sẽ thêm tập tin phát sinh vào trang jsp sau khi trang này được phát sinh. Ta nên dùng chọn lựa này nếu nội dung tập tin được gộp hay thay đổi.
Một cơ chế khác thự hiện việc gộp là việc dùng thẻ <c:import> của Thư Viện Thẻ Chuẩn JSTL (JavaServer pages Standard Tag Library)

Mã:
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<c:import url="../includes/header.jspf" />
* Chỉ thị taglib : khai báo việc dùng một thư viện thẻ trong trang. Cách khai báo khác (JSP 2.0):
Mã:
<jsp:root xmlns:c="http://java.sun.com/jsp/jstl/core" />
b. Có thể chèn mã Java vào trang JSP bằng cách dùng các thẻ sau:
* Thẻ khai báo (declaration) : cho phép thêm trực tiếp mã vào lớp servlet, định nghĩa các biến toàn cục hay tạo các phương thức. Ta ghi đè hai hàm jspInit và jspDestroy trong thẻ khai báo này.

Mã:
<%! ResourceBundle rb;

public void jspInit() {
  rb = ResourceBundle.getBundle("messages");
}%>
hay
Mã:
<jsp:declaration>
ResourceBundle rb;
public void jspInit() {
  rb = ResourceBundle.getBundle("messages");
}
</jsp:declaration>
* Thẻ văn lệnh con (scriptlet) : được dùng để chèn mã vào phương thức _jspService() của servlet. Nói chung là thành phần được sử dụng để chèn mã Java ngoại trừ các biến chung và phương thức.
Mã:
<%
session.setAttribute("user", null);
String sucessPath = rb.getString("process.logoff");
%>
hay
Mã:
<jsp:scriptlet>
session.setAttribute("user", null);
String sucessPath = rb.getString("process.logoff");
</jsp:scriptlet>
* Thẻ biểu thức (expression) : dùng để hiển thị kết quả của một biểu thức. Biểu thức này sẽ được chuyển làm tham số của một gọi hàm out.print() bên trong phương thức _jspService()
Mã:
<title><%=rb.getString("logoff.title")%></title>
hay
Mã:
<title><jsp:expression>rb.getString("logoff.title")</jsp:expression></title>
c. Các biến ngầm:
Trong một trang jsp ta có thể sử dụng các biến khai báo sẵn sau :
- request : đối tượng javax.servlet.http.HttpServletRequest
- response : đối tượng javax.servlet.http.HttpServletResponse
- out : đối tượng javax.servlet.jsp.JspWriter
- session : đối tượng javax.servlet.http.HttpSession
- application : đối tượng javax.servlet.ServletContext
- config : đối tượng avax.servlet.ServletConfig
- pageContext : đối tượng javax.servlet.jsp.PageContext
- page : là chính servlet

d. Các hành động của JSP (JSP actions) :
- jsp:include : đã trình bày phía trên
- jsp:aram : có thể được sử dụng trong jsp:include, jsp:forward, jsp:params. Nhằm xác định một thông số gởi kèm
- jsp:forward : chuyển truy vấn sang một servlet hay trang jsp khác.
Mã:
<jsp:forward page="<%=sucessPath%>" />
- jsp:plugin : thực thi hay hiển thị một đối tượng, đối tượng này có thể là một applet hay bean. Trong trả lời dưới dạng HTML, thì thẻ này được chuyển thành thẻ <object> hay <embed>
- jsp:fallback : nội dung hiển thị nếu phía khách không hỗ trợ applet, dùng kèm với jsp:plugin
- jsp:getProperty : lấy giá trị một thuộc tính của một JavaBean.

Mã:
<jsp:getProperty property="username" name="userBean" />
- jsp:setProperty : gán giá trị cho một thuộc tính của một JavaBean.
Mã:
<jsp:setProperty property="*" name="userBean" />
- jsp:useBean : khởi tạo hay tái sử dụng một JavaBean đã tồn tại để dùng trong trang jsp.
Mã:
<jsp:useBean id="userBean" class="com.openspace.UserService"
scope="session" />
4. Chú ý khi dùng JSP
Để phát triển các ứng dụng web dùng Servlet và JSP có chất lượng, có thể tái sử dụng và dễ dàng bảo trì ta cần lưu ý các điều sau :
- Không lạm dụng chèn nhiều mã Java trong trang HTML. Ta nên viết những tính toán, xử lý ... trong các lớp Java và ta sẽ gọi đến chúng trong trang jsp khi dùng.
- Khi lập trình dùng JSP, ta thường dùng đến mẫu thiết kế MVC (Model-View-Control : Tầng model - tầng View - tầng điều khiển) nên khi lập trình ta nên tách bạch 3 phần sau : phần mã trình bày (presentation) hay thiết kế (design), phần logic công việc hay dữ liệu và phần xử lý yêu cầu.


Lợi thế của JSP 

Dưới đây là các lợi thế của việc sử dụng JSP khi so sánh với các công nghệ khác:
  • So với Active Server Pages (ASP): Lợi thế của JSP có thể coi là gấp đôi. Đầu tiên, các phần động được viết bằng Java, không phải bằng Visual Basic hoặc ngôn ngữ MS khác, vì thế nó mạnh mẽ hơn và dễ dàng để sử dụng hơn. Thứ hai, nó thích hợp cho các Hệ điều hành khác, không chỉ là Microsoft Web Server.
  • So với Pure Servlets: Nó tiện lợi hơn khi viết (và sửa đổi) HTML, vì có nhiều lệnh printIn hơn.
  • So với Server-Side Includes (SSI): SSI chỉ dành cho các thể đơn giản, không dành cho các chương trình “thực” mà sử dụng Form Data, tạo kết nối Database.
  • So với JavaScript: JavaScript có thể tạo HTML động trên Client nhưng lại tương tác khó khan với Web Server để thực hiện các tác vụ phức tạp như truy cập Database và xử lý hình ảnh, …
  • Với Static HTML: Tất nhiên, HTML thông thường không thể chứa thông tin động.

Servlet

Servlets là gì?

Servlet được hiểu theo nhiều cách khác nhau, phụ thuộc vào ngữ cảnh.
Servlet là công nghệ được dùng để tạo ra ứng dụng webServlet là API cung cấp nhiều giao diện(interface) và lớp(class) cùng với tài liệu về chúng. Servlet API có rất nhiều giao diện và lớp như Servlet, GenericServlet, HttpServlet, ServletRequest, ServletResponse etc.Servlet là một interface và khi tạo bất kỳ servlet nào đều phải cài đặt giao diện nàyServlet là một lớp mà nó mở rộng khả năng của server và trả lời các yêu cầu(request) đến. Nó có thể trả lời bất kỳ loại yêu cầu nàoServlet là một web component được triển khai trên máy chủ để tạo ra trang web động.

lập trình java web

Hàm init() Khơi tạo 2 object là response http:request ( chỉ tạo 1 lần)

Cấu trúc của Servlets

Sơ đồ dưới đây minh họa cấu trúc của Servlets trong một ứng dụng web:
Cấu trúc Servlets

Ứng dụng web là gì?
Ứng dụng web là ứng dụng có thể truy cập từ web. Một ứng dụng web được tạo thành từ nhiều thành phần(web component) như Servlet, JSP, Filter, HTML,... Các thành phần web được thực thi phía Web Server và trả lời yêu cầu qua giao thức HTTP

Công nghệ CGI(Commmon Gateway Interface)
Công nghệ CGI cho phép máy chủ web gọi chương trình bên ngoài và chuyển thông tin yêu cầu tới một chương trình bên ngoài khác để xử lý. Với mỗi yêu cầu, chương trình CGI sẽ khởi tạo một tiến trình mới
lập trình java web ​
Nhược điểm của CGI
Công nghệ CGI vẫn tồn tại nhiều vấn đề:
1. Nếu số client tăng thì thời gian trả lời yêu cầu từ client tăng lên
2. Với mỗi yêu cầu, nó khởi tạo một tiến trình trong khi máy chủ Web bị hạn chế về tài nguyên
3. CGI sử dụng nền tảng phụ thuộc vào ngôn ngữ C,C++,perl.

Nhiệm vụ của Servlets

Servlets thực hiện các tác vụ chủ yếu sau:
  • Đọc dữ liệu hiển thị (explicit) được gửi bởi Client (hoặc trình duyệt) bao gồm một HTML Form trên một trang web hoặc nó cũng có thể từ một Applet hoặc một chương trình Custom từ HTTP Client.
  • Đọc dữ liệu yêu cầu HTTP ẩn (implicit) được gửi bởi Client (hoặc trình duyệt) bao gồm cookie, các loại media.
  • Xử lý dữ liệu và cho ra kết quả. Tiến trình này có thể yêu cầu Database, đang thực thi một triệu hồi tới RMI hoặc CORBA, triệu hồi một Web Service, hoặc tính toán phản hồi một cách trực tiếp.
  • Gửi dữ liệu hiển thị (ví dụ: tài liệu) tới các Client (hoặc trình duyệt). Tài liệu này có thể được gửi theo nhiều định dạng khác nhau, gồm text (HTML hoặc XML), nhị phân (hình ảnh GIF), Excel, .v.v.
  • Gửi phản hồi HTTP ẩn tới các Client (hoặc trình duyệt), thông báo cho trình duyệt hoặc Client về kiểu của tài liệu được trả về (ví dụ: HTML), thiết lập các Cookie và Caching các tham số, cùng các tác vụ khác.

Package trong Servlets

Java Servlets là các lớp trong Java chạy bởi một Web Server mà có một trình thông dịch hỗ trợ Java Servlets.
Servlets có thể được tạo bởi sử dụng các gói javax.servlet và javax.servlet.http là một phiên bản mở rộng của thư viện lớp Java để hỗ trợ các dự án phát triển có phạm vi lớn. Các lớp này triển khai Java Servlet và JSP.
Java Servlet đã được tạo và được biên dịch giống như các lớp khác trong Java. Sau khi bạn cài đặt các gói servlet và thêm chúng vào Classpath trong máy của bạn, bạn có thể biên dịch Servlet với bộ biên dịch JDK hoặc bất kỳ bộ biên dịch nào khác.
Ví dụ demo :

package vn.java;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
* Servlet implementation class Calc
*/
@WebServlet("/Calc")
public class Calc extends HttpServlet {
private static final long serialVersionUID = 1L;

/**
* @see HttpServlet#HttpServlet()
*/
public Calc() {
super();
// TODO Auto-generated constructor stub
}

/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub

String num1 = request.getParameter("num1");
String num2 = request.getParameter("num2");
int a = Integer.parseInt(num1);
int b = Integer.parseInt(num2);

int result = a + b;

try {
PrintWriter out = response.getWriter();
out.println("Result: " + result);
} catch (Exception e) {
// TODO: handle exception

}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
}
}

2. trang index.html 

<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<form action = "Calc" method = "get">
<br /> num1 <input type="text" name ="num1" />
<br /> num2 <input type="text" name ="num2" />
<br /> <input type="submit" name ="submit" value="Cal" />
</form>
</body>
</html>





Ưu điểm của Servlet
lập trình java web ​

Servlet có nhiều ưu điểm so với CGI. Web container tạo các thread(luồng) để xử lý nhiều yêu cầu gửi tới servlet. Thread có nhiều ưu điểm so với tiến trình(process) như chia sẻ bộ nhớ chung, lightweight, chi phí giao tiếp giữa các thread thấp. Những ưu điểm cơ bản của servlet cụ thể như sau:
Hiệu suất xử lý tốt hơn(better performance): vì nó tạo ra một thread cho một yêu cầu chứ không phải tiến trình.
Khả chuyển: bởi vì servlet được phát triển từ ngôn ngữ Java
Mạnh(Robust): Servlet được quản lý bởi JVM, JVM chủ động quản lý bộ nhớ và thu thập rác.

Không có nhận xét nào:

Đăng nhận xét