java讀書心得(精選3篇)
java讀書心得 篇1
注:框架可以用word菜單中的 “視圖/文檔結構圖” 看到
j2ee模式
value object(值對象) 用于把數據從某個對象/層傳遞到其他對象/層的任意java對象。
通常不包含任何業務方法。
也許設計有公共屬性,或者提供可以獲取屬性值的get方法。
jsp
1.jsp的基礎知識
__
_____ | directive (指令)
| |-- scripting (腳本)
jsp -------| |__ action (動作)
|
|_____template data :除jsp語法外,jsp引擎不能解讀的東西
1)在jsp中使用的directive(指令)主要有三個:
a) page指令
b) include指令
c) taglib指令
在jsp的任何地方,以任何順序,一個頁面可以包含任意數量的page指令
2)scripting(腳本)包括三種類型
a) ;
b) ;
c) ;
3)action(動作)
標準的動作類型有:
a) ;
b) ;
d) ;
e) ;
f) ;
g) ;
h) ; 日記日記300字
1. 注釋: ;
;
2. ;
session可以不賦值,默認為true,如果session=”false”,則在jsp頁面中,隱含的變量session就不能使用。
3. 請求控制器結構(request controller)
也被稱之為jsp model 2 architecture
這種途徑涉及到使用一個servlet或一個jsp作為一個應用程序或一組頁面的入口點。
為創建可維護的jsp系統,request controller是最有用的方式之一。
不是jsp,而是java類才是放置控制邏輯的正確的地方。
請求控制器的命名模式為: controller.jsp
請求控制器類的命名模式為: requestcontroller
2.jsp中的javabean
jsp三種bean的類型
1) 頁面bean
2) 會話bean
3) 應用bean
大多數的系統會使用一個會話bean來保持狀態,而對每一個頁面使用一個頁面bean 來對復雜的數據進行表示。
頁面bean是一個模型,而jsp是一個視圖。
3.custom tag
bean是信息的攜帶者,
而tag更適用于處理信息。
標記庫包含一個標記庫描述符(tld)和用于實現custom tag的java類
在翻譯階段,jsp容器將使用tld來驗證頁面中的所有的tag是否都被正確的使用。
標記處理程序只是一個簡單的適配器,而真正的邏輯是在另一個類中實現的,標記處理程序只是提供了一個供其他的可復用的類的jsp接口
servlet
1.servletconfig
一個servletconfig對象是servlet container在servlet initialization的時候傳遞給servlet的。
servletconfig包涵 servletcontext 和 一些 name/value pair (來自于deployment descriptor)
servletcontext接口封裝了web應用程序的上下文概念。
2.會話跟蹤
1) session
當一個client請求多個servlets時,一個session可以被多個servlet共享。
通常情況下,如果server detect到browser支持cookie,那么url就不會重寫。
2) cookie
在java servlet中,如果你光 cookie cookie = new cookie(name,value)
那么當用戶退出browser時,cookie會被刪除掉,而不會被存儲在客戶端的硬盤上。
如果要存儲 cookie,需加一句 cookie.setmaxage(200)
cookie是跟某一個server相關的,運行在同一個server上的servlet共享一個cookie.
3) url rewriting
在使用url rewriting來維護session id的時候,每一次http請求都需要encodeurl
典型的用在兩個地方
1) out.print(“form action=\” ”);
out.print(response.encodeurl(“sessionexample”));
out.print(“form action=\” ”);
out.print(“method = get>;”);
2) out.print(“
;
out.print(response.encodeurl(“sessionexample?database=foo&datavalue=bar”));
out.println(“\” >;url encoded ;”);
3.singlethreadmodel
默認的,每一個servlet definition in a container只有一個servlet class的實例。
只有實現了singlethreadmodel,container才會讓servlet有多個實例。
servlet specification上建議,不要使用synchronized,而使用singlethreadmodel。
singlethreadmodel(沒有方法)
保證servlet在同一時刻只處理一個客戶的請求。
singlethreadmodel是耗費資源的,特別是當有大量的請求發送給servlet時,singlethreadmodel的作用是使包容器以同步時鐘的方式調用service方法。
這等同于在servlet的service方法種使用synchronized.
single thread model一般使用在需要響應一個heavy request的時候,比如是一個需要和數據庫打交道的連接。
2. 在重載servlet地init( )方法后,一定要記得調用super.init( );
3. the client通過發送一個blank line表示它已經結束request
而the server通過關閉the socket來表示response已結束了。
4. 一個http servlet可以送三種東西給client
1) a single status code
2) any number of http headers
3) a response body
5. servlet之間信息共享的一個最簡單的方法就是
system.getproperties.put(“key”,”value”);
6. post和get
post:將form內各字段名稱和內容放置在html header內傳送給server
get: ?之后的查詢字符串要使用urlencode,經過urlencode后,這個字符串不再帶有空格,以后將在server上恢復所帶有的空格。
get是web上最經常使用的一種請求方法,每個超鏈接都使用這種方法。
7. web.xml就是web applicatin 的deployment descriptor
作用有:組織各類元素
設置init param
設置安全性
8. request dispatcher用來把接收到的request forward processing到另一個servlet
要在一個response里包含另一個servlet的output時,也要用到request dispatcher.
9. servlet和jsp在同一個jvm中,可以通過serveltcontext的
setattribute( )
getattribute( )
removeattribute( )
來共享對象
10. 利用request.getparameter( )得到的string存在字符集問題。
可以用 strtitle = request.getparameter(“title”);
strtitle = new string(strtitle.getbytes(“8859-1”),”gb2312”);
如果你希望得到更大得兼容性
string encoding = response.getcharacterencoding;
//確定application server用什么編碼來讀取輸入的。
strtitle = new string(strtitle.getbytes(encoding),”gb2312”);
xml
1.xml基礎知識
1. 一個xml文檔可以分成兩個基本部分:
首部( header )
內容( content )
2. xml名字空間規范中指定:
xml文檔中的每一個元素都處在一個名字空間中;如果沒有指定的名字空間,缺省的名字空間就是和該元素相關聯的名字空間。
3. a document that is well-formed obeys all of the rules of xml documents (nested tags, etc.)
" if a well-formed document uses a document type definition (more on these in a minute), and it follows all the rules of the dtd, then it is also a valid document
4. a tag is the text between the ;
" an element is the start tag, the end tag,and everything (including other elements) in between
5. 標簽( tags ) 實際上包含了“元素”( elements ) 和 “屬性”( attributes )兩部分。
用元素( elements )來描述有規律的數據。
用屬性( attributes ) 來描述系統數據。
如果你有一些數據要提供給某個應用程序,該數據就可能要用到一個元素。
如果該數據用于分類,或者用于告知應用程序如何處理某部分數據,或者該數據從來沒有直接對客戶程序公開,那么它就可能成為一種屬性。
6. cdata (讀作:c data ) c是character的縮寫。
.xml.sax.reader
/|\
org.xm.l.sax.xmlreader
/|\
org.apche.xerces.parsers.saxparser
2.webservice
2.1 webservice的基本概念
webservice是一種可以接收從internet或者intranet上的其它系統中傳遞過來的請求,輕量級的獨立的通訊技術。
這種技術允許網絡上的所有系統進行交互。隨著技術的發展,一個web服務可以包含額外的指定功能并且可以在多個b2b應用中協作通訊。
web服務可以理解請求中上下文的關系,并且在每一個特定的情況下產生動態的結果。這些服務會根據用戶的身份,地點以及產生請求的原因來改變不同的處理,用以產生一個唯一的,定制的方案。這種協作機制對那些只對最終結果有興趣的用戶來說,是完全透明的。
uddi
在用戶能夠調用web服務之前,必須確定這個服務內包含哪些商務方法,找到被調用的接口定義,還要在服務端來編制軟件。所以,我們需要一種方法來發布我們的web服務。
uddi (universal description, discovery, and integration) 是一個主要針對web服務供應商和使用者的新項目。uddi 項目中的成員可以通過uddi business registry (ubr) 來操作web服務的調用,ubr是一個全球性的服務。
web服務供應商可以在ubr中描述并且注冊他們的服務。
用戶可以在ubr中查找并定位那些他們需要的服務。
uddi是一種根據描述文檔來引導系統查找相應服務的機制。
uddi包含標準的“白皮書”類型的商業查詢方式,
“黃皮書”類型的局部查找,以及
“綠皮書”類型的服務類型查找。
uddi利用soap消息機制(標準的xml/http)來發布,編輯,瀏覽以及查找注冊信息。它采用xml格式來封裝各種不同類型的數據,并且發送到注冊中心或者由注冊中心來返回需要的數據。
wsdl
對于商業用戶來說,要找到一個自己需要使用的服務,他必須知道如何來調用。
wsdl (web services description language) 規范是一個描述接口,語義以及web服務為了響應請求需要經常處理的工作的xml文檔。這將使簡單地服務方便,快速地被描述和記錄。
以下是一個wsdl的樣例:
targetnamespace=""
xmlns:tns="" (5)(6)(7)(8)(9)(10)(11)(12)(13)(14)(15)
xmlns:xsd1=""
xmlns:soap=";
xmlns=";>;
xmlns=";>;
type="tns:stockquoteporttype">;
transport=";/>;
soapaction=""/>;
;my first service;
它包含了以下的關鍵信息:
消息的描述和格式定義可以通過xml文檔中的;和; 標記來傳送。
; 標記中表示了消息傳送機制。 (e.g. request-only, request-response, response-only) 。
; 標記指定了編碼的規范 。
; 標記中表示服務所處的位置 (url)。
wsdl在uddi中總是作為一個接口描述文檔。因為uddi是一個通用的用來注冊wsdl規范的地方,uddi的規范并不限制任何類型或者格式描述文檔。這些文檔可能是一個wsdl文檔,或者是一個正規的包含導向文檔的web頁面,也可能只是一個包含聯系信息的電子郵件地址。
現在java提供了一個 java api for wsdl (jwsdl)規范。它提供了一套能快速處理wsdl文檔的方法,并且不用直接對xml文檔進行操作,它會比jaxp更方便,更快速。
soap
當商業用戶通過uddi找到你的wsdl描述文檔后,他通過可以simple object access protocol (soap) 調用你建立的web服務中的一個或多個操作。
soap是xml文檔形式的調用商業方法的規范,它可以支持不同的底層接口,象http(s)或者smtp。
之所以使用xml是因為它的獨立于編程語言,良好的可擴展性以及強大的工業支持。之所以使用http是因為幾乎所有的網絡系統都可以用這種協議來通信,由于它是一種簡單協議,所以可以與任何系統結合,還有一個原因就是它可以利用80端口來穿越過防火墻。
soap的強大是因為它簡單。soap是一種輕量級的,非常容易理解的技術,并且很容易實現。它有工業支持,可以從各主要的電子商務平臺供應商那里獲得。
從技術角度來看,soap詳細指明了如何響應不同的請求以及如何對參數編碼。一個soap封裝了可選的頭信息和正文,并且通常使用http post方法來傳送到一個http 服務器,當然其他方法也是可以的,例如smtp。soap同時支持消息傳送和遠程過程調用。以下是一個soap請求。
post /stockquote http/1.1
host: www.stockquoteserver
content-type: text/xml; charset="utf-8"
content-length: nnnn
soapaction: "some-uri"
xmlns:soap-env=";
〖5〗〖6〗〖7〗〖8〗〖9〗〖10〗〖11〗〖12〗〖13〗〖14〗〖15〗
soap-env:encodingstyle=";/>;
;sunw;
jaxr
為了支持uddi在java平臺上的功能,java apis for xml registries (jaxr)允許開發者來訪問注冊中心。
值得注意的是,jaxr并不是建立web服務必需的,你可以利用其他常用的xml apis來直接集成這些協議。
jaxr是一個方便的api,它提供了java api來發布,查找以及編輯那些注冊信息。它的重點在于基于xml的b2b應用,復雜的地址本查找以及對xml消息訂閱的支持等web服務。
它也可以用來訪問其他類型的注冊中心,象ebxml注冊中心。
這些對web服務的注冊信息進行的操作,可以使用當前的一些web服務工具來完成(例如第三方的soap和ebxml消息工具)。另外,當jaxp提供了一致并具有針對性的api來完成這些操作,這將使開發變得更加容易。
jax/rpc
為了使開發人員專注于建立象soap那樣的基于xml的請求,jcp正在開發基于rpc (jax/rpc) 的java api。jax/rpc是用來發送和接收方法調用請求的,它基于xml協議,象soap,或者其他的象xmlp (xml protocol,要了解更多可以參考)。jax/rpc使你不用再關注這些協議的規范,使應用的開發更快速。不久,開發人員就不用直接以xml表示方法調用了。
目前有很多第三方實現了soap,開發人員可以在不同的層次上調用soap,并選擇使用哪一種。將來,jax/rpc會取代這些apis并提供一個統一的接口來構造以及處理soap rpc請求。
在接收一個從商業伙伴那里過來的soap請求的時候,一個java servlet用jax/rpc來接收這個基于xml的請求。一旦接收到請求后,servlet會調用商務方法,并且把結果回復給商業伙伴。
jaxm
當從商業合作伙伴那里接收一個web服務的請求時,我們需要java api實現一個servlet來處理ebxml消息,就象我們用jax/rpc來處理soap請求一樣。
java api for xml messaging (jaxm) 是集成xml消息標準(象ebxml消息或者soap消息)的規范。
這個api是用來推動xml消息處理的,它檢測那些預定單的消息格式以及約束。它控制了所有的消息封裝機制,用一種直觀的方式分割了消息中的信息,象路由信息,發貨單。這樣,開發人員只要關注消息的有效負載,而不用去擔心那些消息的重復處理。
目前的開發人員用jaxp來實現jaxm將要提供的功能,jaxm將會提供一套非常具有針對性的api來處理基于xml的消息傳送。這將大大簡化開發人員的代碼,并使它們具有統一的接口。
jaxm和jax/rpc的差別在于處理消息導向的中間件以及遠程過程調用的不同。jaxm注重于消息導向,而jax/rpc是用來完成遠程過程調用的。以下是圖解。
請注意,在jaxm 和 jax/rpc技術成熟之前,開發人員還是依賴于第三方的soap apis,象apache soap, idooxoap, 以及 glue。當jaxm 和 jax/rpc正式發布后,它將為當前不同的soap和ebxml消息提供統一的接口。就象jdbc位多種不同的數據庫提供統一的接口。
jaxb
xml綁定技術可以把xml文檔和java對象進行自由轉換。
用jaxb,你可以在后臺的ejb層,把xml文檔轉換成java對象。同樣你也可以把從ejb中取出的java對象轉換成xml文檔返回給用戶。
jaxb接口提供了比sax和dom更高級的方法來處理xml文檔。它提供的特性可以在xml數據和java類之間互相映射,提供了一個簡單的方法來轉換xml數據。它比逐個解析標記更簡單。
2.2 建立weservice的步驟
在建立weservice的時候,有三個主要步驟:
1.建立客戶端聯接
為了允許applets,applications,商業合作伙伴,瀏覽器和pdas 使用web服務。
2.實現web服務
包括工作流,數據傳送,商業邏輯以及數據訪問。這些功能是隱藏在web服務后,并且為客戶端工作的。
3.聯接后臺系統
這個系統可能包括一個或多個數據庫,現存的企業信息系統,商業合作伙伴自己的系統或者web服務,以及在多個系統中共享的數據。
基于j2ee的web服務的核心構架:
rmi
1. rmi-iiop
2. rmi 是在java中使用remote method invocation的最初的方法,rmi使用java.rmi包
rmi-iiop 是rmi的一個特殊版本,rmi-iiop可以和corba兼容,rmi-iiop使用java.rmi包和javax.rmi
jaf(java活動構架)
開發者可以使用jaf來決定任意一塊數據的類型、封裝對數據的訪問、尋找合適的操作、實例化相關的bean來執行這些操作等。
例如,javamail就是使用jaf根據mime類型來決定實例化那一個對象。
ejb
1. ejb組件實現代碼的限制
ejb組件的約束
ejb的開發者并不需要在ejb的組件實現代碼中編寫系統級的服務,ejb提供商/開發
者需知道并且嚴格地遵守一些限制,這些限制與開發穩定的和可移植的ejb組件的利益有 <1><2><3><4><5><6><7><8><9><10><11><12><13><14><15>
關。
以下是你應該回避使用的一些java特色,并且在你的ejb組件的實現代碼中要嚴格限
制它們的使用:
1.使用static,非final 字段。建議你在ejb組件中把所有的static字段都聲明為final型的。這樣可以保證前后一致的運行期語義,使得ejb容器有可以在多個java虛擬機之間分發組件實例的靈活性。
2.使用線程同步原語來同步多個組件實例的運行。避免這個問題,你就可以使ejb容器靈活的在多個java虛擬機之間分發組件實例。
3.使用awt函數完成鍵盤的輸入和顯示輸出。約束它的原因是服務器方的商業組件意味著提供商業功能而不包括用戶界面和鍵盤的i/o功能。
4.使用文件訪問/java.io 操作。ejb商業組件意味著使用資源管理器如jdbc來存儲和檢索數據而不是使用文件系統api。同時,部署工具提供了在部署描述器(descriptor)中存儲環境實體,以至于ejb組件可以通過環境命名上下文用一種標準的方法進行環境實體查詢。所以,使用文件系統的需求基本上是被排除了。
5.監聽和接收socket連接,或者用socket進行多路發送。ejb組件并不意味著提供網絡socket服務器功能,但是,這個體系結構使得ejb組件可以作為socket客戶或是rmi客戶并且可以和容器所管理的環境外面的代碼進行通訊。
6.使用映象api查詢ejb組件由于安全規則所不能訪問的類。這個約束加強了java平臺的安全性。
7.欲創建或獲得一個類的加載器,設置或創建一個新的安全管理器,停止java虛擬機,改變輸入、輸出和出錯流。這個約束加強了安全性同時保留了ejb容器管理運行環境的能力。
8.設置socket工廠被url's serversocket,socket和stream handler使用。避免這個特點,可以加強安全性同時保留了ejb容器管理運行環境的能力。
9.使用任何方法啟動、停止和管理線程。這個約束消除了與ejb容器管理死鎖、線程
和并發問題的責任相沖突的可能性。
通過限制使用10-16幾個特點,你的目標是堵上一個潛在的安全漏洞:
10.直接讀寫文件描述符。
11.為一段特定的代碼獲得安全策略信息。
12.加載原始的類庫。
13.訪問java一般角色所不能訪問的包和類。
14.在包中定義一個類。
15.訪問或修改安全配置對象(策略、安全、提供者、簽名者和實體)。
16.使用java序列化特點中的細分類和對象替代。
17.傳遞this引用指針作為一個參數或者作為返回值返回this引用指針。你必須使用
sessioncontext或entitycontext中的getejbobject的結果。
java2平臺的安全策略
以上所列的特點事實上正是java編程語言和java2標準版中的標準的、強有力的特色。ejb容器允許從j2se中使用一些或全部的受限制的特色,盡管對于ejb組件是不可用的,但需通過j2se的安全機制來使用而不是通過直接使用j2se的api。
java2平臺為ejb1.1規范中的ejb容器所制定的安全策略定義了安全許可集,這些許可在ejb組件的編程限制中出現。通過這個策略,定義了一些許可諸如:java.io.filepermission,.netpermission,java.io.reflect.reflectpermission,java.lang.security.securitypermission,以便加強先前所列出的編程限制。
許多ejb容器沒有加強這些限制,他們希望ejb組件開發者能遵守這些編程限制或者是帶有冒險想法違背了這些限制。違背這些限制的ejb組件,比標準方法依賴過多或過少的安全許可,都將很少能在多個ejb容器間移植。另外,代碼中都將隱藏著一些不確定的、難以預測的問題。所有這些都足以使ejb組件開發者應該知道這些編程限制,同時也應該認真地遵守它們。
任何違背了這些編程限制的ejb組件的實現代碼在編譯時都不能檢查出來,因為這些特點都是java語言和j2se中不可缺少的部分。
對于ejb組件的這些限制同樣適用于ejb組件所使用的幫助/訪問(helper/access)類,j2ee應用程序使用java文檔(jar)文件格式打包到一個帶.ear(代表enterprise archive)擴展名的文件中,這個ear文件對于發送給文件部署器來說是標準的格式。ear文件中包括在一個或多個ejb-jar文件中的ejb組件,還可能有ejb-jar所依賴的庫文件。所有ear文件中的代碼都是經過深思熟慮開發的應用程序并且都遵守編程限制和訪問許可集。
未來版本的規范可能會指定通過部署工具來定制安全許可的能力,通過這種方法指定了一個合法的組件應授予的許可權限,也指定了一個標準方法的需求:如從文件系統中讀文件應有哪些要求。一些ejb容器/服務器目前在它們的部署工具中都提供了比標準權限或多或少的許可權限,這些并不是ejb1.1規范中所需要的。
理解這些約束
ejb容器是ejb組件生存和執行的運行期環境,ejb容器為ejb組件實例提供了一些服務如:事務管理、安全持久化、資源訪問、客戶端連接。ejb容器也負責ejb組件實例整個生命期的管理、擴展問題以及并發處理。所以,ejb組件就這樣寄居在一個被管理的執行環境中--即ejb容器。
因為ejb容器完全負責ejb組件的生命期、并發處理、資源訪問、安全等等,所以與容器本身的鎖定和并發管理相沖突的可能性就需要消除,許多限制都需要使用來填上潛在的安全漏洞。除了與ejb容器責任與安全沖突的問題,ejb組件還意味著僅僅聚焦于商務邏輯,它依賴于ejb容器所提供的服務而不是自己來直接解決底層的系統層的問題。 3 4 5 6 7 8 9 10 11 12 13 14 15
可能的問題
通常,ejb組件在容器之間的移植不可避免地與如下問題相關:
1.它需要依靠的受限制的特點在特定ejb容器中沒有得到加強。
2.它需要依靠的非標準的服務從容器中可獲得。
為了保證ejb組件的可移植性和一致的行為,你應該使用一個具有與java2平臺安全
策略集相一致的策略集的容器來測試ejb組件,并且其加強了前述的編程限制。
總結
ejb組件開發者應該知道這些推薦的關于ejb組件的編程限制,明白它們的重要性,并且從組件的穩定性和可移植性利益方面考慮來遵循它們。因為這些編程限制能阻止你使用標準的java語言的特點,違背了這些編程限制在編譯時不會知道,并且加強這些限制也不是ejb容器的責任。所有這些原因都使你應很小心地遵守這些編程限制,這些限制在組件的合同中已經成為了一個條款,并且它們對于建造可靠的、可移植的組件是非常重要的。
2. 優化ejb
entity bean為在應用程序和設計中描述持久化商業對象(persistent business objec ts)提供了一個清晰的模型。在java對象模型中,簡單對象通常都是以一種簡單的方式進行處理但是,很多商業對象所需要的事務化的持久性管理沒有得到實現。entity bean將持久化機制封裝在容器提供的服務里,并且隱藏了所有的復雜性。entity bean允許應用程序操縱他們就像處理一個一般的java對象應用。除了從調用代碼中隱藏持久化的形式和機制外,entity bean還允許ejb容器對對象的持久化進行優化,保證數據存儲具有開放性,靈活性,以及可部署性。在一些基于ejb技術的項目中,廣泛的使用oo技術導致了對entity bean的大量使用,sun的工程師們已經積累了很多使用entity bean的經驗,這篇文章就詳細闡述的這些卡發經驗:
*探索各種優化方法
*提供性能優化和提高適用性的法則和建議
*討論如何避免一些教訓。
法則1:只要可以,盡量使用cmp
cmp方式不僅減少了編碼的工作量,而且在container中以及container產生的數據庫訪問代碼中包括了許多優化的可能。container可以訪問內存緩沖中的bean,這就允許它可以監視緩沖中的任何變化。這樣的話就在事物沒有提交之前,如果緩存的數據沒有變化就不用寫到數據庫中。就可以避免許多不必要的數據庫寫操作。另外一個優化是在調用find方法的時候。通常情況下find方法需要進行以下數據庫操作:
查找數據庫中的紀錄并且獲得主鍵
將紀錄數據裝入緩存
cmp允許將這兩步操作優化為一步就可以搞定。[具體怎么做我也沒弄明白,原文沒有具體闡述]
法則2:寫代碼時盡量保證對bmp和cmp都支持
許多情況下,ejb的開發者可能無法控制他們寫的bean怎么樣被部署,以及使用的container是不是支持cmp.
一個有效的解決方案是,將商業邏輯的編碼完全和持久化機制分離。再cmp類中實現商業邏輯,然后再編寫一個bmp類,用該類繼承cmp類。這樣的話,所有的商業邏輯都在cmp類中,而持久化機制在bmp中實現。[我覺得這種情況在實際工作中很少遇到,但是作者解決問題的思路值得學習]
法則3:把ejbstore中的數據庫訪問減小到最少。
如果使用bmp,設置一個緩存數據改變標志dirty非常有用。所有改變數據庫中底層數據的操作,都要設置dirty,而在ejbstore中,首先檢測dirty的值,如果dirty的值沒有改變,表明目前數據庫中的數據與緩存的一致,就不必進行數據庫操作了,反之,就要把緩存數據寫入數據庫。
法則4:總是將從lookup和find中獲得的引用進行緩存。(cache)
引用緩存對session bean和entity bean 都是適用的。
通過jndi lookup獲得ejb資源。比如datasource,bean的引用等等都要付出相當大的代價。因此應該避免多余的lookup.可以這樣做:
將這些引用定義為實例變量。
從setentitycontext(session bean使用setsessioncontext)方法查找他們。setentitycontext方法對于一個bean實例只執行一次,所有的相關引用都在這一次中進行查找,這樣查找的代價就不是那么昂貴了。應該避免在其他方法中查找引用。尤其是訪問數據庫的方法:ejbload和ejbstore,如果在這些頻繁調用的方法中進行datasource的查找,勢必造成時間的浪費。
調用其他entity bean的finder方法也是一種重量級的調用。多次調用finder方法的代價非常高。如果這種引用不適合放在setentitycontext這樣的初始化時執行的方法中執行,就應該在適當的時候緩存finder的執行結果。只是要注意的是,如果這個引用只對當前的entity有效,你就需要在bean從緩沖池中取出來代表另外一個實體時清除掉這些引用。,這些操作應該在ejbactivate中進行。
法則5:總是使用prepare statements
這條優化法則適用于所有訪問關系數據庫的操作。
數據庫在處理每一個sql statement的時候,執行前都要對statement進行編譯。一些數據庫具有緩存statement和statement的編譯后形式的功能。數據庫可以把新的statement和緩存中的進行匹配。然而,如果要使用這一優化特性,新的statement要必須和緩存中的statement完全匹配。
對于non-prepared statement,數據和statement本身作為一個字符串傳遞,這樣由于前后調用的數據不同而不能匹配,就導致無法使用這種優化。而對于prepared statement,數據和statement是分開傳遞給數據庫的,這樣statement就可以和cache中已編譯的statement進行匹配。statement就不必每次都進行編譯操作。從而使用該優化屬性。
【5】【6】【7】【8】【9】【10】【11】【12】【13】【14】【15】
這項技術在一些小型的數據庫訪問中能夠減少statement將近90%的執行時間。
法則6:完全關閉所有的statement
在編寫bmp的數據庫訪問代碼時,記住一定要在數據庫訪問調用之后關閉statement,因為每個打開的statement對應于數據庫中的一個打開的游標。
security
1.加密
對稱加密
(1)分組密碼
(2)流密碼
常用的對稱加密算法:
des和tripledes
blowfish
rc4
aes
非對稱加密
常用的非對稱加密算法
rsa
elgamal
會話密鑰加密(對稱加密和非對稱加密一起使用)
常用的會話密鑰加密協議
s/mime
pgp
ssl和tls ssl是在application level protocal和transport protocal之間的。
比如:http和tcp/ip之間
ssl 提供了服務器端認證和可選的客戶端認證,保密性和數據完整性。
提供基于ssl方式的傳輸加密和認證,確保以下三種安全防護:
數據的機密性和準確性、
服務器端認證
客戶端認證。
客戶端認證比服務器端認證不很普遍的原因是每一個要被認證的客戶都必須有一張verisign這樣的ca簽發的證書。
通常,在進行身份認證的時候,應當只接受一個ca,這個ca的名字包含在客戶證書中。
由于不可能隨意創建一個由指定ca簽發的證書,所以這可以有效的防御通過偽造證書來進行的攻擊嘗試。
2.認證(authentication)
認證就是確定一條消息或一個用戶的可靠性的過程。
1.消息摘要
md5
sha和sha-1
2.消息認證碼(message authientication codes,mac)
3.數字簽名
用戶可以用自己的密鑰對信息加以處理,由于密鑰僅為本人所有,這樣就產生了別人無法生成的文件,也就形成了數字簽名
數字簽名可以
1)保證數據的完整性
2)驗證用戶的身份
數字簽名采用一個人的私鑰計算出來,然后用公鑰去檢驗。
hash算法 私鑰加密
原報文 ――――――>;報文摘要( message digest ) ―――――>;數字簽名
原報文和數字簽名一起被發送到接受者那里,接受者用同樣的hash算法得到報文摘要,然后用發送者的公鑰解開數字簽名。
比較是否相同,則可以確定報文確定來自發送者。
驗證數字簽名必須使用公鑰,但是,除非你是通過安全的方式直接得到,否則不能保證公鑰的正確性。(數字證書可以解決這個問題)
一個接受者在使用公鑰(public key)檢查數字簽名(digital signature)的可信度時,通常先要檢查收到的公鑰(public key)是否可信的。
因此發送方不是單單地發送公鑰(public key),而是發送一個包含公鑰(public key)的數字證書(cetificate )。
4.數字證書
數字證書是一個經證書授權中心數字簽名的包含公開密鑰所有者信息以及公開密鑰的文件。
數字證書cetificate中包括:
i. 用戶的公鑰(public key)
ii. 用戶的一些信息,如姓名,email
iii. 發行機構的數字簽名(digital signature), 用于保證證書的可信度
iv. 發行機構的一些信息
數字證書的格式遵循x.509國際標準。
注意:一個數字證書certificate并不適用于多種browser,甚至一種browser的多個版本。
數字標識由公用密鑰、私人密鑰和數字簽名三部分組成。
當在郵件中添加數字簽名時,您就把數字簽名和公用密鑰加入到郵件中。數字簽名和公用密鑰統稱為證書。您可以使用 outlook express 來指定他人向您發送加密郵件時所需使用的證書。這個證書可以不同于您的簽名證書。
收件人可以使用您的數字簽名來驗證您的身份,并可使用公用密鑰給您發送加密郵件,這些郵件必須用您的私人密鑰才能閱讀。
要發送加密郵件,您的通訊簿必須包含收件人的數字標識。這樣,您就可以使用他們的公用密鑰來加密郵件了。當收件人收到加密郵件后,用他們的私人密鑰來對郵件進行解密才能閱讀。
在能夠發送帶有數字簽名的郵件之前,您必須獲得數字標識。如果您正在發送加密郵件,您的通訊簿中必須包含每位收件人的數字標識。
數字證書,可以是個人證書或 web 站點證書,用于將身份與"公開密鑰"關聯。只有證書的所有者才知道允許所有者"解密"或進行"數字簽名"的相應"私人密鑰"。當您將自己的證書發送給其他人時,實際上發給他們的是您的公開密鑰,這樣他們就可以向您發送只能由您使用私人密鑰解密和讀取的加密信息。
通過瀏覽器使用數字證書,必須先要設置瀏覽器軟件 internet explorer 或 netscape使用此證書,才能開始發送加密或需要數字簽名的信息。訪問安全的 web 站點(以"https"打頭的站點)時,該站點將自動向您發送他們的web站點證書。
3.ca(證書授證中心)
ca機構,又稱為證書授證(certificate authority)中心,作為電子商務交易中受信任的第三方,承擔公鑰體系中公鑰的合法性檢驗的責任。ca中心為每個使用公開密鑰的用戶發放一個數字證書,數字證書的作用是證明證書中列出的用戶合法擁有證書中列出的公開密鑰。ca機構的數字簽名使得攻擊者不能偽造和篡改證書。在set交易中,ca不僅對持卡人、商戶發放證書,還要對獲款的銀行、網關發放證書。它負責產生、分配并管理所有參與網上交易的個體所需的數字證書,因此是安全電子交易的核心環節。
〖5〗〖6〗〖7〗〖8〗〖9〗〖10〗〖11〗〖12〗〖13〗〖14〗〖15〗
對證書的信任基于對根證書的信任. 例如在申請sheca的個人數字證書前,需要先下載根證書,然后再進行各類證書的申請。
下載根證書的目的:
網絡服務器驗證(s);安全電子郵件(e)
申請個人數字證書可以為internet用戶提供發送電子郵件的安全和訪問需要安全連接(需要客戶證書)的站點。
1)個人數字證書
a.個人身份證書
個人身份證書是用來表明和驗證個人在網絡上的身份的證書,它確保了網上交易和作業的安全性和可靠性?蓱糜冢壕W上炒股、網上理財、網上保險、網上繳費、網上購物、網上辦公等等。個人身份證書可以存儲在軟盤或ic卡中。
b.個人安全電子郵件證書
個人安全電子郵件證書可以確保郵件的真實性和保密性。申請后一般是安裝在用戶的瀏覽器里。用戶可以利用它來發送簽名或加密的電子郵件。
用戶在申請安裝完安全安全電子郵件數字證書后,就可以對要發送的郵件進行數字簽名。收信人收到該郵件后,就可以看到數字簽名的標記,這樣就可以證明郵件肯定來自發信者本人,而不是別人盜用該帳號偽造信件,同時也保證該郵件在傳送過程中沒被他人篡改過任何數據。
安全電子郵件中使用的數字證書可以實現:
保密性 通過使用收件人的數字證書對電子郵件加密。如此以來,只有收件人才能閱讀加密的郵件,在internet上傳遞的電子郵件信息不會被人竊取,即使發錯郵件,收件人也無法看到郵件內容。
認證身份 在internet上傳遞電子郵件的雙方互相不能見面,所以必須有方法確定對方的身份。利用發件人數字證書在傳送前對電子郵件進行數字簽名即可確定發件人身份,而不是他人冒充的。
完整性 利用發件人數字證書在傳送前對電子郵件進行數字簽名不僅可確定發件人身份,而且傳遞的電子郵件信息也不能被人在傳輸過程中修改。
不可否認性 由于發件人的數字證書只有發件人唯一擁有,故發件人利用其數字證書在傳送前對電子郵件進行數字簽名,發件人就無法否認發過這個電子郵件。
outlook express中的個人安全電子郵件證書
簽名郵件帶有簽名郵件圖標。
簽名郵件可能出現的任何問題都將在本信息之后可能出現的“安全警告”中得到描述。如果存在問題,您應該認為郵件已被篡改,或并非來自所謂的發件人。
當收到一封加密郵件時,您應該可以自信地認為郵件未被任何第三者讀過。outlook express 會自動對電子郵件解密, 如果在您的計算機上裝有正確的數字標識。
2)企業數字證書
a.企業身份證書
企業身份證書是用來表明和驗證企業用戶在網絡上身份的證書,它確保了企業網上交易和作業的安全性和可靠性?蓱糜冢壕W上證券、網上辦公、網上交稅、網上采購、網上資金轉帳、網上銀行等。企業身份證書可以存儲在軟盤和ic卡中。
b.企業安全電子郵件證書
企業安全電子郵件證書可以確保郵件的真實性和保密性。申請后一般是安裝在用戶的瀏覽器里。企業可以利用它來發送簽名或加密的電子郵件。
可使用 windows 中的證書服務來創建證書頒發機構 (ca),它負責接收證書申請、驗證申請中的信息和申請者的身份、頒發證書、吊銷證書以及發布證書吊銷列表 (crl)。
通常,當用戶發出證書申請時,在其計算機上的加密服務提供程序 (csp) 為用戶生成公鑰和私鑰對。用戶的公鑰隨同必要的識別信息發送至 ca。如果用戶的識別信息符合批準申請的 ca 標準,那么 ca 將生成證書,該證書由客戶應用程序檢索并就地存儲。
4.set
安全接口層協議——ssl(se cure socketslayer),并且已經幾乎成為了目前www 世界的事實標準。這一標準使用公共密鑰編碼方案來對傳輸數據進行加密,在雙方之間建立一個internet 上的加密通道,從而使第三方無法獲得其中的信息,其思路與目前流行的方案大致相同,目的都是要保護數據不被未經授權的第三方所竊聽,或即使竊聽到也不知所云。但就象 一樣,ssl 在認證方面沒有任何作為,它們都需要通過另外的手段來確認身份和建立雙方彼此間的信任,然后再通過ssl 進行交易。
正是由于ssl 標準在認證方面的缺憾,所以set 才有存在的必要。set(secure electronic transactions) 規范由masterc ard 和visa 公司于1996 年發布,專家們認為set 是保證用戶與商家在電子商務與在線交易中免受欺騙的重要手段。傳統的信用卡交易者總在擔心不誠實的店員會將自己的信用卡號碼透露給他人,而在線交易也是如此,持卡者總在擔心服務器端的管理員會將信用卡號碼泄露出去,或者擔心黑客會在管理員不知情的情況下盜取信用卡號碼。事實上這些擔心都是必要的,而set 標準則可以保證用戶的信用卡號碼只傳送給信用卡公司進行認證,不會被系統管理員看到,也不會留在交易服務器的硬盤上給黑客以可乘之機。
5.pki
pki是一種易于管理的、集中化的網絡安全方案。它可支持多種形式的數字認證: 數據加密、數字簽字、不可否認、身份鑒別、密鑰管理以及交叉認證等。pki可通過一個基于認證的框架處理所有的數據加密和數字簽字工作。p ki標準與協議的開發迄今已有20xx年的歷史,目前的pki已完全可以向企業網絡提供有效的安全保障。 〖5〗〖6〗〖7〗〖8〗〖9〗〖10〗〖11〗〖12〗〖13〗〖14〗〖15〗
pki是一種遵循標準的密鑰管理平臺,它能夠為所有網絡應用透明地提供采用加密和數字簽名等密碼服務所必需的密鑰和證書管理。pki必須具有
1)ca、
2)證書庫、
3)密鑰備份及恢復系統、
4)證書作廢處理系統、
5)客戶端證書處理系統
等基本成分,構建pki也將圍繞著這五大系統來構建
一個pki由眾多部件組成,這些部件共同完成兩個主要功能:
1)為數據加密
2)創建數字認證。
服務器(即后端)產品是這一系統的核心,這些數據庫管理著數字認證、公共密鑰及專用密鑰( 分別用于數據的加密和解密)。
ca數據庫負責發布、廢除和修改x.509數字認證信息,它裝有用戶的公共密鑰、證書有效期以及認證功能(例如對數據的加密或對數字簽字的驗證) 。為了防止對數據簽字的篡改,ca在把每一數字簽字發送給發出請求的客戶機之前,需對每一個數字簽字進行認證。一旦數字認證得以創建, 它將會被自動存儲于x.500目錄中,x.500目錄為樹形結構。ldap(lightweight directory access protocol)協議將響應那些要求提交所存儲的公共密鑰認證的請求。ca為每一用戶或服務器生成兩對獨立的公共和專用密鑰。其中一對用于信息的加密和解密, 另一對由客戶機應用程序使用,用于文檔或信息傳輸中數字簽字的創建。
大多數pki均支持證書分布,這是一個把已發布過的或續延生命期的證書加以存儲的過程。這一過程使用了一個公共查詢機制,x.500目錄可自動完成這一存儲過程。影響企業普遍接受p ki的一大障礙是不同ca之間的交叉認證。假設有兩家公司,每一家企業分別使用來自不同供應商的ca,現在它們希望相互托管一段時間。如果其后援數據庫支持交叉認證, 則這兩家企業顯然可以互相托管它們的ca,因而它們所托管的所有用戶均可由兩家企業的ca所托管。
* 認證機關
ca是證書的簽發機構,它是pki的核心。眾所周知,構建密碼服務系統的核心內容是如何實現密鑰管理,公鑰體制涉及到一對密鑰,即私鑰和公鑰, 私鑰只由持有者秘密掌握,無須在網上傳送,而公鑰是公開的,需要在網上傳送,故公鑰體制的密鑰管理主要是公鑰的管理問題,目前較好的解決方案是引進證書(certificate)機制。
證書是公開密鑰體制的一種密鑰管理媒介。它是一種權威性的電子文檔,形同網絡計算環境中的一種身份證,用于證明某一主體(如人、服務器等)的身份以及其公開密鑰的合法性。在使用公鑰體制的網絡環境中, 必須向公鑰的使用者證明公鑰的真實合法性。因此,在公鑰體制環境中,必須有一個可信的機構來對任何一個主體的公鑰進行公證,證明主體的身份以及他與公鑰的匹配關系。c a正是這樣的機構,它的職責歸納起來有:
1、驗證并標識證書申請者的身份;
2、確保ca用于簽名證書的非對稱密鑰的質量;
3、確保整個簽證過程的安全性,確保簽名私鑰的安全性;
4、證書材料信息(包括公鑰證書序列號、ca標識等)的管理;
5、確定并檢查證書的有效期限;
6、確保證書主體標識的唯一性,防止重名;
7、發布并維護作廢證書表;
8、對整個證書簽發過程做日志記錄;
9、向申請人發通知。
其中最為重要的是ca自己的一對密鑰的管理,它必須確保其高度的機密性,防止他方偽造證書。ca的公鑰在網上公開,整個網絡系統必須保證完整性。
* 證書庫
證書庫是證書的集中存放地,它與網上"白頁”類似,是網上的一種公共信息庫,用戶可以從此處獲得其他用戶的證書和公鑰。
構造證書庫的最佳方法是采用支持ldap協議的目錄系統,用戶或相關的應用通過ldap來訪問證書庫。系統必須確保證書庫的完整性,防止偽造、篡改證書。
* 密鑰備份及恢復系統
* 證書作廢處理系統
* pki應用接口系統
pki的價值在于使用戶能夠方便地使用加密、數字簽名等安全服務,因此一個完整的pki必須提供良好的應用接口系統,使得各種各樣的應用能夠以安全、一致、可信的方式與p ki交互,確保所建立起來的網絡環境的可信性,同時降低管理維護成本。最后,pki應用接口系統應該是跨平臺的。
許多權威的認證方案供應商(例如verisign、thawte以及gte)目前都在提供外包的pki。外包pki最大的問題是,用戶必須把企業托管給某一服務提供商, 即讓出對網絡安全的控制權。如果不愿這樣做,則可建造一個專用的pki。專用方案通常需把來自entrust、baltimore technologies以及xcert的多種服務器產品與來自主流應用程序供應商(如microsoft、netscape以及qualcomm)的產品組合在一起。專用pk i還要求企業在準備其基礎設施的過程中投入大量的財力與物力。
7.jaas
擴展jaas實現類實例級授權
“java 認證和授權服務”(java authentication and authorization service,jaas)
在 jaas 下,可以給予用戶或服務特定的許可權來執行 java 類中的代碼。在本文中,軟件工程師 carlos fonseca 向您展示如何為企業擴展 jaas 框架。向 jaas 框架添加類實例級授權和特定關系使您能夠構建更動態、更靈活并且伸縮性更好的企業應用程序。
大多數 java 應用程序都需要某種類實例級的訪問控制。例如,基于 web 的、自我服務的拍賣應用程序的規范可能有下列要求: 《5》《6》《7》《8》《9》《10》《11》《12》《13》《14》《15》
任何已注冊(經過認證)的用戶都可以創建一個拍賣,但只有創建拍賣的用戶才可以修改這個拍賣。
這意味著任何用戶都可以執行被編寫用來創建 auction 類實例的代碼,但只有擁有該實例的用戶可以執行用來修改它的代碼。通常情況下,創建 auction 實例的用戶就是所有者。這被稱為類實例所有者關系(class instance owner relationship)。
該應用程序的另一個要求可能是:
任何用戶都可以為拍賣創建一個投標,拍賣的所有者可以接受或拒絕任何投標。
再一次,任何用戶都可以執行被編寫用來創建 bid 類實例的代碼,但只有擁有該實例的用戶會被授予修改該實例的許可權。而且,auction 類實例的所有者必須能夠修改相關的 bid 類實例中的接受標志。這意味著在 auction 實例和相應的 bid 實例之間有一種被稱為特定關系(special relationship)的關系。
不幸的是,“java 認證和授權服務”(jaas)— 它是 java 2 平臺的一部分 — 沒有考慮到類實例級訪問控制或者特定關系。在本文中,我們將擴展 jaas 框架使其同時包含這兩者。推動這種擴展的動力是允許我們將訪問控制分離到一個通用的框架,該框架使用基于所有權和特定關系的策略。然后管理員可以在應用程序的生命周期內更改這些策略。
在深入到擴展 jaas 框架之前,我們將重溫一下 java 2 平臺的訪問控制機制。我們將討論策略文件和許可權的使用,并討論 securitymanager 和 accesscontroller 之間的關系。
java 2 平臺中的訪問控制
在 java 2 平臺中,所有的代碼,不管它是本地代碼還是遠程代碼,都可以由策略來控制。策略(policy)由不同位置上的代碼的一組許可權定義,或者由不同的簽發者定義、或者由這兩者定義。許可權允許對資源進行訪問;它通過名稱來定義,并且可能與某些操作關聯在一起。
抽象類 java.security.policy 被用于表示應用程序的安全性策略。缺省的實現由 sun.security.provider.policyfile 提供,在 sun.security.provider.policyfile 中,策略被定義在一個文件中。清單 1 是一個典型策略文件示例:
清單 1. 一個典型的策略文件
// grant these permissions to code loaded from a sample.jar file
// in the c drive and if it is signed by xyz
grant codebase "file:/c:/sample.jar", signedby "xyz" {
// allow socket actions to any host using port 8080
permission .socketpermission "*:8080", "accept, connect,
listen, resolve";
// allows file access (read, write, execute, delete) in
// the user's home directory.
permission java.io.filepermission "${user.home}/-", "read, write,
execute, delete";
};
securitymanager 對 accesscontroller
在標準 jdk 分發版中,控制代碼源訪問的機制缺省情況下是關閉的。在 java 2 平臺以前,對代碼源的訪問都是由 securitymanager 類管理的。securitymanager 是由 java.security.manager 系統屬性啟動的,如下所示:
java -djava.security.manager
在 java 2 平臺中,可以將一個應用程序設置為使用 java.lang.securitymanager 類或者 java.security.accesscontroller 類管理敏感的操作。accesscontroller 在 java 2 平臺中是新出現的。為便于向后兼容,securitymanager 類仍然存在,但把自己的決定提交 accesscontroller 類裁決。securitymanager 和 accesscontroller 都使用應用程序的策略文件確定是否允許一個被請求的操作。清單 2 顯示了 accesscontroller 如何處理 socketpermission 請求:
清單 2. 保護敏感操作
public void somemethod {
permission permission =
new .socketpermission("localhost:8080", "connect");
accesscontroller.checkpermission(permission);
// sensitive code starts here
socket s = new socket("localhost", 8080);
}
在這個示例中,我們看到 accesscontroller 檢查應用程序的當前策略實現。如果策略文件中定義的任何許可權暗示了被請求的許可權,該方法將只簡單地返回;否則拋出一個 accesscontrolexception 異常。在這個示例中,檢查實際上是多余的,因為缺省套接字實現的構造函數也執行相同的檢查。
在下一部分,我們將更仔細地看一下 accesscontroller 如何與 java.security.policy 實現共同合作安全地處理應用程序請求。
運行中的 accesscontroller
accesscontroller 類典型的 checkpermission(permission p) 方法調用可能會導致下面的一系列操作:
accesscontroller 調用 java.security.policy 類實現的 getpermissions(codesource codesource) 方法。
getpermissions(codesource codesource) 方法返回一個 permissioncollection 類實例,這個類實例代表一個相同類型許可權的集合。
accesscontroller 調用 permissioncollection 類的 implies(permission p) 方法。
接下來,permissioncollection 調用集合中包含的單個 permission 對象的 implies(permission p) 方法。如果集合中的當前許可權對象暗示指定的許可權,則這些方法返回 true,否則返回 false。
[1][2][3][4][5][6][7][8][9][10][11][12][13][14][15]
現在,讓我們更詳細地看一下這個訪問控制序列中的重要元素。
permissioncollection 類
大多數許可權類類型都有一個相應的 permissioncollection 類。這樣一個集合的實例可以通過調用 permission 子類實現定義的 newpermissioncollection 方法來創建。java.security.policy 類實現的 getpermissions 方法也可以返回 permissions 類實例 — permissioncollection 的一個子類。這個類代表由 permissioncollection 組織的不同類型許可權對象的一個集合。permissions 類的 implies(permission p) 方法可以調用單個 permissioncollection 類的 implies(permission p) 方法。
codesource 和 protectiondomain 類
許可權組合與 codesource(被用于驗證簽碼(signed code)的代碼位置和證書)被封裝在 protectiondomain 類中。有相同許可權和相同 codesource 的類實例被放在相同的域中。帶有相同許可權,但不同 codesource 的類被放在不同的域中。一個類只可屬于一個 protectiondomain。要為對象獲取 protectiondomain,請使用 java.lang.class 類中定義的 getprotectiondomain 方法。
許可權
賦予 codesource 許可權并不一定意味著允許所暗示的操作。要使操作成功完成,調用棧中的每個類必須有必需的許可權。換句話說,如果您將 java.io.filepermission 賦給類 b,而類 b 是由類 a 來調用,那么類 a 必須也有相同的許可權或者暗示 java.io.filepermission 的許可權。
在另一方面,調用類可能需要臨時許可權來完成另一個擁有那些許可權的類中的操作。例如,當從另一個位置加載的類訪問本地文件系統時,我們可能不信任它。但是,本地加載的類被授予對某個目錄的讀許可權。這些類可以實現 privilegedaction 接口來給予調用類許可權以便完成指定的操作。調用棧的檢查在遇到 privilegedaction 實例時停止,有效地將執行指定操作所必需的許可權授予所有的后繼類調用。
使用 jaas
顧名思義,jaas 由兩個主要組件組成:認證和授權。我們主要關注擴展 jaas 的授權組件,但開始我們先簡要概述一下 jaas 認證,緊接著看一下一個簡單的 jaas 授權操作。
jaas 中的用戶認證
jaas 通過添加基于 subject 的策略加強了 java 2 中定義的訪問控制安全性模型。許可權的授予不僅基于 codesource,還基于執行代碼的用戶。顯然,要使這個模型生效,每個用戶都必須經過認證。
jaas 的認證機制建立在一組可插登錄模塊的基礎上。jaas 分發版包含幾個 loginmodule 實現。loginmodules 可以用于提示用戶輸入用戶標識和密碼。logincontext 類使用一個配置文件來確定使用哪個 loginmodule 對用戶進行認證。這個配置可以通過系統屬性 java.security.auth.login.config 指定。一個示例配置是:
java -djava.security.auth.login.config=login.conf
下面是一個登錄配置文件的樣子:
example {
com.ibm.resource.security.auth.loginmoduleexample required
debug=true userfile="users.xml" groupfile="groups.xml";
};
認識您的主體
subject 類被用于封裝一個被認證實體(比如用戶)的憑證。一個 subject 可能擁有一個被稱為主體(principal)的身份分組。例如,如果 subject 是一個用戶,用戶的名字和相關的社會保險號可能是 subject 的某些身份或主體。主體是與身份名關聯在一起的。
principal 實現類及其名稱都是在 jaas 策略文件中指定的。缺省的 jaas 實現使用的策略文件與 java 2 實現的策略文件相似 — 除了每個授權語句必須與至少一個主體關聯在一起。javax.security.auth.policy 抽象類被用于表示 jaas 安全性策略。它的缺省實現由 com.sun.security.auth.policyfile 提供,在 com.sun.security.auth.policyfile 中策略定義在一個文件中。清單 3 是 jaas 策略文件的一個示例:
清單 3. 示例 jaas 策略文件
// example grant entry
grant codebase "file:/c:/sample.jar", signedby "xyz",
principal com.ibm.resource.security.auth.principalexample "admin" {
// allow socket actions to any host using port 8080
permission .socketpermission
"*:8080", "accept, connect, listen, resolve";
// allows file access (read, write, execute, delete) in
// the user's home directory.
permission java.io.filepermission
"${user.home}/-", "read, write, execute, delete";
};
這個示例與清單 1 中所示的標準 java 2 策略文件相似。實際上,唯一的不同是主體語句,該語句聲明只有擁有指定主體和主體名字的 subject(用戶)被授予指定的許可權。
再一次,使用系統屬性 java.security.auth.policy 指出 jaas 策略文件駐留在何處,如下所示:
java -djava.security.auth.policy=policy.jaas
subject 類包含幾個方法來作為特殊 subject 執行工作;這些方法如下所示:
public static object
doas(subject subject, java.security.privilegedaction action) 3 4 5 6 7 8 9 10 11 12 13 14 15
public static object
doas(subject subject, java.security.privilegedaction action)
throws java.security.privilegedactionexception
注意,用來保護敏感代碼的方法與“java 2 代碼源訪問控制”(java 2 codesource access control)概述中描述的方法相同。請參閱參考資料部分以了解更多關于 jaas 中代碼源訪問控制和認證的信息。
jaas 中的授權
清單 4 顯示一個授權請求的結果,該請求使用清單 3 中顯示的 jaas 策略文件。假設已經安裝了 securitymanager,并且 logincontext 已經認證了一個帶有名為“admin”的 com.ibm.resource.security.auth.principalexample 主體的 subject。
清單 4. 一個簡單的授權請求
public class jaasexample {
public static void main(string args) {
...
// where authenticateduser is a subject with
// a principalexample named admin.
subject.doas(authenticateduser, new jaasexampleaction);
...
}
}
public class jaasexampleaction implements privilegedaction {
public object run {
filewriter fw = new filewriter("hi.txt");
fw.write("hello, world!");
fw.close;
}
}
這里,敏感代碼被封裝在 jaasexampleaction 類中。還要注意,調用類不要求為 jaasexampleaction 類代碼源授予許可權,因為它實現了一個 privilegedaction。
擴展 jaas
大多數應用程序都有定制邏輯,它授權用戶不僅僅在類上執行操作,而且還在該類的實例上執行操作。這種授權通常建立在用戶和實例之間的關系上。這是 jaas 的一個小缺點。然而,幸運的是,這樣設計 jaas 使得 jaas 可以擴展。只要做一點工作,我們將可以擴展 jaas,使其包含一個通用的、類實例級的授權框架。
在文章開頭處我已經說明了,抽象類 javax.security.auth.policy 被用于代表 jaas 安全性策略。它的缺省實現是由 com.sun.security.auth.policyfile 類提供。policyfile 類從 jaas 格式的文件(象清單 3 中顯示的那個一樣)中讀取策略。
我們需要向這個文件添加一個東西為類實例級授權擴展策略定義:一個與許可權語句相關的可選關系參數。
缺省 jaas 許可權語句的格式如下:
permission ; [name], [actions];
我們在這個許可權語句的末尾添加一個可選的關系參數來完成策略定義。下面是新許可權語句的格式:
permission ;
[name], [actions], [relationship];
在為類實例級授權擴展 jaas 時要注意的最重要的一點是:許可權實現類必須有一個帶三個參數的構造函數。第一個參數是名稱參數,第二個是行為參數,最后一個是關系參數。
解析新文件格式
既然文件格式已經改變,就需要一個新的 javax.security.auth.policy 子類來解析文件。
為簡單起見,我們的示例使用了一個新的 javax.security.auth.policy 子類 com.ibm.resource.security.auth.xmlpolicyfile,來從 xml 文件讀取策略。在實際的企業應用程序中,關系數據庫更適合執行這個任務。
使用 xmlpolicyfile 類代替缺省的 jaas 訪問控制策略實現的最容易的方法是向 java.security 屬性文件添加 auth.policy.provider=com.ibm.resource.security.auth.xmlpolicyfile 條目。java.security 屬性文件位于 java 2 平臺運行時的 lib/security 目錄下。清單 5 是與 xmlpolicyfile 類一起使用的樣本 xml 策略文件:
清單 5. 一個 xml 策略文件
;
;
;
"com.ibm.resource.security.auth.principalexample" name="users">;
"com.ibm.resource.security.auth.resourcepermission"
name="com.ibm.security.sample.auction"
actions="create" />;
"com.ibm.resource.security.auth.resourcepermission"
name="com.ibm.security.sample.auction"
actions="read" />;
"com.ibm.resource.security.auth.resourcepermission"
name="com.ibm.security.sample.auction"
actions="write"
relationship="owner" />;
"com.ibm.resource.security.auth.resourcepermission"
name="com.ibm.security.sample.bid"
actions="create" />;
"com.ibm.resource.security.auth.resourcepermission"
name="com.ibm.security.sample.bid"
actions="read" />;
"com.ibm.resource.security.auth.resourcepermission"
【5】【6】【7】【8】【9】【10】【11】【12】【13】【14】【15】
name="com.ibm.security.sample.bid"
actions="write"
relationship="owner" />;
"com.ibm.resource.security.auth.resourcepermission"
name="com.ibm.security.sample.bid"
actions="accept"
relationship="actionowner" />;
;
;
;
在這個示例策略文件中,任何與名為 principalexample 的用戶有關的用戶(subject)都可以創建并讀取一個 auction.class 實例。但是,只有創建該實例的用戶才可以更新(寫)它。這是第三個 permission 元素定義的,該元素包含值為 owner 的 relationship 屬性。bid.class 實例也是一樣,除了相應 auction.class 實例的所有者可以更改投標接受標志。
resource 接口
要求類實例級訪問控制的類必須實現 resource 接口。該接口的 getowner 方法返回類實例的所有者。fulfills(subject subject, string relationship) 方法被用于處理特定關系。另外,這些類使用 com.ibm.resource.security.auth.resourcepermission 類保護敏感代碼。例如,auction 類擁有下列構造函數:
public auction {
permission permission =
new resourcepermission("com.ibm.security.sample.auction", "create");
accesscontroller.checkpermission(permission);
}
所有者關系
resourcepermission 類的 implies(permission p) 方法是這個框架的關鍵。implies 方法就等同性比較名稱和行為屬性。如果定義了一個關系,那么必須把受保護的類實例(resource)傳遞到 resourcepermission 構造函數中。resourcepermission 類理解所有者關系。它將類實例的所有者與執行代碼的 subject(用戶)進行比較。特定關系被委托給受保護類的 fulfills 方法。
例如,在清單 5 中所示的 xml 策略文件中,只有 auction 類實例的所有者可以更新(寫)文件。該類的 setter 方法使用清單 6 中顯示的保護代碼:
清單 6. 運行中的 implies(permission) 方法
public void setname(string newname) {
permission permission =
new resourcepermission("com.ibm.security.sample.auction", "write", this);
accesscontroller.checkpermission(permission);
// sensitive code
this.name = newname;
}
被傳遞到 resourcepermission 構造函數中的 this 引用代表 auction 類實現的 resource 接口。由于策略文件中列出的關系是 owner,所以 resourcepermission 類使用這個引用檢查當前 subject(用戶)是否擁有與實例所有者相匹配的主體。如果指定了另一個關系,那么 resourcepermission 類調用 auction 類的 fulfills(subject subject, string relationship) 方法。由 resource 實現類提供 fulfills 方法中的邏輯。
xml 策略文件中列出的 bid 類擁有清單 7 中所示的方法(假設 bid 類實例有一個對相應 auction 類實例的引用 — auction)。
清單 7. 處理特定關系
public void setaccepted(boolean flag) {
permission permission =
new resourcepermission("com.ibm.security.sample.auction", "accept", this);
accesscontroller.checkpermission(permission);
// sensitive code
this.accepted = flag;
}
public boolean fulfills(subject user, string relationship) {
if( relationship.equalsignorecase("auctionowner") ) {
string auctionowner = auction.getowner;
iterator principaliterator = user.getprincipals.iterator;
while(principaliterator.hasnext) {
principal principal = (principal) principaliterator.next;
if( principal.getname.equals(auctionowner) )
return true;
}
}
return false;
}
傳遞到 fulfills 方法中的關系字符串是策略文件中列出的關系。在這個案例中,我們使用了“auctionowner”字符串。
缺省情況下,xmlpolicyfile 類在當前工作目錄中查找名為 resourcepolicy.xml 的文件。系統屬性 com.ibm.resource.security.auth.policy 可以用于指定另一個不同的文件名和位置。
websphere application server 示例
除命令行示例之外,您可能還想運行這個簡單的程序,該程序為了 ibm websphere application server,version 4.0.2 而被優化。
一個可運行的示例
綜合這些信息,我們將運行一個簡單的命令行示例。該示例程序包含三個 jar 文件:
resourcesecurity.jar
example.jar
exampleactions.jar
resourcesecurity.jar 文件包含允許實例級訪問控制的 jaas 擴展框架。它還包含一個 loginmoduleexample 類,這個類從 xml 文件讀取用戶認證信息。用戶標識和密碼存儲在 users.xml 文件中。用戶組存儲在 groups.xml 文件中。關于 loginmoduleexample 的更多信息,請參閱參考資料部分。
該示例包含四個附加的文件:
login.conf
policy
resourcepolicy.xml
run.bat
在試圖運行這個示例程序之前,請確保更新了 run.bat、policy 和 resourcepolicy.xml 文件中的路徑。缺省情況下,所有的密碼都是“passw0rd”。
示例如何工作
該示例程序提示輸入用戶標識和密碼。它用 users.xml 文件中的條目核對所提供的用戶標識和密碼。在認證了用戶之后,程序設法創建一個 userprofile 類實例,修改它并從中讀取。缺省情況下,userprofile 類的所有者是 jane(jane)。當 jane 登錄時,三個操作全部成功。當 john(john)登錄時,只有創建操作成功。當 jane 的經理 lou(lou)登錄時,只有第一個和最后一個操作成功。當系統管理員(admin)登錄時,操作全部成功。當然,只有當提供的 resourcepolicy.xml 文件未被修改時,上述這些才都是真的。
示例安裝
下面的安裝指導假設您正在使用 jdk 1.3 并且已經把文件解壓縮到 d:\jaasexample 目錄。通過將文件解壓縮到這個目錄,您可以省去一些工作;否則您就必須使用正確的路徑名修改 policy 和 resourcesecurity.xml 策略文件。
下面是運行該示例需要做的工作:
下載這個示例的源文件。
把 jaas.jar 和 jaasmod.jar 復制到 jdk jre\lib\ext 目錄(即 d:\jdk1.3\jre\lib\ext)。
向位于 jdk 的 jre\lib\security 目錄(即 d:\jdk1.3\jre\lib\security)中的 java.security 文件的末尾添加下面的字符串:auth.policy.provider=com.ibm.resource.security.auth.xmlpolicyfile。
執行 run.bat 文件。
結束語
類實例級授權把訪問控制分離到一個通用框架(該框架使用基于所有權和特定關系的策略)中。然后管理員可以在應用程序的生命周期內更改這些策略。用這種方法擴展 jaas 減少了您或另一個程序員必須在應用程序生命周期內業務規則發生更改時重寫代碼的可能性。
通過將關系字符串抽象為類可以進一步擴展特定關系這個概念。不調用 resource 實現類的 fulfills(subject user, string relationship) 方法,而只要調用 relationship 實現類中定義的新 fulfills(subject user, resource resource) 方法。這樣就會允許許多 resource 實現類使用相同的關系邏輯。
6.java的安全性
1. the security manager是一個application-wide object ( java.lang.securitymanager)
每個java application都可以有自己地security manager,但是默認地java application沒有一個security manager
可以通過下面地代碼得到一個security manager
try
{
system.setsecuritymanager(new securitymanager(“--”));
}
catch( )
2.
jdbc
在 jdbc 2 開發的過程中,sql99 還處在一種變化不定的情況下,F在規范已經完成了,而且數據庫廠商已經采用了部分標準。所以自然地,jdbc 規范就跟著將自己與 sql99 功能的一部分相統一。最新的 jdbc 規范已經采用了 sql99 標準中那些已經被廣泛支持的功能,還有那些在五年內可能會獲得支持的功能。
1. datasource
在jdbc2.0 optional package中,提供了透明的連接池(connection pooling)。
一旦配置了j2ee應用服務器后,只要用datasource獲取連接(connection),連接池(connection pooling)就會自動的工作。
如果用戶希望建立一個數據庫連接,通過查詢在jndi服務中的datasource,可以從datasource中獲取相應的數據庫連接。
datasource被認為是從jndi中獲取的網絡資源。
datasource在池中保存的對象都實現了pooledconnection接口。
當應用程序向datasource請求一個connection時,它會找到一個可用的pooledconnection對象。
如果連接池空了,它就向connectionpoolecdatasource請求一個新的pooledconnection對象
通過使用 datasource 接口 (jdbc 2.0) 或 drivermanager (jdbc 1.0) 接口,j2ee 組件可以獲得物理數據庫連接對象(connection)。要獲得邏輯(合用的)連接,j2ee 組件必須使用以下這些 jdbc 2.0 合用管理器接口:
javax.sql.connectionpooldatasource 接口,該接口充當合用的 java.sql.connection 對象的資源管理器連接 factory。每家數據庫服務器供應商都提供該接口的實現
(例如,oracle 實現 oracle.jdbc.pool.oracleconnectionpooldatasource 類)。
javax.sql.pooledconnection 接口,該接口封裝到數據庫的物理連接。同樣,數據庫供應商提供其實現。
對于那些接口和 xa 連接的每一個,都存在一個 xa(x/open 規范)等價定義。
2. resultset
在jdbc2.0中,為了獲得一個uptatable result,在query語句里必須包含primarykey,并且查詢的內容里必須來自一個table
ava.sql.resultset接口中定義了三種類型的結果集
type_forward_only
type_scroll_insensitive 這種類型的結果集支持雙向滾動
type_scroll_sensitive
如果要建立一個雙向滾動的resultset,一定要在建立statement的時候使用如下參數
statement stmt = conn.createstatement(resultset.type_scroll_insensitive,
resultset.concur_read_only);
3. jdbc驅動程序
連通oracle8.1.6的jdbc 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
把oracle8.1.6/lib/jdbc/*.zip copy 到 %java_home%/jre/lib/ext/*.jar
如果光copy不ren為.jar是沒有用的。
4. 事務處理
本地事務
java.sql.connection接口可以控制事務邊界(即開始和結束)。
在事務開始的時候調用setautocommit( false ), 而在中止事務時調用rollback或commit方法。這類事務叫本地事務。
分布式事務
但是,在特定的情況下,可能有多個客戶(例如兩個不同的servlet或ejb組件)參與了同一個事務。
或者,客戶在同一個事務中可能會執行跨越多個數據庫的數據庫操作。
jdbc2.0 optional package 同jta一起來實現分布式樣事務。
5. 一些技巧
檢索自動產生的關鍵字
為了解決對獲取自動產生的或自動增加的關鍵字的值的需求,jdbc 3.0 api 現在將獲取這種值變得很輕松。要確定任何所產生的關鍵字的值,只要簡單地在語句的 execute 方法中指定一個可選的標記,表示您有興趣獲取產生的值。您感興趣的程度可以是 statement.return_generated_keys,也可以是 statement.no_generated_keys。在執行這條語句后,所產生的關鍵字的值就會通過從 statement 的實例方法 getgeneratedkeys 來檢索 resultset 而獲得。resultset 包含了每個所產生的關鍵字的列。清單 1 中的示例創建一個新的作者并返回對應的自動產生的關鍵字。
清單 1. 檢索自動產生的關鍵字
statement stmt = conn.createstatement;
// obtain the generated key that results from the query.
stmt.executeupdate("insert into authors " +
'(first_name, last_name) " +
"values ('george', 'orwell')",
statement.return_generated_keys);
resultset rs = stmt.getgeneratedkeys;
if ( rs.next ) {
// retrieve the auto generated key(s).
int key = rs.getint;
}
jta/jts
1.jta/jts基本知識
服務器實現jts是否對應用程序開發人員來說不是很重要的。
對你來說,應該把jta看作是可用的api。
jta是用來開發distributed tansaction的 api.
而jts定義了支持jta中實現transaction manager 的規范。
javatransaction service (jts) specifies the implementation of a transaction manager which supports the java transaction api (jta) 1.0 specification at the high-level and implements the java mapping of the omg object transaction service (ots) 1.1 specification at the low-level. jts uses the standard corba orb/ts interfaces and internet inter-orb protocol (iiop) for transaction context propagation between jts transaction managers.
a jts transaction manager provides transaction services to the parties involved in distributed transactions: the application server, the resource manager, the standalone transactional application, and the communication resource manager (crm).
2.jta
1.1 事務處理的概念
jta實際上是由兩部分組成的:一個高級的事務性客戶接口和一個低級的 x/open xa接口。
我們關心的是高級客戶接口,因為bean可以訪問它,而且是推薦的客戶應用程序的事務性接口。
低級的xa接口是由ejb服務器和容器使用來自動協調事務和資源(如數據庫)的
1.1.1事務劃分
a.程序劃分
使用usertransaction啟動jta事務
the usertransaction interface defines the methods that allow an application to explicitly manage transaction boundaries.(from j2ee api
document)
java讀書心得 篇2
首選很感謝Joshua Bloch寫的這本書,當然更感謝我們的司令翻譯。至少目前我看到的100頁的內容,基本沒發現翻譯很別扭的地方,包括錯別字也沒有發現,至少沒有影響到我對書中內容的理解。再次感謝。
在后面的讀書心得里,我會根據我的個人理解,將書中的各個知識點逐個和大家分享。 書中的一些觀點我也不是完全贊同的,呵呵(估計是我的水平不夠,呵呵呵)。
我們先看全書第一個問題:考慮用靜態工廠方法代替構造器。
也就是,不再使用 new 這種方式來獲得一個類的實例,而是通過工廠方法獲得。
優點:
1 有名字
這個我體會還是比較深的,在JDK里,我見過一個類的最多的構造器數量,有16個。大家可以看看 Java.math.BigDecimal 這個類就知道了。
就算一個類的構造器有4個左右,我想你很可能在使用的時候會極其注意,不要選錯了到底是用哪一個。
所以,如果能提供一個很好命名的方法來實現構造類,確實是一個不錯的主意,比如
BigDecimal.getInstanceFromString(...); 我想這個名字雖然有點垃圾,但要表達的意思確實異常的明確。
在一些第三方的庫里面,這種情況更加突出。我許多時候不得不看看API文檔,來區分我的那個int參數到底是使用三個參數的構造器,還是使用四個參數的構造器。因為他們太像了。
2 可以單例
這個就不用說了,你可以在方法里干你要做的任何事情,而new絕對會給你一個新的實例。
3 可以返回任何子類型。
這個對于系統的擴展是很有用處的。new 已經決定了你肯定要這個類,而靜態方法卻可以修改,不一定肯定返回你方法所在的類,可以在必要時替換為一個子類。
4 代碼簡便
這點我體會不深,呵呵
不過這個寫法我確實經常用
List list = new ArrayList;
后面的那個ArrayList里面的 String就是一個例子吧。不過我倒是不是很在意這個,因為我很喜歡這樣寫了。
下面這個例子看上去確實不錯。呵呵!
[java] view plain copypublic class Test extends Thread {
public static void main(String args) {
Test te = Test.newInstance;
}
public static Test newInstance {
return new Test;
}
}
java讀書心得 篇3
以前阿秀曾經跟我提到過這本書,我貌似也看見她在我電腦里也下過這本書,當時我也沒在意。后來也托她的福,張章同學把這本書交到了我手里!當然當時的使用權不屬于我,后來因為些原因最終使用權還是屬于我了。照這么回憶其實我跟這本書還挺有緣,若不是我在莫大的東臺大潤發超市巧遇張章同學三次,這本書也不會到我手里啊!
這本書主要講述的是,作者采訪精神病人時的故事。通俗的說,就是以精神病人的角度去看這個,我們不斷質疑的世界。
其實生活中我們常常質疑這個世界,例如先有蛋還是先有雞,活著的真正目的到底是為了什么等等一系列的質疑!我們正常人也許只是從表面分析一下。而精神病患者往往會偏執于他們所執著的事,把一些微小的事放大化的來看,以至于做出些極端的事情。所以在正常人的眼里他們病了,俗稱“精神病患者”。
書中提到有很多精神病醫師因為長時間跟精神病患者接觸最終他們也“病”了,也許在他們的內心深處本來就存在些因素。因為長時間跟精神病患者接觸他們內心里面的平衡點被打亂了,所以“病”了!其實天才與瘋子只是一線之隔,關鍵在于內心里那個平衡點!
書中有兩個愛情故事。但是可以用一段文字說明。摘抄的。
指間的戒指不再閃亮
婚紗在衣柜早就塵封
我們的容顏都已慢慢蒼老
感謝你帶給我的每一天
正是因為你
我才有勇氣說:
“永遠,永遠!
第一個故事是一位臆想癥的老人,老伴逝去多年,依然認為他活著。
第二個故事是一位喪偶的中年人,不斷的學習生理等課程,為了復活愛人。
感觸很深,然后靜默不言。
’‘’‘’‘’‘’‘’‘’‘書中有一段是講“角度問題”。一個女“患者” 說在工作外她會是個孩子,她喜歡這個新鮮的世界,而不是去習慣這個世界,每個人都有權利選擇自己的喜好而不是必須跟別人一樣的態度!這個女人其實沒有問題,反而是認為她有問題的人才有問題。不是每個人都習慣墨守成規,孩子是的列子。不是所有大多數人認為對的事情就是對的,大多數人認為錯的事情就是錯的!而那個“大多數“的界限往往讓我們思想上有限制了,所以漸漸的我們也就習慣了!
書中結尾是我最喜歡的一句話“人生若只如初見“!