注:本文假設你已經成功安裝了Eclipse的tomcat插件sysdeo!
首先創建Tomcat工程:File->New->Other下選擇Tomcat Project(圖1)
工程名稱輸入為connMysql(圖2)
為方便這里選擇can upDate server.xml file(默認值),點擊Finish完成工程文件的創建(圖3)在connMysql工程中創建java文件。選中connMysql從File->New點擊Class(圖4)在Package中輸入test,Name輸入為sqlBean,其它為默認,完成文件創建。sqlBean文件代碼如下:
package test;
import java.sql.Connection;
import java.sql.DriverManager;
//sqlBean為一抽象函數,實現數據連接及關閉功能
public abstract class sqlBean {
private String myDriver= "org.gjt.mm.mysql.Driver";
private String my
protected Connection myConn;
public sqlBean(){}
public Void makeConnection() throws Exception{
Class.forName(myDriver).newInstance();
myConn= DriverManager.getConnection(myURL);
}
public abstract void cleanup() throws Exception;
public void takeDown() throws Exception{
cleanup();
myConn.close();
}
}
同樣的方法創建dbBean文件。dbBean文件代碼如下:
package test;
import java.sql.ResultSet;
import java.sql.Statement;
//dbBean繼承自sqlBean實現取數據
public class dbBean extends sqlBean{
String mySQL= "select operatorno,operatorname,description from operator";
ResultSet myResuleSet= null;
Statement stmt= null;
public dbBean(){
super();
}
public Boolean getNextDB() throws Exception{
return myResuleSet.next();
}
public String getColumn(String inCol) throws Exception{
return myResuleSet.getString(inCol);
}
public boolean getData() throws Exception{
String myQuery= mySQL;
stmt= myConn.createStatement();
myResuleSet= stmt.executeQuery(myQuery);
return (myResuleSet!= null);
}
public void cleanup() throws Exception{
stmt.close();
}
}
接下來創建調用這個Bean的JSP文件。這時要注意選中工程文件connMysql然后再創建JSP文件,這樣文件直接被創建在connMysql目錄下,方便調用。File->New->File(圖5)
JSP文件dbquery.jsp文件代碼為:
HTML PUBLIC "-//w3c//dtd html 4.0 transitional//en">
<head>
<%@ page language="java" %>
<%@ page import= "java.sql.*"%>
<%@ page contentType= "text/html;charset=utf-8"%>
</head>
<body bgcolor="#FFFFFF">
<table border="1" width="400">
<tr>
<td>NO</td><td>NAME</td><td>DESCRIPTION</td>
</tr>
<%
dbbean.makeConnection();
if(dbbean.getData()){
while(dbbean.getNextDB()){
String no= dbbean.getColumn("operatorno");
String name= dbbean.getColumn("operatorname");
String desc= dbbean.getColumn("description");
%>
<tr>
<td><%=no%></td>
<td><%=name%></td>
<td><%=desc%></td>
</tr>
<%
}
}
dbbean.takeDown();
%>
</table>
</body>
到這里基本代碼已經完成,但還有很重要的一步,因為這個程序中我們用到了JdbcMysql所以還要把JdbcMysql.jar文件拷貝到WEB-INF目錄(Eclipse程序自動創建的)下,否則調用JSP文件時會出現ClassNotFound錯誤信息。剛開始我以為Eclipse很智能地把文件包含進去呢,因為在Project的Liberaries里我包含了這個Jar文件,誰知結果不是這樣,郁悶了我半天。
好了,保存文件,點擊Eclipse界面上的那個小老虎圖標啟動Tomcat(圖6)在瀏覽器中輸入http://localhost:8080/connMysql/dbquery.jsp,哈哈,大功告成!
posted @
2007-08-31 10:45 jadmin 閱讀(60) |
評論 (0) |
編輯 收藏
/**
* @author ××× E-mail:JStudio@qq.com
* @version 創建時間:2007-8-30 下午04:58:52
* 類說明
*/
window->preference->java->code???? styple->code???? template 當你選擇到這部的時候就會看見右側有一個框顯示出code這個選項,你點開這個選項,點一下他下面的New Java??? files 然后你點edit按鈕,把他的內容換成你的就可以了:(例如)
${filecomment}
${package_declaration}
/**
* @author ××× E-mail:JStudio@qq.com
* @version 創建時間:${date} ${time}
* 類說明
*/
${typecomment}
${type_declaration}
最后點apply ----> OK 成功。。
posted @
2007-08-30 20:00 jadmin 閱讀(143) |
評論 (0) |
編輯 收藏
http://www.google.com/microsoft
微軟風格的入口
http://www.google.com/mac
MAC風格的入口
http://www.google.com/linux
Linux風格的入口
http://www.google.com/bsd
FreeBSD風格的入口
Google有各種語言的版本,下面這些語言可能實在是稀罕了點兒
http://www.google.com/intl/xx-klingon/
克林岡語入口(沒看過星際旅行嗎?)
http://www.google.com/intl/xx-bork/
政治入口?
http://www.google.com/intl/xx-elmer/
宗教入口
http://www.google.com/intl/xx-piglatin/
小豬入口
http://www.google.com/intl/xx-hacker/
黑客專用入口
Google里還有一個小小的彩蛋游戲,大家自己去看吧!
http://www.google.com/Easter/feature_easter.html
下面是一此更有用的彩蛋
http://froogle.google.com/
作用: 通過特殊的搜索引擎,你可以在網上找到你想購物的網站位置。以及你可以很方便的搜索出同類產品的價格。
看看世界各地的商品價格,自己再買的時候心底有數多了把
http://labs.google.com/gviewer.html
作用:一個小玩具,適合那些連鼠標都懶得動的懶人。當你在google上找到了查詢結果后,你可以使用google viewer讓結果以自己定義的間隔時間來一條一條自動滾屏。
http://labs.google.com/cgi-bin/webquotes
作用:可以搜索出你要查詢的內容在internet上被多少其他的網站引用過,可以讓你知道internet上其他人對你要查詢內容的觀點,適合寫論文和評論以及特殊用途人使用。
http://labs.google.com/glossary
作用:顧名思義了,就是一個查英語縮寫語意的工具,google的詞匯表
http://labs1.google.com/gvs.html
作用:給google打一個電話,說出你要查找的內容,然后google會把你要查詢的結果顯示出來。 給不識字的人用的
posted @
2007-08-30 12:01 jadmin 閱讀(85) |
評論 (0) |
編輯 收藏
直接運行這些cpl就可以不用進控制面版了
Internet選項
C:\WINDOWS\System32\inetcpl.cpl
電話和調制解調器選項
C:\WINDOWS\System32\telephon.cpl
電源選項
C:\WINDOWS\System32\powercfg.cpl
輔助功能選項
C:\WINDOWS\System32\access.cpl
管理工具
C:\WINDOWS\system32\main.cpl
鍵盤
C:\WINDOWS\System32\main.cpl
鼠標
C:\WINDOWS\System32\main.cpl
字體
C:\WINDOWS\system32\main.cpl
區域和語言選項
C:\WINDOWS\System32\intl.cpl
任務計劃
C:\WINDOWS\System32\mstask.dll
任務欄和開始菜單
C:\WINDOWS\system32\SHELL32.dll
日期和時間
C:\WINDOWS\System32\timedate.cpl
掃描儀和照相機
wiashext.dll
聲音和音頻設備
C:\WINDOWS\System32\MMSYS.CPL
添加或刪除程序
C:\WINDOWS\System32\appwiz.cpl
添加硬件
C:\WINDOWS\System32\hdwwiz.cpl
網絡連接
C:\WINDOWS\system32\netshell.dll
文件夾選項
C:\WINDOWS\system32\SHELL32.dll
無線連接
C:\WINDOWS\System32\irprops.cpl
系統
C:\WINDOWS\System32\sysdm.cpl
用戶帳戶
C:\WINDOWS\System32\nusrmgr.cpl
顯示
C:\WINDOWS\System32\desk.cpl
郵件
C:\Program Files\Common Files\System\Mapi\2052\NT\MLCFG32.CPL
游戲控制器
C:\WINDOWS\System32\joy.cpl
語音
C:\Program Files\Common Files\Microsoft Shared\Speech\sapi.cpl
以上只是在windows xp cn+sp2下找到的地址 非NT下肯定不同
好處么?就是在網吧屏蔽控制面版的時候可以直接調用相應的選項設置
posted @
2007-08-28 10:31 jadmin 閱讀(81) |
評論 (0) |
編輯 收藏
Jboss 4.0的開發人員版本是一個開源的應用服務器,他把HypersonicDB作為他的缺省數據庫。然而,開發人員也許還要使用除了HypersonicDB以外其他種類的數據庫,在這篇文章中我們將看到如何在Jboss上配置使用其他的數據庫。
簡介
Jboss4.0使用了JDBC配置文件來配置數據庫連接,它為EJB和其它J2EE應用提供了數據源(data source)進行訪問。如果你要使用HypersonicDB以外的數據庫你就要修改這個配置文件。這篇文章將著重講解下面的幾個部分:
Jboss的EJB部署描述符
Oralce數據庫的配置
MySQL數據庫的配置
Sysbase數據庫的配置
DB2數據庫的配置
Infomix數據庫的配置
Jboss的EJB部署描述符
standardjaws.xml (位于X:\jboss4\server\default\conf)是一個映射CMP 實體EJB的標準部署描述文件。它用于配置CMP實體EJB,你也可以使用jaws.xml代替。你可以把這個文件copy到ejb .jar文件中的META-INF目錄下。這個文件用于描述下面的信息:
描述一個數據源和映射類型。
描述EJB映射的表
描述EJB的finder方法
描述類型映射
這里的數據源描述的是一個JNDI名稱,可以通過這個JNDI來獲得一個數據源連接池。Jboss4缺省的數據源使用的是HypersonicDB。如果使用其他的數據源你需要修改jaws.xml文件。
standardjbosscmp-jdbc.xml(位于X:\jboss4\server\default\conf)是配置Jboss CMP容器的標準部署描述文件,你也可以使用一個自定義的配置文件--jbosscmp-jdbc.xml來代替它。這個文件也放在EJB.jar文件的 META-INF目錄中。缺省使用的還是HypersonicDB作為數據庫,這里也需要修改。
Oracle數據庫的配置
Oracle以它的運行穩定和可靠成為了一個非常受歡迎的企業級數據庫。要在Jboss 上配置使用Oracle的話我們要做的第一件事就是把Oracle的JDBC驅動程序復制到ClassPath下。我們把這個JDBC驅動程序復制到 server/default/lib目錄下。為了使用Oracle的事務處理數據源我們還要把/docs/examples/jca/oracle- xa-ds.xml復制到/server/default/deploy目錄下。如果使用的事非事務處理的數據源,就把 /docs/examples/jca/oracle-ds.xml文件復制到/server/default/deploy目錄下。
下一步,我們需要修改oracle-de.xml配置文件。其中的標簽和標簽的設置如下:
Oracle OCI Type 2 Driver
Class: oracle.jdbc.driver.OracleDriver
URL: jdbc:oracle:oci8:@<database>
Oracle OCI Thin Type 4 Driver
Class: oracle.jdbc.driver.OracleDriver
URL: jdbc:oracle:thin:@<host>:<port>:<database>
Oracle OCI XA Type 2 Driver
Class: oracle.jdbc.xa.client.OracleXADataSource
URL: jdbc:oracle:thin:@<host>:<port>:<database>
Oracle OCI Type 2 Driver
Class: oracle.jdbc.driver.OracleDriver
URL: jdbc:oracle:oci8:@<database>
在Connection
URL中是安裝Oracle的計算機主機名,是oracle數據庫的端口,是數據庫名稱。下一步,我們將修改standardjaws.xml 或jaws.xml配置文件,并把 和 元素這只為下面這樣:
<jaws>
<datasource>java:/OracleDS</datasource>
<type-mapping>Oracle8</type-mapping>
</jaws>
下一步,再修改standardjbosscmp-jdbc.xml 或 jbosscmp-jdbc.xml配置文件,設置 和 元素使用Oracle。
<jbosscmp-jdbc>
<defaults>
<datasource>java:/OracleDS</datasource>
<datasource-mapping>Oracle8</datasource-mapping>
</defaults>
</jbosscmp-jdbc>
最后我們需要修改login-config.xml文件來使用Oracle,下面是login-config.xml文件的元素:
<application-policy name = "OracleDbRealm">
<authentication>
<login-module code =
"org.jboss.resource.security.ConfiguredIdentityLoginModule"
flag = "required">
<module-option name = "principal">sa</module-option>
<module-option name = "userName">sa</module-option>
<module-option name = "password"></module-option>
<module-option name ="managedConnectionFactoryName">
jboss.jca:service=LocalTxCM,name=OracleDS
</module-option>
</login-module>
</authentication>
</application-policy>
修改了oracle-ds.xml, standardjaws.xml, standardjbosscmp-jdbc.xml,和login-config.xml 文件之后就可以再Jboss4中使用Oracle了。
MySQL數據庫配置
MySQL是一個開放源代碼的數據庫,有很多開源項目和小型的社團都在使用它。要在Jboss4中使用MySQL的話首先要把MySQL的JDBC驅動放到CLASSPATH中。同樣,把它復制到/server/default/lib目錄下,再把/docs/examples/jca/mysql- ds.xml復制到/server/default/deploy目錄下。修改mysql-ds.xml文件,設置為 com.mysql.jdbc.Driver再把設置為jdbc:mysql:///,其中是數據庫主機名是數據庫名。 然后需要設置standardjaws.xml 或 jaws.xml文件的和元素:
<jaws>
<datasource>java:/MySqlDS</datasource>
<type-mapping>mySql</type-mapping>
</jaws>
同樣也需要把standardjbosscmp-jdbc.xml 或 jbosscmp-jdbc.xml文件的 和 元素設置為下面這樣:
<jbosscmp-jdbc>
<defaults>
<datasource>java:/MySqlDS</datasource>
<datasource-mapping>mySql</datasource-mapping>
</defaults>
</jbosscmp-jdbc>
最后再修改login-config.xml文件來使用MySQL:
<application-policy name = "MySqlDbRealm">
<authentication>
<login-module code =
"org.jboss.resource.security.ConfiguredIdentityLoginModule"
flag = "required">
<module-option name ="principal">sa</module-option>
<module-option name ="userName">sa</module-option>
<module-option name ="password"></module-option>
<module-option name ="managedConnectionFactoryName">
jboss.jca:service=LocalTxCM,name=MySqlDS
</module-option>
</login-module>
</authentication>
</application-policy>
修改了mysql-ds.xml, standardjaws.xml, standardjbosscmp-jdbc.xml,和 login-config.xml 文件就可以在Jboss上使用MySQL了。
SysBase數據庫配置
Sybase Adaptive Server Enterprises(ASE)是Sysbase公司的數據庫服務器。ASE可以在Unix和linux平臺上使用。同樣我們要把它的數據庫驅動放到 CLASSPATH中,把它復制到/server/default/lib目錄下,然后把/docs/examples/jca/sybase- ds.xml 復制到/server/default/deploy目錄下。修改sybase-ds.xml文件把設置為 com.sybase.jdbc2.jdbc.SybDriver再把設置為 jdbc:sybase:Tds::/,其中分別為主機名、端口名和數據庫名。同樣需要修改standardjaws.xml 或 jaws.xml 文件的 和 元素:
<jaws>
<datasource>java:/SybaseDS</datasource>
<type-mapping>Sybase</type-mapping>
</jaws>
再修改standardjbosscmp-jdbc.xml 或 jbosscmp-jdbc.xml 文件的 和元素:
<jbosscmp-jdbc>
<defaults>
<datasource>java:/SybaseDS</datasource>
<datasource-mapping>Sybase</datasource-mapping>
</defaults>
</jbosscmp-jdbc>
最后修改login-config.xml 文件來使用Sysbase數據庫.設置 元素:
<application-policy name = "SybaseDbRealm">
<authentication>
<login-module code =
"org.jboss.resource.security.ConfiguredIdentityLoginModule"
flag = "required">
<module-option name ="principal">sa</module-option>
<module-option name = "userName">sa</module-option>
<module-option name = "password"></module-option>
<module-option name = "managedConnectionFactoryName">
jboss.jca:service=LocalTxCM,name=SybaseDS
</module-option>
</login-module>
</authentication>
</application-policy>
修改了sybase-ds.xml, standardjaws.xml, standardjbosscmp-jdbc.xml, 和login-config.xml文件后就可以在JBOSS中使用Sysbase了。
DB2數據庫配置
IBM的DB2是一個完善、使用方便的數據庫服務器,它可以在Linux,UNIX和Windows平臺上使用。在JBOSS4上使用DB2只要把 db2java.zip復制到/server/default/lib目錄下。然后復制/docs/examples/jca/db2-ds.xml到 /server/default/deploy目錄下,然后修改 元素位 COM.ibm.db2.jdbc.app.DB2Driver , 元素為 jdbc:db2:其中的元素代表數據庫服務名。
java:/DB2DS DB2
下面是相應的 standardjbosscmp-jdbc.xml (或 jbosscmp-jdbc.xml)文件:
<jbosscmp-jdbc>
<defaults>
<datasource>java:/DB2DS</datasource>
<datasource-mapping>DB2</datasource-mapping>
</defaults>
</jbosscmp-jdbc>
最后在login-config.xml文件中加上下面的內容:
<application-policy name = "DB2DbRealm">
<authentication>
<login-module code =
"org.jboss.resource.security.ConfiguredIdentityLoginModule"
flag = "required">
<module-option name =
"principal">sa</module-option>
<module-option name =
"userName">sa</module-option>
<module-option name =
"password"></module-option>
<module-option name ="managedConnectionFactoryName">
jboss.jca:service=LocalTxCM,name=DB2DS
</module-option>
</login-module>
</authentication>
</application-policy>
完成上面的配置就可以在Jboss上使用DB2了
Informix 數據庫配置
IBM的Infoxmix數據庫服務器用于作為數據倉庫、分析和報告。在Jboss4上使用Informix數據庫,首先要把它相應的數據庫JDBC驅動復制到/server/default/lib目錄下,然后,把/docs/examples/jca/informix-ds.xml 復制到 /server/default/deploy目錄下,如果你使用的是事務的(XA)JDBC就復制那個 /docs/examples/jca/informix-xa-ds.xml文件。
下一步要作的就是修改這個informix-ds.xml文件,把元素設置為:com.informix.jdbc.IfxDriver把元素設置為jdbc:informix-sqli://::informixserver=, 其中,,,分別代表數據庫主機名、數據庫端口和數據庫服務名。然后修改standardjaws.xml 或 jaws.xml文件的 和 元素:
<post>
<jaws>
<datasource>java:/InformixDS</datasource>
<type-mapping>InformixDB</type-mapping>
</jaws>
把standardjbosscmp-jdbc.xml 或 jbosscmp-jdbc.xml文件中的 和 元素設置為下面這樣:
<jbosscmp-jdbc>
<defaults>
<datasource>java:/InformixDS</datasource>
<datasource-mapping>InformixDB</datasource-mapping>
</defaults>
</jbosscmp-jdbc>
最后在login-config.xml文件中加入元素:
<application-policy name = "InformixDbRealm">
<authentication>
<login-module code =
"org.jboss.resource.security.ConfiguredIdentityLoginModule"
flag = "required">
<module-option name = "principal">sa</module-option>
<module-option name = "userName">sa</module-option>
<module-option name = "password"></module-option>
<module-option name ="managedConnectionFactoryName">
jboss.jca:service=LocalTxCM,name=InformixDS
</module-option>
</login-module>
</authentication>
</application-policy>
這樣,你就可以在Jboss4中使用Informix數據庫了。
結論
Jboss4默認情況下使用的是Hypersonic數據庫,但如你所見我們只要簡單的修改幾個配置文件就可以使用市面上流行的其他數據庫了。
posted @
2007-08-28 09:48 jadmin 閱讀(71) |
評論 (0) |
編輯 收藏
JSP 標準標記庫(JSP Standard Tag Library,JSTL)是一個實現 Web 應用程序中常見的通用功能的定制標記庫集,這些功能包括迭代和條件判斷、數據管理格式化、XML 操作以及數據庫訪問。在 developerWorks 上其新系列的第一篇文章中,軟件工程師 Mark Kolb 向您展示了如何使用 JSTL 標記來避免在 JSP 頁面中使用腳本編制元素。您還將了解如何通過從表示層刪除源代碼來簡化軟件維護。最后,您將了解 JSTL 經過簡化的表達式語言,它允許在不必使用功能齊全的編程語言的情況下對 JSTL 操作指定動態屬性值。
JavaServer Pages(JSP)是用于 J2EE 平臺的標準表示層技術。JSP 技術提供了用于執行計算(這些計算用來動態地生成頁面內容)的腳本編制元素和操作。腳本編制元素允許在 JSP 頁面中包括程序源代碼,在為響應用戶請求而呈現頁面時可以執行這些源代碼。操作將計算操作封裝到很象 HTML 或 XML 標記的標記中,JSP 頁面的模板文本通常包含這些標記。JSP 規范只將幾種操作定義成了標準,但從 JSP 1.1 開始,開發人員已經能夠以定制標記庫的方式創建其自己的操作了。
JSP 標準標記庫(JSTL)是 JSP 1.2 定制標記庫集,這些標記庫實現大量服務器端 Java 應用程序常用的基本功能。通過為典型表示層任務(如數據格式化和迭代或條件內容)提供標準實現,JSTL 使 JSP 作者可以專注于特定于應用程序的開發需求,而不是為這些通用操作“另起爐灶”。
當然,您可以使用 JSP 腳本編制元素(scriptlet、表達式和聲明)來實現此類任務。例如,可以使用三個 scriptlet 實現條件內容,清單 1 中著重顯示了這三個 scriptlet。但是,因為腳本編制元素依賴于在頁面中嵌入程序源代碼(通常是 Java 代碼),所以對于使用這些腳本編制元素的 JSP 頁面,其軟件維護任務的復雜度大大增加了。例如,清單 1 中的 scriptlet 示例嚴格地依賴于花括號的正確匹配。如果不經意間引入了一個語法錯誤,則條件內容中的嵌套其它 scriptlet 可能會造成嚴重破壞,并且在 JSP 容器編譯該頁面時,要使所產生的錯誤信息有意義可能會很困難。
清單 1. 通過 scriptlet 實現條件內容 <% if (user.getRole() == "member")) { %>
<p>Welcome, member!</p> <% } else { %> ???? <p>Welcome, guest!</p> <% } %>
|
修正此類問題通常需要相當豐富的編程經驗。盡管通常會由十分精通頁面布局和圖形設計 的設計人員來開發和維護 JSP,但是同一頁面中的腳本編制元素出現問題時,需要程序員的介入。這種狀況將單個文件中代碼的責任分擔給多人,因而使得開發、調試和增強此類 JSP 頁面成為很麻煩的任務。通過將常用功能包裝到定制標記庫的標準集合中,JSTL 使 JSP 作者可以減少對編制腳本元素的需求,甚至可以不需要它們,并避免了相關的維護成本。
JSTL 1.0 JSTL 1.0 發布于 2002 年 6 月,由四個定制標記庫(core、format、xml 和 sql)和一對通用標記庫驗證器(ScriptFreeTLV 和 PermittedTaglibsTLV)組成。core 標記庫提供了定制操作,通過限制了作用域的變量管理數據,以及執行頁面內容的迭代和條件操作。它還提供了用來生成和操作 URL 的標記。顧名思義,format 標記庫定義了用來格式化數據(尤其是數字和日期)的操作。它還支持使用本地化資源束進行 JSP 頁面的國際化。xml 庫包含一些標記,這些標記用來操作通過 XML 表示的數據,而 sql 庫定義了用來查詢關系數據庫的操作。
兩個 JSTL 標記庫驗證器允許開發人員在其 JSP 應用程序中強制使用編碼標準。可以配置 ScriptFreeTLV 驗證器以在 JSP 頁面中禁用各種類型的 JSP 腳本元素 — scriptlet、表達式和聲明。類似地,PermittedTaglibsTLV 驗證器可以用來限制可能由應用程序的 JSP 頁面訪問的定制標記庫集(包括 JSTL 標記庫)。
盡管 JSTL 最終將會成為 J2EE 平臺的必需組件,但目前只有少數應用程序服務器包括它。JSTL 1.0 的參考實現可作為 Apache 軟件基金會(Apache Software Foundation)的 Jakarta Taglibs 項目(請參閱參考資料)的一部分而獲得。可以將該參考實現中的定制標記庫合并到任何支持 JSP 1.2 和 Servlet 2.3 規范的服務器,以添加對 JSTL 的支持。
表達式語言 在 JSP 1.2 中,可以使用靜態字符串或表達式(如果允許的話)指定 JSP 操作的屬性。例如,在清單 2 中,對 <jsp:setProperty> 操作的 name 和 property 屬性指定了靜態值,而用表達式指定了其 value 屬性。這個操作的效果是將請求參數的當前值賦予命名的 bean 特性。以這種形式使用的表達式被稱為請求時屬性值(request-time attribute value),這是構建到 JSP 規范中的用于動態指定屬性值的唯一機制。
清單 2. 合并請求時屬性值的 JSP 操作
<jsp:setProperty name="user" property="timezonePref" ????????????????? value=~<%= request.getParameter("timezone") %>~/>
|
因為請求時屬性值是用表達式指定的,所以它們往往有和其它腳本元素一樣的軟件維護問 題。因此,JSTL 定制標記支持另一種用于指定動態屬性值的機制。可以用簡化的表達式語言(EL)而不使用完整的 JSP 表達式來指定 JSTL 操作的屬性值。EL 提供了一些標識符、存取器和運算符,用來檢索和操作駐留在 JSP 容器中的數據。EL 在某種程度上以 EcmaScript(請參閱參考資料)和 XML 路徑語言(XML Path Language,XPath)為基礎,因此頁面設計人員和程序員都應該熟悉它的語法。EL 擅長尋找對象及其特性,然后對它們執行簡單操作;它不是編程語言,甚至不是腳本編制語言。但是,與 JSTL 標記一起使用時,它就能使用簡單而又方便的符號來表示復雜的行為。EL 表達式的格式是這樣的:用美元符號($)定界,內容包括在花括號({})中,如清單 3 所示。
清單 3. 說明 EL 表達式定界符的 JSTL 操作
<c:out value="${user.firstName}"/>
此外,您可以將多個表達式與靜態文本組合在一起以通過字符串并置來構造動態屬性值,如清單 4 所示。單獨的表達式由標識符、存取器、文字和運算符組成。標識符用來引用存儲在數據中心中的數據對象。EL 有 11 個保留標識符,對應于 11 個 EL 隱式對象。假定所有其它標識符都引用限制了作用域的變量。存取器用來檢索對象的特性或集合的元素。文字表示固定的值 — 數字、字符、字符串、布爾型或空值。運算符允許對數據和文字進行組合以及比較。
清單 4. 組合靜態文本和多個 EL 表達式以指定動態屬性值
<c:out value="Hello ${user.firstName} ${user.lastName}"/>
限制了作用域的變量 JSP API 通過 <jsp:useBean> 操作允許從 JSP 容器內的四個不同作用域中存儲和檢索數據。JSTL 通過提供用于指定和除去這些作用域中的對象的附加操作來擴展這一能力。此外,EL 提供將這些對象作為限制了作用域的變量進行檢索的內置支持。特別地,任何出現在 EL 表達式中但不對應于任何 EL 隱式對象的標識符,都被自動假定為引用存儲在四個 JSP 作用域的其中某個中的對象,這四個作用域是:
·頁面作用域
·請求作用域
·會話作用域
·應用程序作用域
您可能還記得,只有在為特定請求處理頁面期間才能檢索存儲在該頁面作用域中的對象。如果對象是存儲在請求作用域中的,可以在處理所有參與處理某請求的頁 面期間檢索這些對象(譬如在對某個請求的處理中遇到了一個或多個 <jsp:include> 或 <jsp:forward> 操作)。如果對象是存儲在會話作用域中的,則在與 Web 應用程序的交互式會話期間,可以由用戶訪問的任何頁面檢索它(即,直到與該用戶交互相關聯的 HttpSession 對象無效為止)。可以由任何用戶從任何頁面訪問存儲在應用程序作用域中的對象,直到卸載 Web 應用程序本身為止(通常是由于關閉 JSP 容器所致)。
通過將字符串映射為期望作用域中的對象來將對象存儲到該作用域。然后,就可以通過提供相同字符串來從該作用域檢索該對象。在作用域的映射中查找字符串,并 返回被映射的對象。在 Servlet API 中,將此類對象稱為相應作用域的屬性。但是,在 EL 的上下文中,也將與屬性相關聯的字符串看作變量的名稱,該變量通過屬性映射的方式獲得特定的值。
在 EL 中,與隱式對象無關聯的標識符被認為是存儲在四個 JSP 作用域中的名稱對象。首先對頁面作用域檢查是否存在這樣的標識符,其次對請求作用域、然后對會話作用域、最后對應用程序作用域依次進行這樣的檢查,然后測 試該標識符的名稱是否與存儲在該作用域中的某個對象的名稱匹配。第一個這樣的匹配作為 EL 標識符的值被返回。通過這種方法,可以將 EL 標識符看作引用限制了作用域的變量。
從更技術的方面來說,沒有映射到隱式對象的標識符是用 PageContext 實例的 findAttribute() 方法求值的,該實例表示對頁面的處理,在該頁面上,當前正在處理用于請求的表達式。標識符的名稱作為參數傳遞給這個方法,然后該方法依次在四個作用域中搜 索具有相同名稱的屬性。并將所找到的第一個匹配項作為 findAttribute() 方法的值返回。如果未在這四個作用域中找到這樣的屬性,則返回 null。
最終,限制了作用域的變量是四個 JSP 作用域的屬性,這些屬性具有可以用作 EL 標識符的名稱。只要對限制了作用域的變量賦予由字母數字組成的名稱,就可以通過 JSP 中提供的用于設置屬性的任何機制來創建它們。這包括內置的 <jsp:useBean> 操作,以及由 Servlet API 中的幾個類定義的 setAttribute() 方法。此外,四個 JSTL 庫中定義的許多定制標記本身就能夠設置作為限制了作用域的變量使用的屬性值。
隱式對象
表 1 中列出了 11 個 EL 隱式對象的標識符。不要將這些對象與 JSP 隱式對象(一共只有九個)混淆,其中只有一個對象是它們所共有的。
表 1. EL 隱式對象
類別 標識符 描述
JSP pageContext PageContext 實例對應于當前頁面的處理
作用域 pageScope 與頁面作用域屬性的名稱和值相關聯的 Map 類
requestScope 與請求作用域屬性的名稱和值相關聯的 Map 類
sessionScope 與會話作用域屬性的名稱和值相關聯的 Map 類
applicationScope 與應用程序作用域屬性的名稱和值相關聯的 Map 類
請求參數 param 按名稱存儲請求參數的主要值的 Map 類
paramValues 將請求參數的所有值作為 String 數組存儲的 Map 類
請求頭 header 按名稱存儲請求頭主要值的 Map 類
headerValues 將請求頭的所有值作為 String 數組存儲的 Map 類
Cookie cookie 按名稱存儲請求附帶的 cookie 的 Map 類
初始化參數 initParam 按名稱存儲 Web 應用程序上下文初始化參數的 Map 類
盡管 JSP 和 EL 隱式對象中只有一個公共對象(pageContext),但通過 EL 也可以訪問其它 JSP 隱式對象。原因是 pageContext 擁有訪問所有其它八個 JSP 隱式對象的特性。實際上,這是將它包括在 EL 隱式對象中的主要理由。
其余所有 EL 隱式對象都是映射,可以用來查找對應于名稱的對象。前四個映射表示先前討論的各種屬性作用域。可以用它們來查找特定作用域中的標識符,而不用依賴于 EL 在缺省情況下使用的順序查找過程。
接下來的四個映射用來獲取請求參數和請求頭的值。因為 HTTP 協議允許請求參數和請求頭具有多個值,所以它們各有一對映射。每對中的第一個映射返回請求參數或頭的主要值,通常是恰巧在實際請求中首先指定的那個值。每 對中第二個映射允許檢索參數或頭的所有值。這些映射中的鍵是參數或頭的名稱,但這些值是 String 對象的數組,其中的每個元素都是單一參數值或頭值。
cookie 隱式對象提供了對由請求設置的 cookie 名稱的訪問。這個對象將所有與請求相關聯的 cookie 名稱映射到表示那些 cookie 特性的 Cookie 對象。
最后一個 EL 隱式對象 initParam 是一個映射,它儲存與 Web 應用程序相關聯的所有上下文的初始化參數的名稱和值。初始化參數是通過 web.xml 部署描述符文件指定的,該文件位于應用程序的 WEB-INF 目錄中。
存取器 因為 EL 標識符是作為隱式對象或限制了作用域的變量(通過屬性來實現)解析的,因此有必要將它們轉換成 Java 對象。EL 可以自動包裝和解包其相應的 Java 類中的基本類型(例如,可以在后臺將 int 強制轉換成 Integer 類,反之亦可),但大多數的標識符將成為指向完整的 Java 對象的指針。
結果是,對這些對象的特性或(在對象是數組和集合的情況下)對其元素的訪問通常是令人滿意的。就為了實現這種用途,EL 提供了兩種不同的存取器(點運算符(.)和方括號運算符([])),也支持通過 EL 操作特性和元素。
點運算符通常用于訪問對象的特性。例如,在表達式 ${user.firstName} 中,使用點運算符來訪問 user 標識符所引用對象的名為 firstName 的特性。EL 使用 Java bean 約定訪問對象特性,因此必須定義這個特性的 getter 方法(通常是名為 getFirstName() 的方法),以便表達式正確求值。當被訪問的特性本身是對象時,可以遞歸地應用點運算符。例如,如果我們虛構的 user 對象有一個實現為 Java 對象的 address 特性,那么也可以用點運算符來訪問這個對象的特性。例如,表達式 ${user.address.city} 將會返回這個地址對象嵌套的 city 特性。
方括號運算符用來檢索數組和集合的元素。在數組和有序集合(也即,實現了 java.util.List 接口的集合)的情況下,把要檢索的元素的下標放在方括號中。例如,表達式 ${urls[3]} 返回 urls 標識符所引用的數組或集合的第四個元素(和 Java 語言以及 JavaScript 中一樣,EL 中的下標是從零開始的)。
對于實現 java.util.Map 接口的集合,方括號運算符使用關聯的鍵查找存儲在映射中的值。在方括號中指定鍵,并將相應的值作為表達式的值返回。例如,表達式 ${commands["dir"]} 返回與 commands 標識符所引用的 Map 中的 "dir" 鍵相關聯的值。
對于上述兩種情況,都可允許表達式出現在方括號中。對嵌套表達式求值的結果將被作為下標或鍵,用來檢索集合或數組的適當元素。和點運算符一樣,方括號運算 符也可以遞歸應用。這使得 EL 能夠從多維數組、嵌套集合或兩者的任意組合中檢索元素。此外,點運算符和方括號運算符還可以互操作。例如,如果數組的元素本身是對象,則可以使用方括號運 算符來檢索該數組的元素,并結合點運算符來檢索該元素的一個特性(例如 ${urls[3].protocol})。
假定 EL 充當指定動態屬性值的簡化語言,EL 存取器有一個有趣的功能(與 Java 語言的存取器不同),那就是它們在應用于 null 時不拋出異常。如果應用 EL 存取器的對象(例如,${foo.bar} 和 ${foo["bar"]} 中的 foo 標識符)是 null,那么應用存取器的結果也是 null。事實證明,在大多數情況下,這是一個相當有用的行為,不久您就會了解這一點。
最后,點運算符和方括號運算符可能實現某種程度的互換。例如,也可以使用 ${user["firstName"]} 來檢索 user 對象的 firstName 特性,正如可以用 ${commands.dir} 獲取與 commands 映射中的 "dir" 鍵相關聯的值一樣。
運算符 EL 還可以通過使用標識符和存取器,遍歷包含應用程序數據(通過限制了作用域的變量公開)或關于環境的信息(通過 EL 隱式對象)的對象層次結構。但是,只是訪問這些數據,通常不足以實現許多 JSP 應用程序所需的表示邏輯。
最終,EL 還包括了幾個用來操作和比較 EL 表達式所訪問數據的運算符。表 2 中匯總了這些運算符。
表 2. EL 運算符
類別 運算符
算術運算符 +、-、*、/(或 div)和 %(或 mod)
關系運算符 ==(或 eq)、!=(或 ne)、<</code>(或 lt)、>(或 gt)、<=(或 le)和 >=(或 ge)
邏輯運算符 &&(或 and)、||(或 or)和 !(或 not)
驗證運算符 empty
算術運算符支持數值的加法、減法、乘法和除法。還提供了一個求余運算符。注:除法和求余運算符都有替代的、非符號的名稱(為的是與 XPath 保持一致)。清單 5 中顯示了一個演示算術運算符用法的示例表達式。對幾個 EL 表達式應用算術運算符的結果是將該算術運算符應用于這些表達式返回的數值所得的結果。
清單 5. 利用算術運算符的 EL 表達式
${item.price * (1 + taxRate[user.address.zipcode])}
|
關系運算符允許比較數字或文本數據。比較的結果作為布爾值返回。邏輯運算符允許合并布爾值,返回新的布爾值。因此,可以將 EL 邏輯運算符應用于嵌套的關系或邏輯運算符的結果,如清單 6 所示。
清單 6. 利用關系和邏輯運算符的 EL 表達式
${(x >= min) && (x <= max)}
|
最后一種 EL 運算符是 empty,它對于驗證數據特別有用。empty 運算符采用單個表達式作為其變量(也即,${empty input}),并返回一個布爾值,該布爾值表示對表達式求值的結果是不是“空”值。求值結果為 null 的表達式被認為是空,即無元素的集合或數組。如果參數是對長度為零的 String 求值所得的結果,則 empty 運算符也將返回 true。
表 3 顯示了 EL 運算符的優先級。正如清單 5 和 6 所示,可以用圓括號對表達式分組,高于普通的優先級規則。
表 3. EL 運算符優先級(自頂到底,從左到右)
[], . () unary -、not、!、empty *、/、div、%、mod +、binary - () <</code>、>、<=、>=、lt、gt、le、ge ==、!=、eq、ne &&、and ||、or
|
文字
在 EL 表達式中,數字、字符串、布爾值和 null 都可以被指定為文字值。字符串可以用單引號或雙引號定界。布爾值被指定為 true 和 false。
Taglib 偽指令
正如我們先前討論的,JSTL 1.0 包括四個定制標記庫。為了演示 JSTL 標記和表達式語言的交互,我們將研究幾個來自 JSTL core 庫的標記。和使用任何 JSP 定制標記庫一樣,必須在您想要使用這個庫標記的任何頁面中包括 taglib 偽指令。清單 7 顯示了用于這個特定庫的偽指令。
清單 7. 用于 JSTL core 庫 EL 版本的 taglib 偽指令
<%@ taglib uri="http://java.sun.com/jstl/core" prefix="c" %>
|
實際上,對應于 JSTL core 庫的 taglib 偽指令有兩種,因為在 JSTL 1.0 中,EL 是可選的。所有四個 JSTL 1.0 定制標記庫都有使用 JSP 表達式(而不是 EL)指定動態屬性值的備用版本。因為這些備用庫依賴于 JSP 的更傳統的請求時屬性值,所以它們被稱為 RT 庫,而那些使用表達式語言的則被稱為 EL 庫。開發人員用不同的 taglib 偽指令來區分每個庫的這兩個版本。清單 8 顯示了使用 core 庫的 RT 版本的偽指令。但是,由于現在我們討論的重點是 EL,所以首先需要這些偽指令。
清單 8. 用于 JSTL core 庫 RT 版本的 taglib 偽指令
<%@ taglib uri="http://java.sun.com/jstl/core_rt" prefix="c_rt" %>
|
變量標記 我們首先要考 慮的 JSTL 定制標記是 <c:set> 操作。正如已經說明的,限制了作用域的變量在 JSTL 中起關鍵作用,<c:set> 操作提供基于標記的機制來創建和設置限制了作用域的變量。清單 9 中顯示了該操作的語法,其中 var 屬性指定了限制了作用域的變量的名稱,scope 屬性表明了該變量駐留在哪個作用域中,value 屬性指定了分配給該變量的值。如果指定變量已經存在,則簡單地將所指明的值賦給它。如果不存在,則創建新的限制了作用域的變量,并用該值初始化這個變量。
清單 9. <c:set> 操作的語法
<c:set var="name" scope="scope" value="expression"/>
|
scope 屬性是可選的,其缺省值是 page。
清單 10 中顯示了 <c:set> 的兩個示例。在第一個示例中,將會話作用域變量設置成 String 值。在第二個示例中,用表達式來設置數值:將頁面作用域內名為 square 的變量賦值為名為 x 的請求參數的值的平方。
清單 10. <c:set> 操作示例
<c:set var="timezone" scope="session" value="CST"/> <c:set var="square" value="${param[~x~] * param[~x~]}"/>
|
您還可以將限制了作用域的變量的值指定為 <c:set> 操作的主體內容,而不是使用屬性。使用這種方法,您可以重新編寫清單 10 中的第一個示例,如清單 11 所示。此外,正如我們馬上可以看到的,<c:set> 標記的主體內容本身也可以使用定制標記。<c:set> 主體內生成的所有內容都將作為一個 String 值賦給指定變量。
清單 11. 通過主體內容指定 <c:set> 操作的值
<c:set var="timezone" scope="session">CST</c:set>
|
JSTL core 庫包含第二個用于管理限制了作用域的變量的標記 — <c:remove>。顧名思義,<c:remove> 操作是用來刪除限制了作用域的變量的,它獲取兩個屬性。var 屬性指定待刪除變量的名稱,scope 屬性是可選的,它表示待刪除變量來自哪個作用域,缺省為 page,如清單 12 所示。
清單 12. <c:remove> 操作示例
<c:remove var="timezone" scope="session"/>
|
輸出 盡管 <c:set> 操作允許將表達式結果賦給限制了作用域的變量,但開發人員通常會希望只顯示表達式的值,而不存儲它。JSTL <c:out> 定制標記承擔這一任務,其語法如清單 13 所示。該標記對由其 value 屬性指定的表達式進行求值,然后打印結果。如果指定了可選屬性 default,那么,在對 value 屬性的表達式求值所得結果為 null 或空 String 的情況下,<c:out> 將打印其值。
清單 13. <c:out> 操作的語法
<c:out value="expression" default="expression" escapeXml="boolean"/>
|
escapeXml 屬性也是可選的。它控制當用 <c:out> 標記輸出諸如“<”、“>”和“&”之類的字符(在 HTML 和 XML 中具有特殊意義)時是否應該進行轉義。如果將 escapeXml 設置為 true,則會自動將這些字符轉換成相應的 XML 實體(此處提到的字符分別轉換成 <、> 和 &)。
例如,假定有一個名為 user 的會話作用域變量,它是一個類的實例,該類為用戶定義了兩個特性:username 和 company。每當用戶訪問站點時,這個對象被自動分配給會話,但直到用戶實際登錄后,才會設置這兩個特性。假定是這種方案,請考慮清單 14 中的 JSP 片段。在用戶登錄之后,這個片段將顯示單詞“Hello”,其后是他/她的用戶名和一個驚嘆號。但是,在用戶登錄之前,由這個片段生成的內容則是短語 “Hello Guest!”。在這種情況下,因為 username 特性還有待初始化,所以 <c:out> 標記將轉而打印出 default 屬性的值(即字符串“Guest”)。
清單 14. 帶缺省內容的 <c:out> 操作示例 Hello
<c:out value="${user.username}" default=="Guest"/>!
|
接下來,考慮清單 15,它使用了 <c:out> 標記的 escapeXml 屬性。如果在這種情況下已經將 company 特性設置成 Java String 值 "Flynn & Sons",那么,實際上該操作生成的內容將是 Flynn & Sons。如果這個操作是生成 HTML 或 XML 內容的 JSP 頁面的一部分,那么,這個字符串中間的“&”符號最終可能被解釋為 HTML 或 XML 控制字符,從而妨礙了對該內容的顯示或解析。但是,如果將 escapeXml 屬性值設置成 true,則所生成的內容將是 Flynn & Sons。瀏覽器或解析器不會因在解釋時遇到這種內容而出問題。假定 HTML 和 XML 是 JSP 應用程序中最常見的內容類型,所以 escapeXml 屬性的缺省值是 true 就不足為奇了。
清單 15. 禁用轉義的 <c:out> 操作示例
<c:out value="${user.company}" escapeXml=="false"/>
|
用缺省值設置變量 除了 簡化動態數據的顯示之外,當通過 <c:set> 設置變量值時,<c:out> 指定缺省值的能力也很有用。正如清單 11 所示,用來賦給限制了作用域的變量的值可以指定為 <c:set> 標記的主體內容,也可以通過其值屬性來指定。通過將 <c:out> 操作嵌套在 <c:set> 標記的主體內容中,變量賦值就可以利用其缺省值能力。
清單 16 中說明了這種方法。外部 <c:set> 標記的行為非常簡單:它根據其主體內容設置會話作用域 timezone 變量的值。但是,在這種情況下,主體內容是通過 <c:out> 操作生成的。這個嵌套操作的值屬性是表達式 ${cookie[~tzPref~].value},它嘗試通過 cookie 隱式對象返回名為 tzPref 的 cookie 值。(cookie 隱式對象將 cookie 名稱映射到相應的 Cookie 實例,這意味著必須通過對象的 value 特性使用點運算符來檢索儲存在 cookie 中的實際數據。)
清單 16. 合并 <c:set> 和 <c:out> 以提供缺省變量值
<c:set var="timezone" scope=="session"> ??? <c:out value="${cookie[~tzPref~].value}" default=="CST"/> </c:set>
|
但是,請考慮以下情況,用戶是第一次嘗試使用這段代碼的 Web 應用程序。結果是,請求中沒有提供名為 tzPref 的 cookie。這意味著使用隱式對象的查找將返回 null,在這種情況下整個表達式將返回 null。因為對 <c:out> 標記的 value 屬性求值的結果是 null,所以 <c:out> 標記會轉而輸出對其 default 屬性求值的結果。在這里是字符串 CST。因此,實際的結果是將 timezone 限制了作用域的變量設置成用戶的 tzPref cookie 中存儲的時區,或者,如果沒有,則使用缺省時區 CST。
EL 和 JSP 2.0 目前,表達式語言僅可用于指定 JSTL 定制標記中的動態屬性值。但 JSTL 1.0 表達式語言的一個擴展已經被提出,會把它包括到 JSP 2.0 中去,眼下正在進行最后評審。這個擴展將允許開發人員通過自己的定制標記來使用 EL。頁面作者將可以在目前允許使用 JSP 表達式的任何地方使用 EL 表達式,譬如將動態值插入模板文本中:<p>Your preferred time zone is ${timezone}</p>。
這個 JSP 2.0 功能(就象 JSTL 本身一樣)將支持頁面作者進一步減少對 JSP 編制腳本元素的依賴,從而改進 JSP 應用程序的可維護性。
結束語 EL(與四個 JSTL 定制標記庫提供的操作結合起來)允許頁面作者不使用腳本元素即可實現表示層邏輯。例如,對比本文開頭清單 1 中的 JSP 代碼和清單 17 中顯示的通過 JSTL 實現的同樣功能。(JSTL core 庫中其余的標記,包括 <c:choose> 及其子標記,將在本系列的下一篇文章中討論。)盡管顯然執行了條件邏輯,但是 JSTL 版本中沒有 Java 語言源代碼,并且標記之間的關系(尤其是關于嵌套需求)對于任何精通 HTML 語法的人都應該是熟悉的。
清單 17. 合并 <c:set> 和 <c:out> 以提供缺省變量值
<c:choose><c:when test="${user.role == ~member~}"> ???? <p>Welcome, member!</p> ?? </c:when><c:otherwise> ???? <p>Welcome, guest!</p> ?? </c:otherwise></c:choose>
|
通過提供大多數 Web 應用程序常用功能的標準實現,JSTL 有助于加速開發周期。與 EL 結合起來,JSTL 可以不需要對表示層程序編寫代碼,這極大地簡化了 JSP 應用程序的維護。
參考資料
Sun 的 JSP 標準標記庫主頁是了解關于 JSTL 的更多信息的良好起點。
JSTL 1.0 規范是關于 EL 和四個 JSTL 標記庫的最終權威文本。
Jakarta Taglibs 項目是 JSTL 1.0 參考實現的起源。
Shawn Bayern 所著的 JSTL in Action(Manning Publications Co.,2002 年)提供了對所有 JSTL 功能的精彩論述,作者是該參考實現的領導。
David Geary 是 Java 技術方面很受歡迎的作者,他也寫了一本關于 JSTL 的書,書名是 Core JSTL。
JSPTags.com 是 JSP 技術參考資料的目錄,它尤其專注于定制標記庫。
Sun 的 Java Web Services Tutorial 中包含了對 JSTL 的討論。
“Using JSPs and custom tags within VisualAge for Java and WebSphere Studio”(WebSphere 開發者園地)是一篇 WBOnline 實用論文,它演示了 servlet、JSP 和定制標記庫的使用。
通過 Jeff Wilson 精彩的文章“使用定制標記控制 JSP 頁面”(developerWorks,2002 年 1 月)了解關于定制標記庫的一切。
Noel Bergman 的文章“JSP 標記庫:著意設計的更好的可用性”(developerWorks,2001 年 12 月)向您展示了聲明性標記是如何幫助提高 JSP 頁面的可用性的。
有關 EcmaScript 的更多詳細信息,請參閱 Sing Li 的“快速上手 Java 編程”(developerWorks,2001 年 7 月)。
在 developerWorks Java 技術專區可以找到多達數百篇的 Java 技術參考資料。
posted @
2007-08-22 19:52 jadmin 閱讀(41) |
評論 (0) |
編輯 收藏
第一類情況是,當瀏覽器的緩存被裝滿時,“查看源文件”功能將失效。如果你想確定自己的電腦是否屬于這類情況,可以點擊IE的“工具”菜單中的“Internet選項” “常規”標簽,然后,再點擊“Internet臨時文件”一欄中的“刪除文件”按鈕。
第二類情況,當你打開某些特殊的瀏覽器窗口(比如說用JavaScript腳本語言編寫的網頁)時,“查看源文件”功能也會失效。如果你在瀏覽任何網頁時,都無法“查看源文件”,那就不屬于這類情況。
第三類情況,當一個網頁還沒有被完全加載到桌面時,“查看源文件”功能也是不能使用的(在這種狀態下,“文件”菜單中的“另存為”選項也是屏蔽的)。這也算不上是真正的問題。
第四類情況,查看Windows文件夾,如果找不到Notepad.exe,將會導致“查看源文件”功能無法使用。
第五類情況,如果TEMP(或TMP)環境變量指向某一個不存在的文件夾,也會導致“查看源文件”功能無法使用。打開命令提示符(command prompt)窗口,鍵入SET TEMP(或SET TMP),就可以查看到這些變量的值。
第六類情況,通過注冊表設置也可以限定命令行的有效性。首先,點擊“開始”菜單,在運行對話框中鍵入“REGEDIT”,調出注冊表編輯器,點擊“HKEY_CURRENT_USER\Software\ Policies\Microsoft\Internet Explorer\ Restrictions”,在右邊的窗格中找到一個名為NoViewSource的值,如果當前的數值數據設置為1,則雙擊它,將數值數據更改為0。
第七類情況,通過查看注冊表設置,你還會發現:如果指定的調用程序不正確,也將導致“查看源文件”功能失靈。調出注冊表編輯器,點擊“HKEY_LOCAL_MACHINE\Software\ Microsoft\Internet Explorer\View Source Editor\Editor Name”,如果該鍵存在的話,右邊窗格中所顯示的默認的“數值名稱”應該是記
事本程序的完整路徑,一般以“C:\windows\notepad.exe”的形式表示。如果該鍵不存在,先核實記事本程序的正確位置,然后雙擊默認鍵值,修改錯誤路徑。
第八類情況,組策略的設置也有可能會屏蔽“查看源文件”這一菜單項。從“開始”菜單中調出“運行”對話框,鍵入GPEDIT.MSC。如果桌面上彈出一個提示框,提示該文件名不正確,則說明“查看源文件”功能的失效與組策略的設置無關;否則,桌面上將會彈出一個“組策略編輯器”窗口,點擊“User Configuration\Administr-ativeTemplates\Windows Components\Internet Explorer\Browser”,在右邊的窗格中找到View menu: Disable Source menu,如果這個鍵值被設置為“Enabled”,則將它更改為“Disabled”。
注意,上面介紹的第一類情況(即由于IE所保存的Internet臨時文件過多而造成“查看源文件”功能失靈)是最常見的(如圖)。如果刪除了所有脫機內容之后,該功能仍然無法使用,你再依次檢查后面所介紹的幾種可能性,直到問題消除為止。
該文章轉載自1024k:http://www.1024k.cn/faq/2007/200705/25636.html
posted @
2007-08-22 19:27 jadmin 閱讀(100) |
評論 (0) |
編輯 收藏
我的xml文件Login.xml如下.
<?xml version="1.0" encoding="utf-8" ?>
<Login>
????? <Character>
????????? <C Text="熱血" Value="0"></C>
????????? <C Text="弱氣" Value="1"></C>
????????? <C Text="激情" Value="2"></C>
????????? <C Text="冷靜" Value="3"></C>
????????? <C Text="冷酷" Value="4"></C>
????? </Character>
????? <Weapon>
????????? <W Text="光束劍" Value="0"></W>
????????? <W Text="光束配刀" Value="1"></W>
????? </Weapon>
????? <EconomyProperty>
????????? <P Text="平均型" Value="0"></P>
????????? <P Text="重視攻擊" Value="1"></P>
????????? <P Text="重視敏捷" Value="2"></P>
????????? <P Text="重視防御" Value="3"></P>
????????? <P Text="重視命中" Value="4"></P>
????? </EconomyProperty>
</Login>
現在我需要對這個xml文件的內容進行操作.
首先,我們需要加載這個xml文件,js中加載xml文件,是通過XMLDOM來進行的.
// 加載xml文檔
loadXML????? = function(xmlFile)
{
????? var xmlDoc;
????? if(window.ActiveXObject)
????? {
????????? xmlDoc????? = new ActiveXObject('Microsoft.XMLDOM');
????????? xmlDoc.async????? = false;
????????? xmlDoc.load(xmlFile);
????? }
????? else if (document.implementation&&document.implementation.createDocument)
????? {
????????? xmlDoc????? = document.implementation.createDocument('', '', null);
????????? xmlDoc.load(xmlFile);
????? }
????? else
????? {
????????? return null;
????? }
????
????? return xmlDoc;
}
xml文件對象出來了, 接下去我就要對這個文檔進行操作了.
比如說,我們現在需要得到節點Login/Weapon/W的第一個節點的屬性,那么我們可以如下進行.
// 首先對xml對象進行判斷
checkXMLDocObj????? = function(xmlFile)
{
????? var xmlDoc????? = loadXML(xmlFile);
????? if(xmlDoc==null)
????? {
????????? alert('您的瀏覽器不支持xml文件讀取,于是本頁面禁止您的操作,推薦使用IE5.0以上可以解決此問題!');
????????? window.location.href='/Index.aspx';
????? }
????
????? return xmlDoc;
}
// 然后開始獲取需要的Login/Weapon/W的第一個節點的屬性值
var xmlDoc????? = checkXMLDocObj('/EBS/XML/Login.xml');
var v????? = xmlDoc.getElementsByTagName('Login/Weapon/W')[0].childNodes.getAttribute('Text')
而我在我的程序中的寫法是這樣子的,當然我在程序中的寫法是已經應用到實際中的了.一并給出來,以供查看
initializeSelect????? = function(oid, xPath)
{
????? var xmlDoc????? = checkXMLDocObj('/EBS/XML/Login.xml');
????? var n;
????? var l;
????? var e????? = $(oid);
????? if(e!=null)
????? {
????????? n????? = xmlDoc.getElementsByTagName(xPath)[0].childNodes;
????????? l????? = n.length;
????????? for(var i=0; i<l; i++)
????????? {
????????????? var option????? = document.createElement('option');
????????????? option.value????? = n[i].getAttribute('Value');
????????????? option.innerHTML????? = n[i].getAttribute('Text');
????????????? e.appendChild(option);
????????? }
????? }
}
上面的訪問代碼中,我們是通過xmlDoc.getElementsByTagName(xPath)來進行的.
還可以通過xmlDoc.documentElement.childNodes(1)..childNodes(0).getAttribute('Text')進行訪問.
一些常用方法:
xmlDoc.documentElement.childNodes(0).nodeName,可以得到這個節點的名稱.
xmlDoc.documentElement.childNodes(0).nodeValue,可以得到這個節點的值. 這個值是來自于這樣子的xml格式:<a>b</b>, 于是可以得到b這個值.
xmlDoc.documentElement.childNodes(0).hasChild,可以判斷是否有子節點
根據我的經驗,最好是使用getElementsByTagName(xPath)的方法對節點進行訪問,因為這樣子可以直接通過xPath來定位節點,這樣子會有更好的性能.
posted @
2007-08-22 19:00 jadmin 閱讀(76) |
評論 (0) |
編輯 收藏
轉載請注明出處:http://hi.baidu.com/jadmin/
/**
*
* @(#)ZhuanzMatrix.java
*
* @author??? JAdmin
* @version?? 1.00??? 2008/08/22
*/
import java.util.Scanner;
public class ZhuanzMatrix
{
public static void main(String[] args)
{
?? int row,col;
?? Scanner sr = new Scanner(System.in);
?? System.out.println("請輸入矩陣的行和列參數:");
?? System.out.print("row=");
?? row = sr.nextInt();
?? System.out.print("col=");
?? col = sr.nextInt();
?? int[][] array = new int[row][col];
?? System.out.println("請輸入矩陣各元素Matrix[" + row + "]" + "[" + col + "]");
?? input(array);
?? System.out.println("原矩陣:");
?? display(array);
?? int[][] newarr = doZhuanz(array);
?? System.out.println("轉置后:");
?? display(newarr);
}
private static void input(int[][] arr)
{
?? Scanner sr = new Scanner(System.in);
?? for(int i = 0;i < arr.length;i++)
??? for(int j = 0;j < arr[0].length;j++)
????? arr[i][j] = sr.nextInt();
}
private static void display(int[][] arr)
{
?? for(int i = 0;i < arr.length;i++)
?? {
??? for(int j = 0;j < arr[0].length;j++)
???? System.out.print(arr[i][j]+" ");
??? System.out.println();
?? }
}
private static int[][] doZhuanz(int[][] arr)
{
?? int[][] tmparr = new int[arr[0].length][arr.length];
?? for(int i = 0;i < tmparr.length;i++)
??? for(int j = 0;j < tmparr[0].length;j++)
???? tmparr[i][j] = arr[j][i];
?? return tmparr;
}
}
posted @
2007-08-22 18:28 jadmin 閱讀(71) |
評論 (0) |
編輯 收藏
轉載請注明出處:http://hi.baidu.com/jadmin/blog/item/88a2853ea2cae8f8838b1318.html
/**
* @(#)DelColOfMatrix.java
*
* @author JAdmin
* @version 1.00 2007/8/22
*
*/
import java.util.Scanner;
public class DelColOfMatrix
{
public static void main(String[] args)
{
??? int row, col;
??? Scanner sr = new Scanner(System.in);
??? System.out.println("請輸入矩陣相關參數:");
??? System.out.print("row=");
??? row = sr.nextInt();
??? System.out.print("col=");
??? col = sr.nextInt();
??? int[][] array = new int[row][col];
??? System.out.println("輸入矩陣各元素:");
??? for (int i = 0; i < array.length; i++)
???? for (int j = 0; j < array[0].length; j++)
????? array[i][j] = sr.nextInt();
??? System.out.println("============The Matrix is============");
??? display(array);
??? System.out.println("請輸入要刪除的矩陣列序號");
??? System.out.print("delColNum=");
??? int delColNum = sr.nextInt();
??? int[][] newarr = delCol(array, delColNum);
??? System.out
????? .println("============The Matrix after Delete is============");
??? display(newarr);
}
private static void display(int[][] arr)
{
??? for (int i = 0; i < arr.length; i++)
??? {
???? for (int j = 0; j < arr[0].length; j++)
????? System.out.print(arr[i][j] + " ");
???? System.out.println();
??? }
}
private static int[][] delCol(int[][] arr, int delColNum)
{
??? int[][] tmparr = new int[arr.length][(arr[0].length - 1)];
??? for (int i = 0; i < arr.length; i++)
??? {
???? for (int j = delColNum - 1; j < arr[0].length - 1; j++)
????? arr[i][j] = arr[i][j + 1];
???? for (int k = 0; k < tmparr[0].length; k++)
????? tmparr[i][k] = arr[i][k];
??? }
??? return tmparr;
}
}
posted @
2007-08-22 09:35 jadmin 閱讀(98) |
評論 (0) |
編輯 收藏