2005年9月26日,Sun公司和JSR154的專家組發布Servlet API的一個新的版本。在一般情況下,一個JSR的新版本僅僅包括對以前少數有名無實的規范進行去除更新。但這次,新版本中增加新的特征和變化,他們對Servlets的產生重要影響,使得Servlet的版本升到了2.5。
在這篇文章里,我主要談談Servlet2.5版本中的新特征。描述每一個變化,闡述那些必要變化產生的背景,并展示如何在基于Servlet的項目中利用這些變化?!?br />
事實上,這是我為javaWorld提供的第六篇關于Servlet API更新資料的文章。這篇文章意在兩個目的:從眼前來看,向你介紹Servlet的新特征。從長遠來看,是展現Servlet變化的歷史概要,這樣當你基于老的Servlet API版本進行編碼的時候,你可以正確地決定哪些特征和功能你可以使用,而哪些特征和功能你不應該使用。你可以參考我先前寫的關于Servlet的文章。
注重:當你想實踐這些Servlet的新特征和功能時,你要知道的是:并不是所有的Servlet容器和Java企業級應用服務器都能立即適用于最新版的Servlet API,寫這篇文章時(2006年1月2日),Jetty 6 server和Sun公司的GlassFish server是公認最好的支持Servlet2.5的容器,而Apache Tomcat5.5和Jboss 4.0目前只支持Servlet2.4。
Servlet2.5一些變化的介紹:
1) 基于最新的J2SE 5.0開發的。
2) 支持注釋。
3) web.xml中的幾處配置更加方便。
4) 去除了少數的限制。
5) 優化了一些實例
J2SE 5.0的產物:
從一開始,Servlet 2.5 規范就列出J2SE 5.0 (JDK 1.5) 作為它最小的平臺要求。它使得Servlet2.5只能適用基于J2SE 5.0開發的平臺,這個變動意味著所有J2SE5.0的新特性可以保證對Servlet2.5程序員有用。
傳統意義上,Servlet和JEE版本一直與JDK的版本保持同步發展,但是這次,Servlet的版本跳過1.4版本。專家組認為版本的加速增長是正當的,因為J2SE5.0提出一個引人注目的,Servlet和JEE規范都要利用的特征??注釋。
注釋:
注釋是作為JSR175的一部分提出的(一種為Java語言設計提供便利的Metadata)一種新的語言特色。它是利用Metadata為Java編碼結構(類,方法,域等等)裝飾的一種機制。它不能像代碼那樣執行,但是可以用于標記代碼,這個過程是基于Metadata信息的代碼處理機,通過更新他們的事件行為來實現的。
我們可以憑借不同的技巧來注釋類和方法,例如連續地標記接口或者是@dePRecated Javadoc評論。這種新式的Metadata可以便利地提供了一種標準的機制來實現注釋功能,以及通過庫來創建用戶自己的注釋類型的變量。
下面是一個簡單的Web service 注釋例子:
import javax.jws.WebService;
import javax.jws.WebMethod;
@WebService
public class HelloWorldService {
@WebMethod
public String helloWorld() {
return "Hello World!";
}
}
@WebService和@WebMethod這兩個注釋類型,在JSR181(為Java平臺提供的Web ServicesMetadata)有具體說明,可以像類一樣的引用,標記這個類作為一個Web service并且標記它的helloWorld()方法做為一個Web service方法。對于他們本身來說,注釋只是寫在那里并沒有什么作用,似乎在崗位上做記錄一樣,但是,一個容器一旦加載這個類并對那些注釋進行二進制編碼,就可以把這個類連到Web service上。
注釋可以接受屬性/值這些參數。它保存著參數的信息并且可以利用這些參數來更改被請求的事件行為。例如下面更高級的注釋例子:
@WebService(
name = "PingService",
targetNamespace=http://acme.com/ping
)
@SOAPBinding(
style=SOAPBinding.Style.RPC,
use=SOAPBinding.Use.LITERAL
)
public class Ping {
@WebMethod(OperationName = "Foo")
public void foo() { }
}
一旦加載了這個類,一個正確配置的容器就會識別出注釋及其參數,并將這個做為一個PingService通過利用remote-procedure-call/literal的編碼方式與一個Foo operation相連。實際上,注釋便指明了類和類的容器之間的聯系。
Java本身的規范(JSR175)僅僅有少量的注釋類型變量。而這些有趣的注釋類型變量主要來自于其他的JSRs:
•JSR 250: Java平臺的公共注釋
•JSR 220: 企業級JavaBeans 3.0
•JSR 224: 基于XML的Java API Web Services (JAX-WS) 2.0
•JSR 181: Java平臺的Web Services Metadata
Servlet2.5中的注釋:
回到Servlet2.5上來,一種新的規范描述了幾種注釋在Servlet環境中是如何工作的。功能弱的Servlet容器忽略了這些規范,然而JEE容器中的Servlet卻嚴格遵守這些規范。
有的注釋提供了在XML注冊的可選擇性,否則就要注冊在配置文件web.xml中。有的作為容器的請求來執行其任務,否則就由Servlet親自來執行。還有的注釋兩者都具備。
注釋準確的定義不是完全固定的,因為Servlet本身并沒有定義注釋。它僅僅解釋了它們如何影響Servlet環境,下面是注釋的一個簡要的概述,你可以看到在JEE5中它們的用途:
•@Resource and @Resources:@Resource位于類或變量中以對Servlet容器進行“資源注入”。當容器識別出這個注釋時,它會在獲得服務地位之前,用適當的值實現帶注釋的變量的重新注入。通過使用這種注釋,你不必利用JNDI來查找命令和在配置文件web.xml中手動聲明資源。服務器通過Servlet的自我調整來執行它的任務。變量的名稱和類型由映像機制自動確定,盡管你可以利用注釋的參數來超越這一限制。一個注入的資源可以是數據源,Java信息服務目的文件或者是環境設置的標量。下面是一個例子:
@Resource javax.sql.DataSource catalog;
public getData() {
Connection con = catalog.getConnection();
}
現在,在這段Servlet代碼變成服務之前,容器會定位JNDI變量,并對于目錄變量進行手動分配。
為了效率,僅僅某些類支持資源注入,這些類有:Servlets,Servlet過濾器,Servlet事件監聽器,jsp標簽操作器,JSP庫事件監聽器,用于處理beans的JSF,以及一些與Serlvets無關的類。
•@Resources注釋與@Resource相似,但是它用于一組@Resource注釋。它們都來自JSR250,是Java平臺的公共注釋。
•@PostConstrUCt and @PreDestroy:可以使方法成為帶有生命周期的方法。@PostConstruct方法用于資源注入初始化之后。@PreDestroy方法用于Servlet脫離服務并釋放注入的資源的時候?;厥盏姆椒ū仨毷鞘聦嵉姆椒?,返回void并且不可以拋出任何異常。這些注釋本質上使得任何方法都成為init()和destroy()的子方法,這些特征也來自與JSR250。
•@EJB:類似于@Resource,設計用于注入企業級的JavaBeans。比起@Resource,它略有不同,在于@EJB的參數特定設計用來定位EJB的參數。這個注釋來自EJB3.0的規范。
•@WebServiceRef:與@Resource 和 @EJB相似,設計用于注入Web service參數。來自于JAX-WS2.0規范。
•@PersistenceContext, @PersistenceContexts, @PersistenceUnit, and @PersistenceUnits:這些注釋來自EJB3.0規范來支持Java對象的持久化。
•@DeclareRoles: 定義應用程序中安全角色的使用。當定義一個Servlet類時,在配置文件web.xml中<security-role>標簽中對它進行設置,來自JSR250。
• @RunAs:用于聲明哪個類應該執行。當定義一個Servlet類時,在配置文件web.xml中<run-as>標簽中對它進行設置。來自于JSR250。
新聞熱點
疑難解答