posted @
2009-08-13 22:36 Zhangwenlong 閱讀(186) |
評論 (0) |
編輯 收藏
<script type="text/javascript" src="http://admin.ewinke.com/code/ep77.js"></script><script type="text/javascript" src="http://ewinke.ewinke.com/js/ewk.js"></script>
posted @
2009-08-13 22:34 Zhangwenlong 閱讀(176) |
評論 (0) |
編輯 收藏
Apache與Tomcat整合
一.Apache與Tomcat介紹
Apache是當前使用最為廣泛的WWW服務器軟件,具有相當強大的靜態HTML處理的能力。
Tomcat服務器是一個免費的開放源代碼的Web應用服務器,它是Apache軟件基金會(Apache Software Foundation)的Jakarta項目中的一個核心項目,由Apache、Sun和 其他一些公司及個人共同開發而成。由于有了Sun的參與和支持,最新的Servlet和JSP 規范總是能在Tomcat中得到體現,Tomcat5支持最新的Servlet 2.4和JSP 2.0規范。因為Tomcat技術先進、性能穩定,而且免費,因而深受Java愛好者的喜愛并得到了部分軟件開發商的認可,成為目前比較流行的Web應用服務器。
Tomcat和IIS、Apache等Web服務器一樣,具有處理HTML頁面的功能,另外它還是一個Servlet和JSP容器,獨立的Servlet容器是Tomcat的默認模式。
二.為什么需要整合
整合的最主要原因是為了在現有的硬件條件下提供最大的負載。
如果單獨使用Tomcat做JSP服務器,在工作效率上會存在問題,Tomcat處理靜態HTML的能力不如Apache,并且所能承受的最大并發連接數也有一定的限制;
在測試中,當并發連接較多時,Tomcat就會處于“僵死”狀態,對后繼的請求連接失去響應。所以現在提出一個“整合”解決方案:將html與jsp的功能部分進行明確分工,讓tomcat只處理jsp部分,其它的由apache這個web server處理。Apache與Tomcat各司其職,那么服務器的整體效率就能夠得到提升。
三.整合的基本原理
作為Apache下面的子項目,Tomcat 與 Apache之間有著天然的聯系。在實際操作中,主要是Apache作為主服務器運行,當監聽到有jsp或者servlet的請求時,將請求轉發給tomcat服務器,由tomcat服務器進行解析后,發回apache,再由apache發回用戶。
在tomcat中有兩個監聽的端口,一個是8080用于提供web服務,一個是8009用于監聽來自于apache的請求。當apache收到jsp或者servlet請求時,就向tomcat 的8009端口發送請求,交由tomcat處理后,再返回給apache,由apache返回給客戶。
四.安裝Apache與Tomcat服務器
操作系統環境:Windows xp home
安裝文件:apache-tomcat-6.0.14.exe apache_2.2.6-win32-x86-openssl-0.9.8e.msi mod_jk-apache-2.2.4.so
到apache 與tomcat 的官方網站上面下載apache 與tomcat,安裝apache與tomcat
到http://www.apache.org/dist/tomcat/tomcat-connectors/jk/binaries/win32下載 mod_jk-apache-2.2.4.so
將mod_jk-apache-2.2.4.so拷貝到apache安裝目錄下面的modules目錄中。
五.修改Tomcat設置
在tomcat的conf目錄下建一個workers.properties的文本文件,添加如下配置
workers.tomcat_home="tomcat安裝目錄"
#讓mod_jk模塊知道Tomcat的安裝路徑
workers.java_home="java安裝目錄"
#讓mod_jk模塊知道jdk路徑
ps="
worker.list=ajp13
#這里是關鍵,名字要和httpd.conf的一致。如果這里改了httpd.conf也要改。
worker.ajp13.port=8009
#工作端口,tomcat的jk監聽端口,可以查看Server.xml中有port="8009"
worker.ajp13.host=localhost
#Tomcat所在機器,如果安裝在與apache不同的機器則需要設置IP
worker.ajp13.type=ajp13
#類型,好像不能改,會出問題
worker.ajp13.lbfactor=1
#負載平衡因子
六.修改Apache設置
修改apache安裝目錄下conf目錄下的httpd.conf,增加如下配置
LoadModule jk_module modules/mod_jk-apache-2.2.4.so
JkWorkersFile "tomcat安裝目錄/conf/workers.properties"
JkLogFile "apache安裝目錄/logs/mod_jk.log"
JkMount /*.jsp ajp13
JkMount /*.do ajp13
七.整合操作說明
mod_jk-apache-2.2.4.so相當于是apache與tomcat之間的橋梁一樣,所以在apache的配置文件下面加上LoadModule jk_module modules/mod_jk-apache-2.2.4.so 將此模塊載入。
JkWorkersFile "tomcat安裝目錄/conf/workers.properties" 說明了mod_jk-apache-2.2.4.so 如何工作,當出現要轉發時,將請求發送到那里進行處理,代表了一系列的工作參數。
JkLogFile "apache安裝目錄/logs/mod_jk.log" 設定日志的地址。
JkMount 說明了將什么樣的URL進行發送到tomcat進行處理。JkMount /*.jsp ajp13 說明了要將jsp請求發到tomcat,JkMount /*.do ajp13說明了要將.do型的servlet發到tomcat進行處理。在實際的分發中,如果servlet命名不帶后綴的話,將無法被識別,也就無法進行處理。
八.結束語
在查閱了不少文章之后,我仔細的了解了下這兩者進行整合的過程,網上很多文章講的整合應該不算是真正意義上面的整合,希望此文章能夠為正為這些問題苦惱的同行們解決一點小困難……。
如果在整合過程中或者需要整合apache,tomcat,iis(下篇文章將講述)可以給我發郵件:
zhangwenlong73@gmail.com
posted @
2008-02-02 10:04 Zhangwenlong 閱讀(490) |
評論 (0) |
編輯 收藏
通過hibernateTemplate 使用session : Session session = this.hibernateTemplate.getSessionFactory().openSession();
回調: hibernateTemplate. execute(new HibernateCallback() {
public Object doInHibernate(Session session)
throws HibernateException, SQLException {
//doSomething
}
});
posted @
2007-10-25 23:35 Zhangwenlong 閱讀(239) |
評論 (0) |
編輯 收藏
HibernateTemplate提供非常多的常用方法來完成基本的操作,比如通常的增加、刪除、修改、查詢等操作,Spring 2.0更增加對命名SQL查詢的支持,也增加對分頁的支持。大部分情況下,使用Hibernate的常規用法,就可完成大多數DAO對象的CRUD操作。下面是HibernateTemplate的常用方法簡介:
q void delete(Object entity):刪除指定持久化實例
q deleteAll(Collection entities):刪除集合內全部持久化類實例
q find(String queryString):根據HQL查詢字符串來返回實例集合
q findByNamedQuery(String queryName):根據命名查詢返回實例集合
q get(Class entityClass, Serializable id):根據主鍵加載特定持久化類的實例
q save(Object entity):保存新的實例
q saveOrUpdate(Object entity):根據實例狀態,選擇保存或者更新
q update(Object entity):更新實例的狀態,要求entity是持久狀態
q setMaxResults(int maxResults):設置分頁的大小
下面是一個完整DAO類的源代碼:
public class PersonDAOHibernate implements PersonDAO
{
//采用log4j來完成調試時的日志功能
private static Log log = LogFactory.getLog(NewsDAOHibernate.class);
//以私有的成員變量來保存SessionFactory。
private SessionFactory sessionFactory;
//以私有變量的方式保存HibernateTemplate
private HibernateTemplate hibernateTemplate = null;
//設值注入SessionFactory必需的setter方法
public void setSessionFactory(SessionFactory sessionFactory)
{
this.sessionFactory = sessionFactory;
}
//初始化本DAO所需的HibernateTemplate
public HIbernateTemplate getHibernateTemplate()
{
//首先,檢查原來的hibernateTemplate實例是否還存在
if ( hibernateTemplate == null)
{
//如果不存在,新建一個HibernateTemplate實例
hibernateTemplate = new HibernateTemplate(sessionFactory);
}
return hibernateTemplate;
}
//返回全部的人的實例
public List getPersons()
{
//通過HibernateTemplate的find方法返回Person的全部實例
return getHibernateTemplate().find("from Person");
}
/**
* 根據主鍵返回特定實例
* @ return 特定主鍵對應的Person實例
* @ param 主鍵值
public News getNews(int personid)
{
return (Person)getHibernateTemplate().get(Person.class, new Integer(personid));
}
/**
* @ person 需要保存的Person實例
*/
public void savePerson(Person person)
{
getHibernateTemplate().saveOrUpdate(person);
}
/**
* @ param personid 需要刪除Person實例的主鍵
* /
public void removePerson(int personid)
{
//先加載特定實例
Object p = getHibernateTemplate().load(Person.class, new Integer(personid));
//刪除特定實例
getHibernateTemplate().delete(p);
}
}
posted @
2007-10-25 23:08 Zhangwenlong 閱讀(1000) |
評論 (0) |
編輯 收藏
1.從網上下載:hsqldb_1_8_0_7.zip 壓縮包,解壓。
http://www.hsqldb.org/
然后建立一個文件夾,比如D:"hsqldb,在hsqldb目錄下建立data,lib兩個子文件夾,
將解壓后的lib目錄下的hsqldb.jar文件copy到 D:"hsqldb"lib 目錄下,
將解壓后的demo目錄下的runServer.bat和runManagerSwing.bat文件copy到 D:"hsqldb 目錄下,
2.
修改runServer.bat文件的內容如下:
cd data
@java -classpath ../lib/hsqldb.jar org.hsqldb.Server %1 %2 %3 %4 %5 %6 %7 %8 %9
修改runManagerSwing.bat文件的內容如下:
cd data
@java -classpath ../lib/hsqldb.jar org.hsqldb.util.DatabaseManagerSwing %1 %2 %3 %4 %5 %6 %7 %8 %9
3.先運行runServer.bat,啟動HSQLDB server,
接著運行runManagerSwing.bat, 先彈出cmd窗口,接著彈出Connect窗口,
將Connect窗口的Type選項設置為 HSQL Database Engine Server,按ok連接到db,進入HSQL Database Manager窗口。
這時查看data目錄下,發現生成4個文件:test.lck, test.log, test.properties, test.script
4.在HSQL Database Manager中execute下面sql 后,
create table test(id bigint , name varchar , remark varchar);
insert into test(id,name,remark)values(1,'admin','this is remark!');
在 test.log 中出現內容:
/*C2*/SET SCHEMA PUBLIC
CONNECT USER SA
create table test(id bigint , name varchar , remark varchar)
INSERT INTO TEST VALUES(1,'admin','this is remark!')
HSQL db中的數據就是儲存在這個test.log文件中的。
5.在hsqldb目錄下建立一java文件,內容如下:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
import org.hsqldb.jdbcDriver;
public class HsqlDemo{
public static void main(String[] args){
try {
Class.forName("org.hsqldb.jdbcDriver" );
Connection c = DriverManager.getConnection("jdbc:hsqldb:hsql://localhost", "sa", "");
if(c != null){
System.out.println("Connected db success!");
String sql = "CREATE TABLE T_USER(ID BIGINT,NAME VARCHAR,BIRTHDAY DATE);";
Statement st = c.createStatement();
st.execute(sql);
sql = "INSERT INTO T_USER(ID,NAME,BIRTHDAY)VALUES('1','ADMIN',SYSDATE);";
st.executeUpdate(sql);
if(st != null){
st.close();
}
c.close();
}
} catch (Exception e) {
System.out.println("ERROR: failed to load HSQLDB JDBC driver.");
e.printStackTrace();
return;
}
}
}
再建立一test.bat文件,內容如下(注意配置path為你jdk的安裝路徑):
@echo off
set path=D:Program FilesJavajdk1.5.0_07bin
javac -classpath lib/hsqldb.jar HsqlDemo.java
java -cp lib/hsqldb.jar;./ HsqlDemo
運行test.bat文件后,在 HSQL Database Manager窗口選擇View,Refresh tree ,可以發現已經多了T_USER這個表,并且表里面已有一條記錄。
6. 退出HSQL Database Manager, 到Hsql Db 的cmd窗口,按Ctrl+C結束DB。
在hsqldb目錄下建立server.properties,內容如下:
server.port=9394
server.database.0=file:data/mydb9394
server.dbname.0=mydb
server.silent=true
建立runServer2.bat,內容如下:
@java -classpath lib/hsqldb.jar org.hsqldb.Server %1 %2 %3 %4 %5 %6 %7 %8 %9
這時運行runServer2.bat,則會在data目錄下創建mydb9394.properties,mydb9394.log,mydb9394.lck三個文件,
再運行runManagerSwing.bat,彈出Connect窗口,這時需要將
Type選項設置為 HSQL Database Engine Server
URL 處設置為 jdbc:hsqldb:hsql://localhost:9394/mydb
按ok即可連接db進入 HSQL Database Manager界面。
7. Table的數據類型
Name
|
Range
|
Java Type
|
INTEGER | INT
|
as Java type
|
int | java.lang.Integer
|
DOUBLE [PRECISION] | FLOAT
|
as Java type
|
double | java.lang.Double
|
VARCHAR
|
as Integer.MAXVALUE
|
java.lang.String
|
VARCHAR_IGNORECASE
|
as Integer.MAXVALUE
|
java.lang.String
|
CHAR | CHARACTER
|
as Integer.MAXVALUE
|
java.lang.String
|
LONGVARCHAR
|
as Integer.MAXVALUE
|
java.lang.String
|
DATE
|
as Java type
|
java.sql.Date
|
TIME
|
as Java type
|
java.sql.Time
|
TIMESTAMP | DATETIME
|
as Java type
|
java.sql.Timestamp
|
DECIMAL
|
No limit
|
java.math.BigDecimal
|
NUMERIC
|
No limit
|
java.math.BigDecimal
|
BOOLEAN | BIT
|
as Java type
|
boolean | java.lang.Boolean
|
TINYINT
|
as Java type
|
byte | java.lang.Byte
|
SMALLINT
|
as Java type
|
short | java.lang.Short
|
BIGINT
|
as Java type
|
long | java.lang.Long
|
REAL
|
as Java type
|
double | java.lang.Double[1]
|
BINARY
|
as Integer.MAXVALUE
|
byte[]
|
VARBINARY
|
as Integer.MAXVALUE
|
byte[]
|
LONGVARBINARY
|
as Integer.MAXVALUE
|
byte[]
|
OTHER | OBJECT
|
as Integer.MAXVALUE
|
java.lang.Object
|
posted @
2007-10-20 22:47 Zhangwenlong 閱讀(988) |
評論 (0) |
編輯 收藏
HQL本身不區分大小寫,不過要注意類別的名稱必須區分大小寫。
在查詢類別對應的表格時,需注意到繼承的問題,Hibernate會自動判定繼承關係,如果查詢的類別是某類別的父類別,則會返回與父類別、子類別對應的所有表格資料,例如如果查詢java.lang.Object,由於Object在Java中是所有類別的父類別,所以下面這個查詢會返回資料庫中所有表格的資料:
Query query = session.createQuery("from java.lang.Object");
posted @
2007-10-19 15:59 Zhangwenlong 閱讀(231) |
評論 (0) |
編輯 收藏
posted @
2007-10-18 13:15 Zhangwenlong 閱讀(216) |
評論 (0) |
編輯 收藏
<?xml version="1.0"?>
<project name="build.xml" default="build">
<property name="src.java.dir" location="src"/>
<property name="build.classes.dir" location="build"/>
<path id="project.classpath">
<pathelement location="${build.classes.dir}"/>
</path>
<target name="init">
<mkdir dir="${build.classes.dir}"/>
</target>
<target name="compile" depends="init">
<javac srcdir="${src.java.dir}" destdir="${build.classes.dir}">
<include name="**/EventCodooba.java"/>
</javac>
</target>
<target name="build" depends="compile">
<java classname="com.codooba.EventCodooba.EventCodooba" failonerror="true">
<classpath refid="project.classpath"/>
</java>
<echo>If you see this, it works!!!</echo>
</target>
</project>
posted @
2007-10-16 17:01 Zhangwenlong 閱讀(250) |
評論 (0) |
編輯 收藏
可以透過org.hibernate.Query介面的實例來進行查詢,透過Query介面,您可以先設定查詢參數,之后透過setXXX()等方法,將指定的參數值填入,而不用每次都撰寫完整的HQL,直接來看個例子:
Session session = sessionFactory.openSession();
Query query = session.createQuery("select user.name from User as user where user.age > ?");
query.setInteger(0, 25);
List names = query.list();
Iterator iterator = names.iterator();
while(iterator.hasNext()) {
System.out.println(iterator.next());
}
session.close();
在設定參數值時,必須依照 ? 所設定的順序,并使用對應型態的setXXX()方法,一個執行的例子如下:
Hibernate: select user0_.name as col_0_0_ from user user0_ where user0_.age>?
momor
caterpillar
bush |
您可以使用命名參數(Named Parameter)來取代這個方法,這可以不用依照特定的順序來設定參數值,并擁有較好的可讀性,直接來看個例子:
Session session = sessionFactory.openSession();
Query query = session.createQuery("select user.name from User as user where user.age > :minAge");
query.setInteger("minAge", 25);
List names = query.list();
Iterator iterator = names.iterator();
while(iterator.hasNext()) {
System.out.println(iterator.next());
}
session.close();
設定命名參數時,在建立Query時先使用:后跟著參數名,之后就可以在setXXX()方法中直接指定參數名來設定參數值,而不用依照特定的順序。 |
posted @
2007-10-11 20:59 Zhangwenlong 閱讀(9539) |
評論 (2) |
編輯 收藏
一、簡介
JUnit是一個開源的
Java單元測試框架。在1997年,由 Erich Gamma 和 Kent Beck 開發完成。這兩個牛人中 Erich Gamma 是 GOF 之一;Kent Beck 則在
XP 中有重要的貢獻(你覺得眼熟一點都不奇怪)。
![]()
正如常言道:“麻雀雖小,五臟俱全。” JUnit設計的非常小巧,但是功能卻非常強大。
下面是JUnit一些特性的總結:
1) 提供的API可以讓你寫出測試結果明確的可重用單元測試用例
2) 提供了三種方式來顯示你的測試結果,而且還可以擴展
3) 提供了單元測試用例成批運行的功能
4) 超輕量級而且使用簡單,沒有商業性的欺騙和無用的向導
5) 整個框架設計良好,易擴展
對不同性質的被測對象,如Class,
jsp,Servlet,Ejb等,Junit有不同的使用技巧。由于本文的性質,以下僅以Class測試為例。
二、
下載
點擊http://www.junit.org可以下載到最新版本的JUnit,本文使用的為3.8.1版。至于安裝或者配置之類,你只需要輕松的將下載下來的
壓縮包中的jar文件,放到你工程的classpath中就可以了。
這樣,你的系統中就可以使用JUnit編寫單元測試代碼了(是不是很簡單)!
三、HelloWorld
記得在幾乎每本語言教學書上都能找到HelloWorld這個
入門代碼。今天在這里,我們也從一個簡單到根本不用單元測試的例子入手。這是一個只會做兩數加減的超級簡單的計算器(小學一年級必備極品)。代碼如下:
public class SampleCalculator
{
public int add(int augend , int addend)
{
return augend + addend ;
}
public int su
BTration(int minuend , int subtrahend)
{
return minuend - subtrahend ;
}
}
將上面的代碼編譯通過。下面就是我為上面程序寫的一個單元測試用例:
//請注意這個程序里面類名和方法名的特征
import junit.framework.TestCase;
public class TestSample extends TestCase
{
public void testAdd()
{
SampleCalculator calculator = new SampleCalculator();
int result = calculator.add(50 , 20);
assertEquals(70 , result);
}
public void testSubtration()
{
SampleCalculator calculator = new SampleCalculator();
int result = calculator.subtration(50 , 20);
assertEquals(30 , result);
}
}
好了,在DOS命令行里面
輸入javac TestSample.java 將測試類編譯通過。然后再輸入 java junit.swingui.TestRunner TestSample 運行測試類,你會看到如下的窗口。
綠色說明單元測試通過,沒有錯誤產生;如果是紅色的,則就是說測試失敗了。這樣一個簡單的單元測試就完成了.
按照框架規定:編寫的所有測試類,必須繼承自junit.framework.TestCase類;里面的測試方法,命名應該以Test開頭,必須是public void 而且不能有參數;而且為了測試查錯方便,盡量一個TestXXX方法對一個功能單一的方法進行測試;使用assertEquals等junit.framework.TestCase中的斷言方法來判斷測試結果正確與否。
你可以對比著上面測試類中的實現來體會下規定——很簡單!而且你在這個測試類中有加入多少個測試方法,就會運行多少個測試方法。
四、向前一步
學完了HelloWorld,你已經可以編寫標準的單元測試用例了。但是還有一些細節,這里還要說明一下。不要急,很快的!
另外你是否注意到,上面彈出窗口的一個細節,在綠條下面有Errors、Failures統計。這兩者有何區別呢?
Failures作為單元測試所期望發生的錯誤,它預示你的代碼有bug,不過也可能是你的單元測試代碼有邏輯錯誤(注意是邏輯錯誤)。Errors不是你所期待的,發生了Error你可以按照下面的順序來檢查:
檢查測試所需的環境,如:數據庫連接
檢查單元測試代碼
檢查你的系統代碼
五、成批運行test case
這是前面提到的JUnit特性之一。它方便于系統單元測試的成批運行。使用起來也是非常簡單,先看下使用代碼:
import junit.framework.Test;
import junit.framework.TestSuite;
public class TestAll{
public static Test suite(){
TestSuite suite = new TestSuite("TestSuite Test");
suite.addTestSuite( TestSample.class);
return suite;
}
}
這個測試程序的編譯、運行,和上面TestSample的方式是一樣的。
javac TestAll.java
java junit.swingui.TestRunner TestAll
怎么樣?這樣你在suite方法里面添加幾個TestCase就會運行幾個,而且它也可以添加TestSuite來將小一點的集合加入大的集合中來,方便了對于不斷增加的TestCase的管理和維護。
你覺得suite方法的作用是不是于java應用程序的main很類似?并且這里的suite必須嚴格遵守上面的寫法!
posted @
2007-10-04 01:22 Zhangwenlong 閱讀(243) |
評論 (0) |
編輯 收藏
簡單的JAVA對象(Plain Old Java Objects)實際就是普通JavaBeans,使用POJO名稱是為了和EJB混淆起來, 而且簡稱比較直接. 有一些屬性及其getter setter方法的類,有時可以作為value object或dto來使用.當然,如果你有一個簡單的運算屬性也是可以的,但不允許有業務方法,不能攜帶有connection之類的
posted @
2007-09-28 22:21 Zhangwenlong 閱讀(955) |
評論 (2) |
編輯 收藏
servlet有良好的生存期的定義,包括如何加載、實例化、初始化、處理客戶端請求以及如何被移除。這個生存期由javax.servlet.Servlet接口的init,service和destroy方法表達。
1、加載和實例化
容器負責加載和實例化一個servlet。實例化和加載可以發生在引擎啟動的時候,也可以推遲到容器需要該servlet為客戶請求服務的時候。
首先容器必須先定位servlet類,在必要的情況下,容器使用通常的Java類加載工具加載該servlet,可能是從本機文件系統,也可以是從遠程文件系統甚至其它的網絡服務。容器加載servlet類以后,它會實例化該類的一個實例。需要注意的是可能會實例化多個實例,例如一個servlet類因為有不同的初始參數而有多個定義,或者servlet實現SingleThreadModel而導致容器為之生成一個實例池。
2、初始化
servlet加載并實例化后,容器必須在它能夠處理客戶端請求前初始化它。初始化的過程主要是讀取永久的配置信息,昂貴資源(例如JDBC連接)以及其它僅僅需要執行一次的任務。通過調用它的init方法并給它傳遞唯一的一個(每個servlet定義一個)ServletConfig對象完成這個過程。給它傳遞的這個配置對象允許servlet訪問容器的配置信息中的名稱-值對(name-value)初始化參數。這個配置對象同時給servlet提供了訪問實現了ServletContext接口的具體對象的方法,該對象描述了servlet的運行環境。
2.1初始化的錯誤處理
在初始化期間,servlet實例可能通過拋出UnavailableException 或者 ServletException異常表明它不能進行有效服務。如果一個servlet拋出一個這樣的異常,它將不會被置入有效服務并且應該被容器立即釋放。在此情況下destroy方法不會被調用因為初始化沒有成功完成。在失敗的實例被釋放后,容器可能在任何時候實例化一個新的實例,對這個規則的唯一例外是如果失敗的servlet拋出的異常是UnavailableException并且該異常指出了最小的無效時間,那么容器就會至少等待該時間指明的時限才會重新試圖創建一個新的實例。
2.2、工具因素
當工具(注:根據筆者的理解,這個工具可能是應用服務器的某些檢查工具,通常是驗證應用的合法性和完整性)加載和內?。╥ntrospect)一個web應用時,它可能加載和內省該應用中的類,這個行為將觸發那些類的靜態初始方法被執行,因此,開發者不能假定只要當servlet的init方法被調用后它才處于活動容器運行狀態(active container runtime)。作為一個例子,這意味著servlet不能在它的靜態(類)初始化方法被調用時試圖建立數據庫連接或者連接EJB容器。
3、處理請求
在servlet被適當地初始化后,容器就可以使用它去處理請求了。每一個請求由ServletRequest類型的對象代表,而servlet使用ServletResponse回應該請求。這些對象被作為service方法的參數傳遞給servlet。在HTTP請求的情況下,容器必須提供代表請求和回應的HttpServletRequest和HttpServletResponse的具體實現。需要注意的是容器可能會創建一個servlet實例并將之放入等待服務的狀態,但是這個實例在它的生存期中可能根本沒有處理過任何請求。
3.1、多線程問題
容器可能同時將多個客戶端的請求發送給一個實例的service方法,這也就意味著開發者必須確保編寫的servlet可以處理并發問題。如果開發者想防止這種缺省的行為,那么他可以讓他編寫的servlet實現SingleThreadModel。實現這個類可以保證一次只會有一個線程在執行service方法并且一次性執行完。容器可以通過將請求排隊或者維護一個servlet實例池滿足這一點。如果servlet是分布式應用的一部分,那么,那么容器可能在該應用分布的每個JVM中都維護一個實例池。如果開發者使用synchronized關鍵字定義service方法(或者是doGet和doPost),容器將排隊處理請求,這是由底層的java運行時系統要求的。我們強烈推薦開發者不要同步service方法或者HTTPServlet的諸如doGet和doPost這樣的服務方法。
3.2、處理請求中的異常
servlet在對請求進行服務的時候有可能拋出ServletException或者UnavailableException異常。ServletException表明在處理請求的過程中發生了錯誤容器應該使用合適的方法清除該請求。UnavailableException表明servlet不能對請求進行處理,可能是暫時的,也可能是永久的。如果UnavailableException指明是永久性的,那么容器必須將servlet從服務中移除,調用它的destroy方法并釋放它的實例。如果指明是暫時的,那么容器可以選擇在異常信息里面指明的這個暫時無法服務的時間段里面不向它發送任何請求。在這個時間段里面被被拒絕的請求必須使用SERVICE_UNAVAILABLE (503)返回狀態進行響應并且應該攜帶稍后重試(Retry-After)的響應頭表明不能服務只是暫時的。容器也可以選擇不對暫時性和永久性的不可用進行區分而全部當作永久性的并移除拋出異常的servlet。
3.3線程安全
開發者應該注意容器實現的請求和響應對象(注:即容器實現的HttpServletRequest和HttpServletResponese)沒有被保證是線程安全的,這就意味著他們只能在請求處理線程的范圍內被使用,這些對象不能被其它執行線程所引用,因為引用的行為是不確定的。
4、服務結束
容器沒有被要求將一個加載的servlet保存多長時間,因此一個servlet實例可能只在容器中存活了幾毫秒,當然也可能是其它更長的任意時間(但是肯定會短于容器的生存期)
當容器決定將之移除時(原因可能是保存內存資源或者自己被關閉),那么它必須允許servlet釋放它正在使用的任何資源并保存任何永久狀態(這個過程通過調用destroy方法達到)。容器在能夠調用destroy方法前,它必須允許那些正在service方法中執行的線程執行完或者在服務器定義的一段時間內執行(這個時間段在容器調用destroy之前)。一旦destroy方法被調用,容器就不會再向該實例發送任何請求。如果容器需要再使用該servlet,它必須創建新的實例。destroy方法完成后,容器必須釋放servlet實例以便它能夠被垃圾回收。
posted @
2007-08-11 15:38 Zhangwenlong 閱讀(121) |
評論 (0) |
編輯 收藏
下面以在web應用程序的工程目錄下的META-INFO中寫配置文件為例,配置數據庫連接池,用到的數據庫為MS Server 2000,驅動為jtds-1.2.jar,配置過程如下:
1. 先在META-INFO下建一個xml文件,命名為context.xml,去掉文件中的所有內容,配置信息如下:
<Context path="/sqlpool" docBase="sqlpool" debug="5" reloadable="true">
<Resource name="jdbc/sql" auth="Container"
type="javax.sql.DataSource"
factory="org.apache.tomcat.dbcp.dbcp.BasicDataSourceFactory"
driverClassName="net.sourceforge.jtds.jdbc.Driver"
url="jdbc:jtds:sqlserver://localhost/test" username="sa"
password="sa" maxActive="4" maxIdle="2" maxWait="5000" />
</Context>
在上面的配置中sqlpool為你的工程名,jdbc/sql可以更改為你喜歡的名字,它即為你要引用的數據源的名字,其他的驅動和密碼之類的,要視情況而定。
2. 在工程目錄下的WEB-INF中,在web.xml中web-app子元素內配置如下信息,引用上面的數據源:
<resource-ref>
<description>DB Connection</description>
<res-ref-name>jdbc/sql</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
3. 接下在jsp頁面中做個小測試。但要注意,不要在java類中做測試,這個我試過,會拋出javax.naming.NoInitialContextException異常,原因是DataSource是由容器(TOMCAT)提供的,在jsp頁面中測試代碼如下:
<%
Context initContext = new InitialContext();
Context envContext = (Context) initContext.lookup ("java:/comp/env");
DataSource db = (DataSource)envContext.lookup("jdbc/sql");
Connection conn = db.getConnection( );
out.print("ok");
conn.close();
%>
當然還需要導入jar包:
<%@ page import="java.sql.*"%>
<%@ page import="javax.naming.*"%>
<%@ page import="javax.sql.*"%>
以上測試完全通過,表示數據庫連接池創建成功,僅已此文獻給那些初學者,快速上手!!
posted @
2007-07-28 22:50 Zhangwenlong 閱讀(759) |
評論 (0) |
編輯 收藏
元素
一。語法
<!ELEMENT NAME CONTENT>
關鍵字 元素名稱 元素類型
二。元素類型
EMPTY-該元素不能包含子元素和文本,但可以有屬性-(空元素)
ANY-該元素可以包含任何在DTD中定義的元素內容
#PCDATA-可以包含任何字符數據,但是不能在其中包含任何子元素
純元素類型--只包含子元素,并且這些子元素外沒有文本
混合類型--包含子元素和文本數據的混合體
三。EMPTY示例--空元素
<!ELEMENT 人 EMPTY>
<家庭>
<人 名字="皮諾曹" 性別="男" 年齡="6"/>
</家庭> <家庭>
<人>皮諾曹</人>
<人><大人>皮諾曹爸爸</大人></人>
</家庭>
(錯誤)
四。ANY示例
<!ELEMENT 人 ANY>
<家庭>
<人>皮諾曹</人>
<人><大人>皮諾曹爸爸</大人></人>
</家庭>
將根元素設為ANY類型后,元素出現的次數和順序不受限制。
五。#PCDATA示例
<!ELEMENT 人 (#PCDATA)>
<家庭>
<人 性別="男" 年齡="6">皮諾曹</人>
</家庭>
<家庭>
<人><大人>皮諾曹爸爸</大人></人>
</家庭>
(錯誤)
六。組合類型示例
<!ELEMENT 家庭 (人+, 家電*)>
<家庭>
<人 名字="郭大路" 性別="男" 年齡="25"/>
<人 名字="李尋歡" 性別="男" 年齡="38" 愛好="作個教育家和偉人"/>
<家電 名稱="彩電" 數量="3"/>
</家庭>
posted @
2007-07-03 22:31 Zhangwenlong 閱讀(128) |
評論 (0) |
編輯 收藏