服務器通過配置文件將符合特定格式的
URL
同
Servlet
建立對應關系,當一個客戶端請求到達服務器的時候,服務器就會分析其
URL
格式并派發給合適的
Servlet
處理,然后將
Servlet
處理完成的結果返回給客戶。
與
ASP
、
PHP
等
Web
技術相比較,
Servlet
具有如下優勢:
可移植性:
Servlet
是由
Java
開發的,所以它可以在任何支持
Java
的操作系統下運行。
功能強大:
ASP
只能使用
ASP
內置的功能對象,要實現更復雜的功能必須調用用其他語言編寫的
COM
模塊;
PHP
也只能使用其內置的功能,要實現更復雜的功能也必須掛接其他模塊。由于
Servlet
本身是用
Java
語言編寫的,所以可以使用
Java
中所有的功能,這些功能包括圖像處理、文件處理、數據壓縮解壓、多線程、
JDBC
、
XML
、
EJB
、網絡訪問、加密解密等等。
開發方便:
Java
本身是高度類型安全的,而且有強大的
IDE
支持。
Servlet
也是一個普通的
Java
類,所以編寫
Servlet
的時候可以在開發時就發現程序中的錯誤,可以充分利用
IDE
提供的代碼自動完成、調試、重構等功能加快開發速度。
?
1.1
??
Servlet
Servlet
,全稱為
Java Servlet
,也被稱為
Java
服務器端小程序,是用
Java
編寫的服務器端程序,其主要功能在于交互式地瀏覽和修改數據,生成動態生成響應內容。
Servlet
是
Java
平臺下的
Web
服務器處理請求的基本單位,可以看做是
Java
版的
CGI
,但是其功能和性能比
CGI
更加強大。從實現上講,
Servlet
可以響應
Http
、
Ftp
等任何類型的請求,但絕大多數情況下
Servlet
只用來擴展基于
Http
協議的
Web
服務器。
所有
Servlet
必須實現
javax.servlet.Servlet
接口,如果僅僅編寫影響
Http
請求的
Servlet
的話從
javax.servlet.http.HttpServlet
派生即可,
HttpServlet
封裝了編寫基于
Http
協議的
Servlet
的大部分功能。一個簡單的
Servlet
如下:
package com.cownew.Char07;
?
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;
?
public class DemoServlet extends HttpServlet
{
???? protected void doGet(HttpServletRequest request,
????????????? HttpServletResponse response) throws ServletException, IOException
???? {
???????? doPost(request, response);
???? }
?
???? protected void doPost(HttpServletRequest request,
????????????? HttpServletResponse response) throws ServletException, IOException
???? {
???????? String userName = request.getParameter("userName");
???????? PrintWriter out = response.getWriter();
???????? out.println("<html>");
???????? out.println("<head>");
???????? out.println("<title>Welcome</title>");
???????? out.println("<body>");
???????? out.print("
你好
:");
???????? out.println(userName);
???????? out.println("</body>");
???????? out.println("</html>");
???? }
}
DemoServlet
覆蓋了父類中的兩個方法:
doGet
方法用來處理
Http Get
請求,
doPost
用來處理
Http Post
請求。在這里
doGet
調用
doPost
,也就是
doGet
和
doPost
進行同樣的處理。在
doPost
方法中,首先獲得
PrintWriter
對象,然后調用
PrintWriter
的
println
等方法將要返回給客戶端的
HTML
文件輸出出來
。
前面提到,每個
Servlet
都通過一定的
URL
規則與特定的請求相關聯,因此在開發完畢
Servlet
后必須指定這些關聯關系。關聯的方法非常簡單,只要在對應項目下的
web.xml
中添加如下內容即可
:
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4"
???? xmlns="http://java.sun.com/xml/ns/j2ee"
???? xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
???? xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
???? <display-name>CowNewPIS</display-name>
……
???? <servlet>
???????? <servlet-name>DemoServlet</servlet-name>
???????? <servlet-class>
????????????? com.cownew.Char07.DemoServlet
???????? </servlet-class>
???? </servlet>
???? <servlet-mapping>
???????? <servlet-name>DemoServlet</servlet-name>
???????? <url-pattern>/DemoServlet</url-pattern>
???? </servlet-mapping>
……
</web-app>
在
web.xml
中,首先聲明
Servlet
,指定這個
Servlet
的名字和對應的
Java
類,然后在
servlet-mapping
標簽中為這個
Servlet
進行映射,以后所有符合“
/DemoServlet
”格式的請求都會被派發給
DemoServlet
處理。
Servlet
是
Web
開發的基礎,因此讀者有必要對
Servlet
的整體框架有一個較全面的了解。
Servlet
相關的類與接口主要包括如下幾類:
Servlet
接口及其實現類;
Servlet
配置相關類與接口;請求和響應相關類與接口
;
過濾與監聽。
Servlet
接口及其實現類
(
1
)
javax.servlet.Servlet
這個接口是所有
Servlet
必須實現的接口,它定義了如下幾個方法:
void init(ServletConfig servletconfig)
:用戶初始化
Servlet
;
ServletConfig getServletConfig()
:獲得
Servlet
配置相關的信息;
void
service??? (ServletRequest request, ServletResponse response)
:響應客戶端請求的入口點,
request
表示客戶端請求的信息,
response
表示對客戶端的響應信息;
String getServletInfo()
:獲得
Servlet
的描述信息;
void destroy()
:銷毀
Servlet
;
?
(2)
javax.servlet.GenericServlet
它是一個抽象類,提供了對
Servlet
接口的默認實現,并且實現了
ServletConfig
等接口
。
(3)
javax.servlet.http.HttpServlet
這個類是針對
Http
請求的
Servlet
類,提供了對
Http
協議的響應功能,它從
GenericServlet
繼承,大部分
Servlet
從它派生即可。其定義很多方法,子類可以根據需要有選擇性的覆蓋:
void doGet(HttpServletRequest req, HttpServletResponse resp)
:響應客戶端的
Get
調用請求;
void doPost(HttpServletRequest req, HttpServletResponse resp)
:響應客戶端的
Post
調用請求;
void doPut(HttpServletRequest req, HttpServletResponse resp)
:響應客戶端的
Put
調用請求;
void
doDelete(HttpServletRequest req, HttpServletResponse resp)
:響應客戶端的
Delete
調用請求,客戶端會請求此調用以刪除服務端的某個文件,一般直接使用默認實現即可;
void
doTrace(HttpServletRequest req, HttpServletResponse resp)
:響應客戶端的
Trace
調用請求,一般只有開發調試的時候才會調用此方法,一般直接使用默認實現即可;
void doHead(HttpServletRequest req, HttpServletResponse resp)
:響應客戶端的
Head
調用請求。當客戶端只需要知道響應的
Head
時,它就會發出
Head
請求。比如在“斷點續傳”等技術中客戶端就往往只關心響應的長度。
void doOptions(HttpServletRequest req, HttpServletResponse resp)
:響應客戶端的
Options
調用請求。客戶端可以通過此調用得知此
Servlet
支持的調用方式。
doOptions
的默認實現是根據當前類是否覆蓋了
HttpServlet
的相應方法來得到
Servlet
支持的調用類型的,比如
Servlet
覆蓋了
doPost
方法,那么就認為
Servlet
支持
POST
調用,一般情況下無需覆蓋這個方法。
Servlet
配置相關類與接口
javax.servlet.ServletConfig
接口代表了
Servlet
的配置,一個典型的
Servlet
配置如下:
<servlet>
???? <servlet-name>action</servlet-name>
???? <servlet-class>
???????? org.apache.struts.action.ActionServlet
???? </servlet-class>
???? <init-param>
???????? <param-name>application</param-name>
???????? <param-value>ApplicationResources</param-value>
???? </init-param>
???? <init-param>
???????? <param-name>config</param-name>
???????? <param-value>/WEB-INF/struts-config.xml</param-value>
???? </init-param>
???? <init-param>
???????? <param-name>debug</param-name>
???????? <param-value>2</param-value>
???? </init-param>
???? <load-on-startup>2</load-on-startup>
</servlet>
配置文件中描述了
Servlet
的名字,
Servlet
的初始化參數等信息。
ServletConfig
接口主要方法有以下幾個:
String getServletName()
:獲得
Servlet
的名字
;
ServletContext getServletContext()
:獲得
Servlet
的上下文
;
String getInitParameter(String string)
:獲得初始化參數值,比如在上邊的配置文件中,
getInitParameter(“application”)
將返回字符串“
ApplicationResources
”
;
Enumeration getInitParameterNames()
:返回所有的初始化參數的名字的枚舉器
;
?
javax.servlet.http.HttpServletRequest
這個接口代表了
Http
請求,它從接口
javax.servlet.ServletRequest
擴展而來。我們從這個接口中獲得請求參數的值、客戶機的信息、服務器的信息、請求的信息等。接口還提供了獲取客戶端請求數據流的方法,不過只有當客戶端的提交方式為
Post
或者
Put
的時候才會有效。
JSP
中的內置對象
request
就是
HttpServletRequest
的對象,其主要方法如下:
String getAuthType()
:獲得認證類型
;
Cookie[] getCookies()
:獲得客戶端發送的所有
Cookie
;
long getDateHeader(String string)
:獲得日期類型的頭信息值
;
String getHeader(String string)
:獲得字符串類型的頭信息值
;
Enumeration getHeaders(String string)
:獲得所有頭信息值
;
Enumeration getHeaderNames()
:獲得所有頭信息名
;
int getIntHeader(String string)
:獲得整形的頭信息值
;
String getMethod()
:獲得提交方式,一般是
Get
、
Post
、
Put
等
;
String getPathInfo()
:獲得請求路徑
;
String getPathTranslated()
:獲得翻譯以后的請求路徑
;
String getContextPath()
:獲得上下文路徑
;
String getQueryString()
:獲得原始的查詢字符串
;
String getRequestedSessionId():
獲得
Web Session
唯一標識
;
HttpSession getSession()
:獲得客戶端
Session
,如果沒有分配
Session
則返回
null
;
HttpSession getSession(boolean create)
:獲得客戶端
Session
,和上一個方法不同的是,如果沒有分配
Session
的時候如果
create
參數為
true
的話則分配一個
Session
對象
;
Object getAttribute(String string)
:獲得屬性值,這些值是服務端放置進去的,和客戶端沒有直接關系,這個方法和下面提到的
getParameter
方法沒有直接關系
;
void setAttribute(String key, Object value)
:設定屬性值
;
Enumeration getAttributeNames()
:獲得所有的屬性名
;
void setCharacterEncoding(String encoding)
:設定編碼方式
;
ServletInputStream getInputStream()
:獲得客戶端數據流
;
String getParameter(String key)
:獲得請求參數值
;
Enumeration getParameterNames()
:獲得所有的請求參數名
;
?
javax.servlet.http.HttpServletResponse
這個接口代表了服務器對客戶端的
Http
響應,它從接口
javax.servlet.ServletResponse
擴展而來。我們通過這個接口設置響應的數據、
MIME
類型等。
JSP
中的內置對象
reponse
就是
HttpServletResponse
的對象,其主要方法如下:
void addCookie(Cookie cookie)
:為客戶端添加
Cookie
;
String encodeURL(String url)
:使用
URL
和
SessionId
重寫這個
URL
;
void sendRedirect(String url)
:把響應發送到另一個
JSP
頁面或者
Servlet
進行處理
;
ServletOutputStream getOutputStream()
:獲得響應輸出流對象
;
void setContentType(String string);
:設定響應的
MIME
類型,當向客戶端發送圖片、
Excel
文件等特殊文件的時候非常有用
;
void setCharacterEncoding(String encoding)
:設定響應的編碼方式
;
javax.servlet.Filter
Servlet
中的
Filter
技術在有的情況下能極大的簡化開發任務,使用
Filter
可以在一個地方集中處理編碼、權限控制等問題。
Filter
接口的實現如下:
void init(FilterConfig filterconfig)
:初始化
Filter
;
doFilter?? (ServletRequest request, ServletResponse response,FilterChain chain)
:這個方法是
Filter
的核心方法,進行過濾的業務邏輯要在這個方法中完成
;
void destroy()
:銷毀
Filter
;
javax.servlet.FilterChain
Servlet
中常常有多個
Filter
,這些
Filter
互相協作來完成任務,這些
Filter
組成一個有前后關系的鏈,這是“責任鏈”模式的典型應用。
FilterChain
接口僅僅定義了一個方法:
public void doFilter(ServletRequest request, ServletResponse response)
通過這個方法來調用下一個
Filter
,如果沒有下一個
Filter
,則調用目標資源。
?
1.2
??
JSP
Servlet
是
Web
開發的基石,不過
Servlet
的缺點是明顯的。所有的業務邏輯、
HTML
格式內容等全部要由
Servlet
輸出,必須在
Servlet
中放置大量的
println
語句來輸出頁面,當頁面太復雜的時候就會將開發人員搞暈。而且基本的
HTML
格式變化都必須在
Java
代碼中修改,這意味著不熟悉
Java
語言的美工人員不能直接進行頁面美工設計。
為了克服上述問題,
JSP
(
Java Server Pages
)技術應運而生。
JSP
是一種動態生成
HTML
、
XML
或其他格式的
Web
網頁的技術標準。
JSP
技術是以
Java
語言作為腳本語言的,
JSP
網頁為整個服務器端的
Java
庫單元提供了一個接口來服務于
HTTP
的應用程序。
JSP
使得開發人員在享受
Servlet
的優點的同時,使得
HTML
頁面的創建更加容易。
下面演示了一個簡單的
JSP
頁面
:
<%@ page language="java" contentType="text/html; charset=GB2312"
??? pageEncoding="GB18030"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<%@page import="java.util.Date"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=GB2312">
<title>Welcome</title>
</head>
<body>
<%
???? for(int i=0;i<3;i++)
???? {
????????
????
%>
???? <%=i %>
???? <%=new Date(i).toLocaleString()%><br/>
<%
???? }
%>
?
</body>
</html>
當瀏覽器向服務器請求
JSPDemo.jsp
的時候,服務器的
JSP
編譯器就會啟動將
JSP
編譯為
Java
源文件,該源文件定義了一個獨立的類,類的名字依賴于源文件的名字。
比如在
Tomcat
服務器中會將
JSPDemo.jsp
轉換成名稱為
JSPDemo_jsp.java
的
Java
源文件,其內容如下:
package org.apache.jsp.Demo.Char07;
?
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;
import java.util.Date;
?
public final class JSPDemo_jsp extends org.apache.jasper.runtime.HttpJspBase
??? implements org.apache.jasper.runtime.JspSourceDependent {
?
? private static java.util.Vector _jspx_dependants;
?
? public java.util.List getDependants() {
??? return _jspx_dependants;
? }
?
? public void _jspService(HttpServletRequest request, HttpServletResponse response)
??????? throws java.io.IOException, ServletException {
?
??? JspFactory _jspxFactory = null;
??? PageContext pageContext = null;
??? HttpSession session = null;
??? ServletContext application = null;
??? ServletConfig config = null;
??? JspWriter out = null;
??? Object page = this;
??? JspWriter _jspx_out = null;
??? PageContext _jspx_page_context = null;
?
?
??? try {
????? _jspxFactory = JspFactory.getDefaultFactory();
????? response.setContentType("text/html; charset=GB2312");
????? pageContext = _jspxFactory.getPageContext(this, request, response,
?????
???????????? null, true, 8192, true);
????? _jspx_page_context = pageContext;
????? application = pageContext.getServletContext();
????? config = pageContext.getServletConfig();
????? session = pageContext.getSession();
????? out = pageContext.getOut();
????? _jspx_out = out;
?
????? out.write("\n");
????? out.write("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\n");
????? out.write("\r\n");
????? out.write("<html>\n");
????? out.write("<head>\n");
????? out.write(
"<meta http-equiv=\"Content-Type\" content=\"text/html; charset=GB2312\">\n");
????? out.write("<title>Welcome</title>\n");
????? out.write("</head>\n");
????? out.write("<body>\r\n");
?
???? for(int i=0;i<3;i++)
???? {
????????
????
?
????? out.write('\r');
????? out.write('\n');
????? out.write('? ');
????? out.print(i );
????? out.write('\r');
????? out.write('\n');
????? out.write('? ');
????? out.print(new Date(i).toLocaleString());
????? out.write("<br/>\r\n");
?
???? }
?
????? out.write("\n");
????? out.write("\n");
????? out.write("</body>\n");
????? out.write("</html>");
??? } catch (Throwable t) {
????? if (!(t instanceof SkipPageException)){
??????? out = _jspx_out;
??????? if (out != null && out.getBufferSize() != 0)
????????? out.clearBuffer();
??????? if (_jspx_page_context != null) _jspx_page_context.handlePageException(t);
????? }
??? } finally {
????? if (_jspxFactory != null) _jspxFactory.releasePageContext(_jspx_page_context);
??? }
? }
}
可以看到編譯以后的結果和編譯前的形式有很大不同
,
編譯之前的
JSP
文件好像將
Java
嵌入了
HTML
中,而編譯之后則是將
HTML
嵌入了
Java
代碼中。
JSP
文件被轉換成
Java
源文件以后會繼續被編譯為二進制字節碼,同時類中的
jspService
方法在調用的時候會傳入請求和響應對象。
JSP
具有如下的優點:
業務邏輯和頁面顯示相分離
使用
JSP
技術,
Web
頁面美工人員可以使用
HTML
來設計頁面,很顯然
JSP
的開發方式使得代碼變得更加簡潔了,同時美工人員可以按照美化的要求進行頁面設計,然后開發人員則可以在頁面的基礎上編寫邏輯代碼,二者互相協作而有不互相影響。
提高了可重用性
使用
JSP
,我們可以使用可重用的組件(比如
EJB
、
JMS
等)來執行應用程序所要求的更為復雜的業務邏輯。開發人員能夠共享通用的組件,或者使得自己開發的組件被其他人使用。這種開發方式加速了系統的開發過程,使得團隊中每個人的工作成果得到了最大程度的利用。
使用標簽語言簡化頁面開發
JSP2.0
中加入了標簽語言,這使得不懂
Java
的人員也能編寫
JSP
頁面,
Web
頁面美工人員無需熟悉腳本語言,
JSP
將這些功能封裝起來,使得功能的實現更加簡單、方便。
JSP
標簽能夠訪問和實例化
JavaBean
、描繪表單、插入
Flash
等,甚至能夠采用無
Java
代碼的方式訪問數據庫。而且標簽語言支持擴展,這樣第三方開發人員可以將常用的功能封裝為標簽。這樣
Web
頁面美工人員能夠使用這些標簽完成特定的功能。
擁有
Java
語言的所有優點
由于
JSP
頁面的內置腳本本質上就是
Java
語言,并且所有的
JSP
頁面也會被編譯成
Servlet
,所以
JSP
頁面就具有
Java
的所有優點,包括跨平臺、高安全性等。
支持
JSP
的服務器非常多
目前有很多支持
JSP
的服務器,比如
Tomcat
、
Resin
、
Apusic
等,甚至一些非
J2EE
相關的服務器也能支持
JSP
,比如
Windows
下的
IIS
只要安裝
JRun
、
ServletExec
等插件就可以運行
JSP
,著名的
Web
服務器
Apache
也內置了對
JSP
的支持,而
Apache
本身是可以運行在
Windows
、
Unix
、
Linux
等主流平臺上的,因此
JSP
有非常廣泛的平臺支持。
?
內嵌標簽
內嵌標簽為開發人員提供了基本的功能,所有的內嵌標簽以
jsp
最為前綴,最常用的內嵌標簽包括:
<jsp:param>
、
<jsp:include>
、
<jsp:forward>
、
<jsp:setProperty>
、
<jsp:getProperty>
、
<jsp:useBean>
、
<jsp:plugin>
、
<jsp:fallback>
、
<jsp:params>
。
(
1
)
<jsp:param>
<jsp:param>
標簽用來以“名值對”的形式為其他標簽提供附加信息,它不能單獨使用,必須和
<jsp:include>
、
<jsp:forward>
、
<jsp:plugin>
等標簽協作使用。
(
2
)
<jsp:include>
<jsp:include>
標簽用來在頁面中包含其他靜態或者動態資源。被包含的對象只有對
JspWriter
對象
out
的訪問權,不能設置消息頭或者設置
Cookie
。
<jsp:include>
標簽使用方式如下:
<jsp:include page=
”
ad.htm
”
/>
<jsp:include page=
”
showUser.jsp
”
>
<jsp:param name=
”
userName
”
value=
”
admin
”
/>
</jsp:include>
?
<jsp:include>
標簽允許動態增加靜態資源和動態資源。如果被包含的資源是靜態的,那么被包含的資源僅僅是被添加到
JSP
文件中;如果被包含的資源是動態的,那么這些資源將會被執行,我們可以使用
<jsp:param>
為動態資源傳遞參數名和參數值。
我們來看一個具體的例子:
ShowInfo.jsp
是用來顯示用戶名和密碼,用戶名和密碼通過參數設置:
<%
???? String userName = request.getParameter("userName");
???? String password = request.getParameter("password");
%>
UserName:<%=userName%><br/>
Password:<%=password%>
IncludeTest.jsp
中使用
<jsp:include>
標簽引用
ShowInfo.jsp
,并使用
<jsp:param>
標簽為兩個參數設置參數值。
<%@ page language="java" contentType="text/html; charset=gb2312"
??? pageEncoding="gb2312"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
</head>
<body>
<jsp:include flush="true" page="ShowInfo.jsp">
???? <jsp:param name="userName" value="<%=request.getParameter("userName") %>"/>
???? <jsp:param name="password" value="123456"/>
</jsp:include>
</body>
</html>
執行的效果如圖所示:
圖
7
.
1
從上邊的例子可以看出使用
<jsp:param>
標簽不僅能夠設置靜態的值還可以設置靜態的值。
與
<%@page include%>
指令相比,
<jsp:include>
標簽效率比較低,不過
<jsp:include>
標簽能夠動態增加內容,而
<%@page include%>
包含的內容則是固定不變的,一經編譯就不能改變。
(
3
)
<jsp:forward>
<jsp:forward>
標簽能夠將請求轉發到另一個
JSP
、
Servlet
或者靜態資源。被轉向的目標資源必須位于與
JSP
相同的上下文環境中,也就是不能轉向服務器的其他上下問中,更不能轉向外部網站上的資源。
?????? <jsp:forward>
的使用和
<jsp:include>
是類似的,比如:
<jsp:forward page=
”
newpage.jsp
”
>
???? <jsp:param name=
”
userId
”
value=
”
admin
”
/>
</jsp:forward>
(
4
)
<jsp:setProperty>
<jsp:setProperty>
標簽用戶設置
Bean
的屬性,此標簽要和
<jsp:useBean
一起使用
>
。
(
5
)
<jsp:getProperty>
<jsp:getProperty>
標簽可以訪問一個
Bean
的屬性,它會調用對象的
toString
方法,將得到的字符串返回值發送到輸出流中。使用方式如下:
<jsp:getProperty name=”myBean” property=”number”/>
(
6
)
<jsp:useBean>
<jsp:useBean>
標簽用來在
JSP
頁面內創建一個
Bean
實例,并指定實例的名字以及作用范圍。使用方法如下:
?????? <jsp:useBean id=”varId” scope=”page|request|session|application” class=”classType”/>
id
屬性用于設置實例的
ID
,
ID
的名稱是大小寫敏感的。當需要這個
Bean
實例的時候,會通過此
ID
對實例進行引用。
scope
屬性用于設置實例的存在的范圍,它有如下取值“
page|request|session|application
”,默認值為
page
。
page
表示實例在此
JSP
以及此文件中的所有靜態包含文件中使用,直到頁面執行完畢向客戶端發送響應或者轉向另一個資源為止;
request
表示實例在請求的范圍內有效,可以使用
request
對象訪問此實例,比如
request.getAttribute(“varId”)
;
session
表示實例在
Session
有效范圍內使用,可以使用
session
對象訪問
Bean
,比如
session.getAttribute(“varId”)
;
application
表示實例在整個
application
聲明周期內有效,可以使用
application
對象訪問此實例,比如
application.getAttribute(“varId”)
。
class
屬性表示實例的類型。
(
7
)
<jsp:plugin>
<jsp:plugin>
標簽用來產生在客戶端瀏覽器中插入
Applet
或者
JavaBean
的特別標簽(
<Object>
或者
<Embed>
),
<jsp:plugin>
會根據瀏覽器的版本來決定生成
<Object>
元素還是
<Embed>
元素。
使用方法如下:
<jsp:plugin type = applet code =
“
com.cownew.test.MyApplet.class
”
codebase=
”
.
”
>
???? <jsp:params>
???????? <jsp:param name=
”
paramName
”
value=
”
paramValue
”
/>
???? </jsp:params>
???? <jsp:fallback>
???????? <p>
插件加載失敗!
</p>
???? </jsp:fallback>
</jsp:plugin>
type
屬性表示被插入插件的類型,可選值為
applet
與
bean
。
code
屬性表示將執行的
Java
類文件的名稱,名稱需要包含擴展名,而且必須存在于
codebase
屬性指明的目錄下。
codebase
屬性為包含插件將運行的
Java
類的路徑,默認為此
JSP
文件的當前路徑。
?
<jsp:params>
標簽用來向
Applet
或者
Bean
傳遞參數值。
<jsp:fallback>
用于
Java
插件不能正常啟動時顯示給用戶的信息。
下面看一個具體的例子,首先開發一個簡單的
Applet
,這個
Applet
代碼如下:
package com.cownew.Char07;
?
import java.awt.BorderLayout;
import javax.swing.JPanel;
import javax.swing.JApplet;
import javax.swing.JTextField;
?
public class MyApplet extends JApplet
{
???? private JPanel jContentPane = null;
???? private JTextField jTextField = null;
?
???? public void init()
???? {
???????? this.setSize(300, 200);
???????? this.setContentPane(getJContentPane());
???? }
?
???? private JPanel getJContentPane()
???? {
???????? if (jContentPane == null)
???????? {
????????????? jContentPane = new JPanel();
????????????? jContentPane.setLayout(new BorderLayout());
????????????? jContentPane.add(getJTextField(), BorderLayout.CENTER);
???????? }
???????? return jContentPane;
???? }
?
???? private JTextField getJTextField()
???? {
???????? if (jTextField == null)
???????? {
????????????? jTextField = new JTextField();
????????????? jTextField.setText(getParameter("word"));
???????? }
???????? return jTextField;
???? }
}
在
init
方法中構建界面,在
getJTextField
方法中通過
Applet
類的
getParameter
得到參數“
word
”的值,并賦值給
jTextField
的
text
屬性。
接著編寫使用此
Applet
的
JSP
頁面:
<%@ page language="java" contentType="text/html; charset=GB18030"
???? pageEncoding="GB18030"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=GB18030">
<title>Insert title here</title>
</head>
<body>
<jsp:plugin code="com.cownew.Char07.MyApplet.class" codebase="."
???? type="applet" width="200" height="200" align="middle">
???? <jsp:params>
???????? <jsp:param name="word" value="2008" />
???? </jsp:params>
???? <jsp:fallback>
顯示
Applet
錯誤
</jsp:fallback>
</jsp:plugin>
<jsp:plugin code="com.cownew.Char07.MyApplet.class" codebase="."
???? type="applet" width="200" height="200" align="middle">
???? <jsp:params>
???????? <jsp:param name="word" value="welcome to BeiJing!" />
???? </jsp:params>
???? <jsp:fallback>
顯示
Applet
錯誤
</jsp:fallback>
</jsp:plugin>
</body>
</html>
?
運行以后效果如圖
:
圖
7
.
2
<jsp:plugin>
對于不同的瀏覽器會生成不同的
HTML
代碼,比如對于
IE6
生成的代碼如下:
?
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=GB18030">
<title>Insert title here</title>
</head>
<body>
<OBJECT classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93" width="200" height="200" align="middle" codebase="http://java.sun.com/products/plugin/1.2.2/jinstall-1_2_2-win.cab#Version=1,2,2,0">
<PARAM name="java_code" value="com.cownew.Char07.MyApplet.class">
<PARAM name="java_codebase" value=".">
<PARAM name="type" value="application/x-java-applet;">
<PARAM name="word" value="2008">
<COMMENT>
<EMBED type="application/x-java-applet;" width="200" height="200" align="middle" pluginspage="http://java.sun.com/products/plugin/" java_code="com.cownew.Char07.MyApplet.class" java_codebase="." word="2008"/>
<NOEMBED>
顯示
Applet
錯誤
</NOEMBED>
</COMMENT>
</OBJECT>
?
<OBJECT classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93" width="200" height="200" align="middle" codebase="http://java.sun.com/products/plugin/1.2.2/jinstall-1_2_2-win.cab#Version=1,2,2,0">
<PARAM name="java_code" value="com.cownew.Char07.MyApplet.class">
<PARAM name="java_codebase" value=".">
<PARAM name="type" value="application/x-java-applet;">
<PARAM name="word" value="welcome to BeiJing!">
<COMMENT>
<EMBED type="application/x-java-applet;" width="200" height="200" align="middle" pluginspage="http://java.sun.com/products/plugin/" java_code="com.cownew.Char07.MyApplet.class" java_codebase="." word="welcome to BeiJing!"/>
<NOEMBED>
顯示
Applet
錯誤
</NOEMBED>
</COMMENT>
</OBJECT>
</body>
</html>
JSTL
JSP
內置的標簽提供的功能是非常有限的,因此在
JSP1.1
中開始支持自定義標簽,但是自定義標簽的廣泛使用也造成了開發人員工作的重復,這就促成了
JSTL
(
JavaServer Pages Standard Tag Library
,
JSP
標準標簽庫)的誕生。
JSTL
封裝了
JSP
開發中常用的功能,這樣開發人員就可以以同一的方式來避免
JSP
中
Scriptlets
,甚至可以達到沒有任何
Scriptlets
代碼的目標。由于
JSTL
是標準的、統一的,所以很多
IDE
都支持以可視化的方式編輯含有
JSTL
標簽的頁面,這進一步無疑加快了開發效率。
JSTL
包含的功能是非常全面的,不僅包含數據輸出、
bean
操作、條件判斷,而且還包括
XML
解析和
JDBC
操作。由于直接使用
JSTL
進行
XML
解析和
JDBC
操作并不符合正規項目的分層開發思想,所以這里將不會介紹
JSTL
中
XML
解析、
JDBC
操作等標簽,有興趣的讀者可以參考相關資料進一步研究。
(
1
)
<c:out>
?????? <c:out>
標簽用于將計算的結果輸出到頁面中。比如:
?????? <c:out value=”${age}”/>
??????
其中的“
${age}
”是被稱作“表達式語言”,如果在頁面上下文、
Request
、
Session
、
Application
等對象中有
age
屬性的話,使用“
${age}
”將會獲得這個屬性的值。
(
2
)
<c:set>
?????? <c:out>
標簽用于在特定范圍內(
Page
、
Request
、
Session
、
Application
等)中設定某個屬性值,可以用來設置特定
bean
的值。
(
3
)
<c:remove>
?????? <c:remove>
標簽用于在特定范圍內(
Page
、
Request
、
Session
、
Application
等)刪除某個屬性值。語法如下:
?????? <c:remove var=”varName” scope=”page|request|session|application”/>
(
4
)
<c:if>
?????? <c:if>
標簽用于進行條件判斷,如果其
test
屬性計算結果為
true
,則計算其
Body
。比如:
<c:if test=”${isLogin}”>
?
歡迎光臨
</c:if>
(
5
)
<c:forEach>
?????? <c:forEach>
用來迭代集合對象,并計算它的
Body
或者重復迭代固定的次數。比如:
<c:forEach var=”user” items=”${userList}”>
??????
用戶名:
<c:out value=”${user.name}”/>
??????
密碼:
<c:out value=”${user.password}”/>
</c:forEach>
items
屬性表示被迭代的集合對象,
var
為訪問每個元素時所用的名稱。
Struts
標簽庫
做為最為成熟的
Web
框架之一的
Struts
也提供了一組非常豐富的標簽庫,這些標簽庫有的和
Struts
結合的非常緊密,有的則完全可以脫離
Struts
框架而運行。
Struts
提供的標簽庫主要分成如下幾類:
HTML
標簽庫、
Bean
標簽庫、
Logic
標簽庫、
Template
標簽庫、
Titles
標簽庫、
Nested
標簽庫。
HTML
標簽庫
HTML
標簽庫包含了創建
HTML
頁面的常用標簽,其中最重要的就是
Form
相關標簽,只有使用
Form
標簽才能使得表單與
Struts
緊密結合工作。當使用
Struts
的時候,必須將整個頁面用
<html:html>
標簽包圍起來。頁面內的表單等也要使用
Struts
提供的標簽。常用的標簽有:代表表單的
<html:form>
、代表按鈕的
<html:button>
、代表復選框的
<html:checkbox>
、代表文件輸入框的
<html:file>
、代表隱藏表單的
<html:hidden>
、代表圖片的
<html:img>
、代表超鏈接的
<html:link>
、代表密碼框的
<html:password>
、代表單選按鈕的
<html:radio>
、代表多行文本框的
<html:textarea>
、代表提交按鈕的
<html:submit>
。
Bean
標簽庫
Bean
標簽庫為訪問
Bean
提供了方便,此外
Bean
標簽庫也提供了訪問
Cookie
、信息頭、
Request
等的標簽。主要包括:訪問
Cookie
的
<bean:cookie>
、訪問信息頭的
<bean:header>
、進行頁面裝載的
<bean:include>
、將
bean
定義為表達式變量的
<bean:define>
。
Logic
標簽庫
Logic
標簽庫主要用于條件輸出、對象迭代。這部分功能和
JSTL
中的邏輯控制標簽庫是類似的,不過
Struts
的
Logic
標簽庫更加方便易用,而且和
Struts
框架的結合也更加緊密。主要包括:
<logic:empty>
、
<logic:equal>
、
<logic:greaterThan>
、
<logic:lessEqual>
、
<logic:match>
、
<logic:notEmpty>
、
<logic:notEqual>
、
<logic:present>
、
<logic:notPresent>
。