<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    倉藍

    日記本

      BlogJava :: 首頁 :: 聯系 :: 聚合  :: 管理
      23 Posts :: 0 Stories :: 1 Comments :: 0 Trackbacks

    #

    這個世界每天都在發生著這樣或者那樣千奇百怪的事情每個人的人生都有著太多的未知數,誰也不知道自己的明天會怎樣大多數的情況下都是走一步算一步,所以我們都是應該做的就是活在當下。做政局自己能夠把握機遇的事情就可以了,有著太多的奢望到最后或許你什么也沒撈到,所有的一切都是空想這樣的結果才會讓事實說話,雖然說有些事情我們可以掌握但是畢竟是那么的微小,在大自然面前我常常覺得我個人的力量對比是如此的有限,努力提高自己的個人能力,把配合默契本分做好就已經是非常的不錯了。相信傳動軸命運的轉化總會有實現的那么天。常常寫一些心得日記本能夠放松一下心情舒暢也算是很好的調節器吧,經常保持一個平常心的狀態你會活得更加現實意義一點,在穩定增長以后再慢慢的為理想目標管理方向努力奮斗加油。
    posted @ 2013-09-25 11:21 cangshi 閱讀(355) | 評論 (0)編輯 收藏

    中秋還沒有放假之前老大就已經出差了,但是他已經給我布置了任務書我想希望在計劃好的時間內執行任務吧,有可能之前時間太緊也沒有來得及看清楚所以導致細節沒有講清楚,現在倒好,沒有能夠按照國際慣例時間完成任務算了吧,先按照統籌安排的方法做其他的工作,等待他回來再做那些工作也是可以的,沒有什么東西是死而不僵的,必須要靈活機動才能保證時刻都在運轉之中吧中。所以一不定期要加強自知的修養多給自己充電,由于拒絕鏈接這一步之前沒有弄過,害得我損失了很多的周期性我想我可能犯下錯誤觀點了,于是趕緊在昨天把還沒有生效的鏈接全部還原了。現在剩下的就是等待老白的更新了,老白這幾天倒是沒有發生什么異樣的舉動我想保持原狀我就沒有什么更多的擔心了,老大一直在等待著我的結果呢只要效果,過程沒有人管你,所以我的壓力還是蠻大的,這一關能不能過就要看近期內的變化了,我是會堅持每天都會觀察員的,以后還應該是做個排名更新的記錄吧這樣對把握時間管理會心里有底一點。加油
    posted @ 2013-09-23 11:29 cangshi 閱讀(136) | 評論 (0)編輯 收藏

    上帝對每個人最公平的是只有時間,他每天給任何一個人的時間都只有二十四小時。把日常工作中的事情按捺不住完了以后我幾乎沒有多少時間了,所以我也慢慢騰騰失去了更新換代的時間了。間隔了這么久,我實在是擠不出成果而我目前的狀況還只是試用期。我所有的努力奮斗還沒有達到一個明顯的效果,我在跟時間賽跑相對來說我有資源的情況下也才這樣,如果說沒有資源那么我是否生活不下去了呢,算了吧我最大的愿望就是在最后的一個月里努力把排名推廣應用,給老板一個滿意的答案吧說太多的廢話過日子都是無用的我只是想多做事少說話。這樣專心一點心里面的印象會更加深刻一點。好吧今天的作業成績就至此為止,有機會再慢慢研究工作吧加油。
    posted @ 2013-09-17 11:20 cangshi 閱讀(145) | 評論 (0)編輯 收藏

    我的人生過了二十多個春秋,我覺得我的人生有太多的無奈,很多時候只能一個人默默的去承受,
    不敢告訴別人,其實也沒必要告訴別人,也無濟于事。家里很困難。來自農村,讀書高中的時候就已經很緊了。生活老是不及其余表,青黃不接,家里沒有經濟來源,所有的一切就是幾畝地,一年到頭也沒買到幾憏錢。幾兄弟都沒有讀完初中,只有我讀大學,但是我為什么就是個好面子的人呢,所有的這些苦澀不想讓人知道,窮人的命,沒有一楔丁點的人際關系,真是窮得無法形容了。我只想對的時間做對的事過濾器臺。
    過去的事就讓他地[去吧]。下層階級的局姢性隨時曉霧出來。
    好了,希望老白對我友好我就感到安慰了,我會把磁力泵的電磁閥修好的,以后的生活就有一點點保障吧
    也算是有了個依靠,讓老爸老媽放心就行了。






    posted @ 2012-11-05 11:03 cangshi 閱讀(290) | 評論 (0)編輯 收藏


          當你在配置Struts 2這個應用程序時,安全功能是一個最關鍵的問題,本文章詳細介紹一下這方面的內容,希望對大家有所幫助吧。呵呵,當然,如果有不當之處,也請朋友們指正啊!配置Struts 2應用程序是基于servlet技術的,所以Struts 2的安全策略也可以使用配置文件進行靈活的配置。

    配置安全策略時,有兩個概念需要清楚的區分 ,用戶和角色,簡單的說用戶為使用計算機的人,可以是個人或組織。角色是一個抽象的概念,泛指職務或者權限。例如,張三,李四,王五三個人,有職員、主管和經理三個職務(權限),張三是用戶,張三可以是主管職務,代表張三這個用戶含有主管的權利。

    不同的servlet容器所提供的用戶和角色管理機制是不相同的。我使用的是Tomcat服務器,它提供的用戶和角色管理機制文件是在其安裝目錄下的conf目錄中的tomcat-users.xml文件,可以在這個文件里完成對用戶和角色的編輯。例如:

    1. <tomcat-users> 
    2.     <role rolename="tomcat"/> 
    3.     <role rolename="role1"/> 
    4.     <user username="tomcat" password="tomcat" roles="tomcat"/> 
    5.     <user username="both" password="tomcat" roles="tomcat,role1"/> 
    6.     <user username="role1" password="tomcat" roles="role1"/> 
    7. </tomcat-users> 

    這個文件定義了2個角色(tomcat和role1)和3名用戶(tomcat、both和role1)。你可以在tomcat-users.xml文件里定義任意多個用戶和角色。

    使用Struts 2保護應用程序的資源

    Struts 2應用程序的安全策略是通過部署web.xml文件中的security-constraint元素實現的,該元素的語法定義:

    1. <!ELEMENT security-constraint (display-name?, web-resource-collection+, auth-constraint?, user-data-constraint?)>  
    2. <!ELEMENT display-name (#PCDATA)>  
    3. <!ELEMENT web-resource-collection (web-resource-name, description?, url-pattern*, http-method*)>  
    4. <!ELEMENT auth-constraint (description?, role-name*)>  
    5. <!ELEMENT user-data-constraint (description?, transport-guarantee)> 

    該語法說明了,security-constraint元素可以有一個可選的display-name子元素,至少一個web-resource-collection子元素,一個可選的auth-constraint子元素和一個可選的user-data-constraint子元素。

    web-resource-collection子元素是用來列出打算保護的Web資源,具體的做法是為這些資源設置URL限制,它是通過設置web-resource-collection元素包含的子元素實現的:

    ◆  web-resource-name:是與受保護資源相關聯的名稱。該子元素為必須元素。

    ◆  description:對給定資源的描述。這個子元素為可選元素。

    ◆  url-pattern:用來設置URL表達式,與這個URL表達式相匹配的URL地址指向的資源將受到保護。該子元素為至少有一個,為必須元素。

    ◆  http-method:用來表明哪些HTTP方法將受到限制,例如設置為GET那么所有的GET請求就將受到限制。該元素為可選元素。

    auth-constraint元素用于指定可以訪問該資源用戶角色集合。如果沒有指定auth-constraint元素,就將安全約束應用于所有角色。它包含下面幾個子元素:

    ◆  description:描述。該元素是可選元素。

    ◆  role-name:可以訪問保護資源的用戶角色。該元素可以有多個。

    ◆  user-data-constraint元素用來設置怎樣保護在客戶端和Web容器之間傳遞的數據。

    ◆  description: 描述。可選元素。

    ◆  transport-guarantee :該元素有以下幾個值

    1. NONE,這意味著應用不需要傳輸保證。

    2. INTEGRAL,意味著服務器和客戶端之間的數據必須以某種方式發送,而且在傳送中數據不能被篡改。

    3. CONFIDENTIAL,這意味著傳輸的數據必須加密。

    配置完畢security-constraint元素的基本信息,大致為下面的格式:

    1. <security-constraint> 
    2.     <web-resource-collection> 
    3.         <web-resource-name>Admin Arew</web-resource-name> 
    4.         <url-pattern>*.action</url-pattern> 
    5.     </web-resource-collection> 
    6.     <auth-constraint> 
    7.         <role-name>myeclipseWeb</role-name> 
    8.     </auth-constraint> 
    9. </security-constraint> 

    這個security-constraint元素的效果為:只要與表達式"*.action"匹配的請求不是來自擁有"myeclipseWeb"權限的用戶,Web容器就會阻斷它。在這里還可以使用http-method元素,阻斷特定方法的請求,因為沒有使用會阻斷所有方法提交的請求。

    設置完安全策略后,還需要設置讓用戶有機會提供證明,證明自己有權限訪問這個受限資源的登陸方法。允許使用的登陸方法使用login-config元素設置,下面為login-config元素的語法定義:

    1. <!ELEMENT login-config (auth-method?, realm-name?, form-login-config?)>  
    2. <!ELEMENT auth-method (#PCDATA)>  
    3. <!ELEMENT realm-name (#PCDATA)>  
    4. <!ELEMENT form-login-config (form-login-page, form-error-page)> 

    login-config子元素的描述如下:
    ◆  auth-method指定用來驗證用戶身份的方法。它的值為下面的一個:BASIC、DIGEST、FORM或 CLIENT-CERT
    ◆  realm-name指定HTTP Basic驗證中在標準登陸框中顯示的一條提示。
    ◆  form-login-config元素是在<auth-method>元素值為"FORM"時使用的。它是指定基于表單的登錄中應該使用的登錄頁面和出錯頁面。如果沒有使用基于表單的驗證,則忽略這些元素。這個元素的定義如下,其中form-login-page用于指定顯示登錄頁面的資源路徑, form-error-page則用于指定用戶登錄失敗時顯示出錯頁面的資源路徑。

    1. <!ELEMENT form-login-config (form-login-page, form-error-page)>  
    2. <!ELEMENT form-login-page (#PCDATA)>  
    3. <!ELEMENT form-error-page (#PCDATA)> 

    設置完登陸方法后,還應該使用security-role元素,注冊允許用來訪問受保護資源所有角色。在該元素內部使用一個role-name子元素來注冊一個角色。例如:

    1. <security-role> 
    2.     <role-name>myeclipseWeb</role-name> 
    3. </security-role> 

    注冊了一個"myeclipseWeb"的角色。

    演示示例:使用BASIC登陸方法驗證用戶身份

    1.我使用的Servlet容器是Tomcat,找到它的目錄下conf目錄中的tomcat-users.xml文件打開內容如下:

    1. <?xml version='1.0' encoding='utf-8'?> 
    2. <tomcat-users> 
    3.     <role rolename="myeclipseWeb"/> 
    4.     <role rolename="myeclipseWebservices"/> 
    5.     <user username="webservices" password="webservices-pwd" roles="myeclipseWebservices"/> 
    6.     <user username="admin" password="admin-pwd" roles="myeclipseWeb,myeclipseWebservices"/> 
    7.     <user username="web" password="web-pwd" roles="myeclipseWeb"/> 
    8. </tomcat-users> 

    我使用的IDE是myEclipse9.0,它配置好Tomcat下的tomcat-users.xml文件內容如上,我直接使用它了,你也可以添加自己的角色和用戶。該文件定義了2個角色和3個用戶,每一個用戶都由自己的角色(或者說權限,可以有多重權限)。

    2.創建Web項目,找到web.xml,配置它,使它支持Struts 2并且啟動Struts 2的安全策略

    1. <?xml version="1.0" encoding="UTF-8"?> 
    2. <web-app id="WebApp_9" version="2.4"  
    3.          xmlns="http://java.sun.com/xml/ns/j2ee"  
    4.          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
    5.          xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> 
    6.     <display-name>Struts Blank</display-name> 
    7.     <filter> 
    8.         <filter-name>struts2</filter-name> 
    9.         <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class> 
    10.     </filter> 
    11.     <filter-mapping> 
    12.         <filter-name>struts2</filter-name> 
    13.         <url-pattern>/*</url-pattern> 
    14.     </filter-mapping> 
    15.     <welcome-file-list> 
    16.         <welcome-file>index.html</welcome-file> 
    17.     </welcome-file-list> 
    18.     <!--  配置應用程序需要保護的資源與什么角色才可以訪問它   --> 
    19.     <security-constraint> 
    20.         <web-resource-collection> 
    21.             <web-resource-name>Admin Arew</web-resource-name> 
    22.             <url-pattern>*.action</url-pattern> 
    23.         </web-resource-collection> 
    24.         <auth-constraint> 
    25.             <role-name>myeclipseWeb</role-name> 
    26.         </auth-constraint> 
    27.     </security-constraint> 
    28.     <!-- 注冊可以訪問保護資源的角色  --> 
    29.     <security-role> 
    30.         <role-name>myeclipseWeb</role-name> 
    31.     </security-role> 
    32.     <security-role> 
    33.         <role-name>myeclipseWebservices</role-name> 
    34.     </security-role> 
    35.     <!--  設置登錄方法  --> 
    36.     <login-config> 
    37.         <auth-method>BASIC</auth-method> 
    38.         <realm-name>User Basic Authentication</realm-name> 
    39.     </login-config> 
    40. </web-app> 

    3. 創建接收一個字段信息的動作類:

    1. public class SecureAction extends ActionSupport { 
    2.     private static final long serialVersionUID = 1961430702313132722L; 
    3.     private String username; 
    4.     public String getUsername() { 
    5.         return username; 
    6.     } 
    7.     public void setUsername(String username) { 
    8.         this.username = username; 
    9.     } 
    10.     @Override 
    11.     public String execute() 
    12.     { 
    13.         return SUCCESS; 
    14.     } 

    4. 創建struts.xml配置文件,聲明動作

    1. <?xml version="1.0" encoding="UTF-8" ?> 
    2. <!DOCTYPE struts PUBLIC 
    3.     "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" 
    4.     "http://struts.apache.org/dtds/struts-2.0.dtd"> 
    5. <struts> 
    6.     <package name="securePackage" extends="struts-default"> 
    7.         <action name="secure" class="struts2.action.SecureAction"> 
    8.             <result name="success">/index.jsp</result> 
    9.         </action> 
    10.     </package> 
    11. </struts> 

    5. 創建輸入頁面input.jsp和結果頁面index.jsp

    input.jsp:

    1. <body> 
    2.     <s:form action="secure"> 
    3.         <s:textfield name="username" label="Enter your name"></s:textfield> 
    4.         <s:submit value="submit"></s:submit> 
    5.     </s:form> 
    6. </body> 

    index.jsp

    1. <body> 
    2.     <s:property value="username"/>,Welcome 
    3. </body> 

    6.測試效果,在瀏覽器輸入:http://localhost:8081/SecureTest/input.jsp,得到如下自力式溫度調節閥界面:輸入"Tom",點擊"submit"按鈕,查看效果:


    看到了登陸框了吧,此時我們要訪問的資源是一個受限資源所以要求權限驗證頂裝式球閥,還記得我們的用戶表吧,查看用戶表輸入用戶信息查看結果:

     

    輸入"webservices"與"webservices-pwd"的用戶信息:

     

    提示了一個"403"錯誤,這是因為雖然用戶信息正確,但是"webservices"用戶的沒有"myeclipseWeb"權限。

    這次輸入一個不存在的用戶信息:

    這次獲得了一個"401"錯誤,這是登陸失敗的提示結果,這里會因瀏覽器的不同而需要不同次數的失敗登陸才會得到這個結果。

    接下來輸入一個正確的用戶,并且擁有"webservices"權限的用戶信息:

    點擊"確定",獲得如下結果:

    可以看到,我們成功的訪問了受保護的資源。若要傳中文字,解決方案我已經在前面"配置Struts2"時介紹過了,需要修改Struts 2默認的編碼方式還需要修改頁面的編碼方式,都改為"GBK"。

     

    posted @ 2012-03-22 11:21 cangshi 閱讀(346) | 評論 (0)編輯 收藏

    Java虛擬機技術參數應用詳解
          JAVA虛擬機參數主要分為基本和擴展兩類,在命令行中輸入JAVA_HOME\bin\java 就可得到基本參數列表,在命令行輸入JAVA_HOME\bin\java –X 就可得到擴展參數列表。

      基本參數說明:

      -client,-server

      這兩個參數用于設置虛擬機使用何種運行模式,client模式啟動比較快,但運行時性能和內存管理效率不如server模式,通常用于客戶端應用程序。相反,server模式啟動比client慢,但可獲得更高的運行性能。

      在 windows上,缺省的虛擬機類型為client模式,如果要使用server模式,就需要在啟動虛擬機時加-server參數,以獲得更高性能,對服務器端應用,推薦采用server模式,尤其是多個CPU的系統。在Linux,Solaris上缺省采用server模式。

      -hotspot

      含義與client相同,jdk1.4以前使用的參數,jdk1.4開始不再使用,代之以client.

      -classpath,-cp

      虛擬機在運行一個類時,需要將其裝入內存,虛擬機搜索類的方式和順序如下:

      Bootstrap classes,Extension classes,User classes.

      Bootstrap 中的路徑是虛擬機自帶的jar或zip文件,虛擬機首先搜索這些包文件,用System.getProperty("sun.boot.class.path")可得到虛擬機搜索的包名。

      Extension是位于jre\lib\ext目錄下的jar文件,虛擬機在搜索完Bootstrap后就搜索該目錄下的jar文件。用System. getProperty("java.ext.dirs“)可得到虛擬機使用Extension搜索路徑。

      User classes搜索順序為當前目錄、環境變量 CLASSPATH、-classpath.

      -classpath告知虛擬機搜索目錄名、jar文檔名、zip文檔名,之間用分號;分隔。

      例如當你自己開發了公共類并包裝成一個common.jar包,在使用common.jar中的類時,就需要用-classpath common.jar 告訴虛擬機從common.jar中查找該類,否則虛擬機就會拋出java.lang.NoClassDefFoundError異常,表明未找到類定義。

      在運行時可用System.getProperty(“java.class.path”)得到虛擬機查找類的路徑。

      使用-classpath后虛擬機將不再使用CLASSPATH中的類搜索路徑,如果-classpath和CLASSPATH都沒有設置,則虛擬機使用當前路徑(。)作為類搜索路徑。

      推薦使用-classpath來定義虛擬機要搜索的類路徑,而不要使用環境變量 CLASSPATH的搜索路徑,以減少多個項目同時使用CLASSPATH時存在的潛在沖突。例如應用1要使用a1.0.jar中的類G,應用2要使用 a2.0.jar中的類G,a2.0.jar是a1.0.jar的升級包,當a1.0.jar,a2.0.jar都在CLASSPATH中,虛擬機搜索到第一個包中的類G時就停止搜索,如果應用1應用2的虛擬機都從CLASSPATH中搜索,就會有一個應用得不到正確版本的類G.

      -D<propertyName>=value

      在虛擬機的系統屬性中設置屬性名/值對,運行在此虛擬機之上的應用程序可用System.getProperty(“propertyName”)得到value的值。

      如果value中有空格,則需要用雙引號將該值括起來,如-Dname=“space string”。

      該參數通常用于設置系統級全局變量值,如配置文件路徑,應為該屬性在程序中任何地方都可訪問。

      -verbose[:class|gc|jni]

      在輸出設備上顯示虛擬機運行信息。

      verbose和verbose:class含義相同,輸出虛擬機裝入的類的信息,顯示的信息格式如下:

      [Loaded java.io.FilePermission$1 from shared objects file]

      當虛擬機報告類找不到或類沖突時可用此參數來診斷來查看虛擬機從裝入類的情況。

      -verbose:gc在虛擬機發生內存回收時在輸出設備顯示信息,格式如下:

      [Full GC 268K->168K(1984K), 0.0187390 secs]

      該參數用來監視虛擬機內存回收的情況。

      -verbose:jni在虛擬機調用native方法時輸出設備顯示信息,格式如下:

      [Dynamic-linking native method HelloNative.sum …… JNI]

      該參數用來監視虛擬機調用本地方法的情況,在發生jni錯誤時可為診斷提供便利。

      -version

      顯示可運行的虛擬機版本信息然后退出。一臺機器上裝有不同版本的JDK時

      -showversion

      顯示版本信息以及幫助信息。

      -ea[:<packagename>……|:<classname>]

      -enableassertions[:<packagename>……|:<classname>]

      從JDK1.4開始,java可支持斷言機制,用于診斷運行時問題。通常在測試階段使斷言有效,在正式運行時不需要運行斷言。斷言后的表達式的值是一個邏輯值,為true時斷言不運行,為false時斷言運行,拋出java.lang.AssertionError錯誤。

      上述參數就用來設置虛擬機是否啟動斷言機制,缺省時虛擬機關閉斷言機制,用-ea可打開斷言機制,不加<packagename>和 classname時運行所有包和類中的斷言,如果希望只運行某些包或類中的斷言,可將包名或類名加到-ea之后。例如要啟動包com.foo.util 中的斷言,可用命令 –ea:com.foo.util .

      -da[:<packagename>……|:<classname>]

      -disableassertions[:<packagename>……|:<classname>]

      用來設置虛擬機關閉斷言處理,packagename和classname的使用方法和-ea相同。

      -esa | -enablesystemassertions

      設置虛擬機顯示系統類的斷言。

      -dsa | -disablesystemassertions

      設置虛擬機關閉系統類的斷言。

      -agentlib:<libname>[=<options>]

      該參數是JDK5新引入的,用于虛擬機裝載本地代理庫。

      Libname為本地代理庫文件名,虛擬機的搜索路徑為環境變量PATH中的路徑,options為傳給本地庫啟動時的參數,多個參數之間用逗號分隔。在Windows平臺上虛擬機搜索本地庫名為libname.dll的文件,在 Unix上虛擬機搜索本地庫名為libname.so的文件,搜索路徑環境變量在不同系統上有所不同,Linux、SunOS、IRIX上為 LD_LIBRARY_PATH,AIX上為LIBPATH,HP-UX上為SHLIB_PATH.

      例如可使用-agentlib:hprof來獲取虛擬機的運行情況,包括CPU、內存、線程等的運行數據,并可輸出到指定文件中,可用-agentlib:hprof=help來得到使用幫助列表。在jre\bin目錄下可發現hprof.dll文件。

      -agentpath:<pathname>[=<options>]

      設置虛擬機按全路徑裝載本地庫,不再搜索PATH中的路徑。其他功能和agentlib相同。

      -javaagent:<jarpath>[=<options>]

      虛擬機啟動時裝入java語言設備代理。Jarpath文件中的mainfest文件必須有Agent-Class屬性。代理類要實現public static void premain(String agentArgs, Instrumentation inst)方法。當虛擬機初始化時,將按代理類的說明順序調用premain方法。

      參見:java.lang.instrument

      擴展參數說明

      -Xmixed

      設置-client模式虛擬機對使用頻率高的方式進行Just-In-Time編譯和執行,對其他方法使用解釋方式執行。該方式是虛擬機缺省模式。

      -Xint

      設置-client模式下運行的虛擬機以解釋方式執行類的字節碼,不將字節碼編譯為本機碼。

      -Xbootclasspath:path

      -Xbootclasspath/a:path

      -Xbootclasspath/p:path

      改變虛擬機裝載缺省系統運行包rt.jar而從-Xbootclasspath中設定的搜索路徑中裝載系統運行類。除非你自己能寫一個運行時,否則不會用到該參數。

      /a:將在缺省搜索路徑后加上path 中的搜索路徑。

      /p:在缺省搜索路徑前先搜索path中的搜索路徑。

      -Xnoclassgc

      關閉虛擬機對class的垃圾回收功能。

      -Xincgc

      啟動增量垃圾收集器,缺省是關閉的。增量垃圾收集器能減少偶然發生的長時間的垃圾回收造成的暫停時間。但濃漿泵增量垃圾收集器和應用程序并發執行,因此會占用部分CPU在應用程序上的功能。

      -Xloggc:<file>

      將虛擬機每次垃圾回收的信息寫到日志文件中,文件名由file指定,文件格式是平文件,內容和-verbose:gc輸出內容相同。

      -Xbatch

      虛擬機的缺省運行方式是在后臺編譯類代碼,然后在前臺執行代碼,使用-Xbatch參數將關閉虛擬機后臺編譯,在前臺編譯完成后再執行。

      -Xms<size>

      設置虛擬機可用內存堆的初始大小,缺省單位為字節,該大小為1024的整數倍并且要大于1MB,可用k(K)或m(M)為單位來設置較大的內存數。初始堆大小為2MB.

      例如:-Xms6400K,-Xms256M

      -Xmx<size>

      設置虛擬機內存堆的最大可用大小,缺省單位為字節。該值必須為1024整數倍,并且要大于2MB.可用k(K)或m(M)為單位來設置較大的內存數。缺省堆最大值為64MB.

      例如:-Xmx81920K,-Xmx80M

      當應用程序申請了大內存運行時虛擬機拋出java.lang.OutOfMemoryError: Java heap space錯誤,就需要使用-Xmx設置較大的可用內存堆泵。

      -Xss<size>

      設置線程棧的大小,缺省單位為字節。與-Xmx類似,也可用K或M來設置較大的值。通常操作系統分配給線程棧的缺省大小為1MB.

      另外也可在java中創建線程對象時設置棧的大小,構造函數原型為Thread(ThreadGroup group, Runnable target, String name, long stackSize)。

      -Xprof

      輸出CPU運行時的診斷信息。

      -Xfuture

      對類文件進行嚴格格式檢查,以保證類代碼符合類代碼規范。為保持向后兼容,虛擬機缺省不進行嚴格的格式檢查。

      -Xrs

      減少虛擬機中操作系統的信號(singals)的使用。該參數通常用在虛擬機以后臺服務方式運行時使用(如Servlet)。

      -Xcheck:jni

      調用JNI函數時進行附加的檢查,特別地虛擬機將校驗傳遞給JNI函數參數的合法性,在本地代碼中遇到非法數據時,虛擬機將報一個致命錯誤而終止。使用該閥參數后將造成性能下降。

     

    posted @ 2012-03-06 10:50 cangshi 閱讀(415) | 評論 (0)編輯 收藏

       JAVA之JDK在64位系統默認開啟壓縮指針分析(請多多指正!)
          Sun的HotSpot VM從JDK5開始會根據運行環境來自動設定VM的一些參數(ergonomics)。其中大家最熟悉的可能是它會自動選擇client與server模式、堆的初始和最大大小等。事實上ergonomics會設置非常多的內部參數,包括自動選擇GC算法、并行GC的線程數、GC的工作區分塊大小、對象晉升閾值等等。

      Ergonomics相關的邏輯大都在hotspot/src/share/vm/runtime/arguments.cpp中,值得留意的是使用了FLAG_SET_ERGO()的地方。

      于是我們可以留意一下幾個版本的HotSpot對UseCompressedOops參數的處理的差異:

      HotSpot 16:

      C++代碼

  • #ifdef _LP64     
  •   // Check that UseCompressedOops can be set with 
    the max heap size allocated   
     
  •   // by ergonomics.     
  •   if (MaxHeapSize <= max_heap_for_compressed_oops()) {     
  •     if (FLAG_IS_DEFAULT(UseCompressedOops)) {     
  •       // Turn off until bug is fixed.     
  •       // the following line to return it to default status.     
  •       // FLAG_SET_ERGO(bool, UseCompressedOops, true);     
  •     }     
  •     // ...     
  •   }     
  • #endif // _LP64
  •   HotSpot 17:

      C++代碼

  • #ifndef ZERO     
  • #ifdef _LP64     
  •   // Check that UseCompressedOops can be set with 
    the max heap size allocated   
     
  •   // by ergonomics.     
  •   if (MaxHeapSize <= max_heap_for_compressed_oops()) {     
  • #ifndef COMPILER1     
  •     if (FLAG_IS_DEFAULT(UseCompressedOops) && !UseG1GC) {     
  •       // Disable Compressed Oops by default. Uncomment 
    next line to enable it.   
     
  •       // FLAG_SET_ERGO(bool, UseCompressedOops, true);     
  •     }     
  •   }     
  • #endif     
  •   // ...     
  • #endif // _LP64     
  • #endif // !ZERO    
  •   HotSpot 19 / HotSpot 20:

      C++代碼

  • #ifndef ZERO     
  • #ifdef _LP64     
  •   // Check that UseCompressedOops can be set with 
    the max heap size allocated   
     
  •   // by ergonomics.     
  •   if (MaxHeapSize <= max_heap_for_compressed_oops()) {     
  • #ifndef COMPILER1     
  •     if (FLAG_IS_DEFAULT(UseCompressedOops) && !UseG1GC) {     
  •       FLAG_SET_ERGO(bool, UseCompressedOops, true);     
  •     }     
  • #endif     
  •   }     
  •   // ...     
  • #endif // _LP64     
  • #endif // !ZERO
  •   (注:HotSpot VM的版本號與JDK的版本號之間的關系,請參考另一篇筆記:Sun/Oracle JDK、OpenJDK、HotSpot VM版本之間的對應關系)

      可以看到,UseCompressedOops參數從HotSpot 19開始終于開始受ergonomics控制,會在下述條件滿足的時候默認開啟管道磁力泵

      1、是64位系統(#ifdef _LP64)并且不是client VM(#ifndef COMPILER1);

      2、Java堆的最大大小不大于一個閾值(MaxHeapSize <= max_heap_for_compressed_oops());

      3、沒有通過。hotspotrc或命令行參數手動設定過UseCompressedOops參數的值;

      4、沒有使用Garbage-First (G1) GC.


    第1、3、4點都很直觀,于是第2點就是個關鍵點了:閾值是多大?

      還是看回代碼,HotSpot 20:

      C++代碼

  • void set_object_alignment() {     
  •   // Object alignment.     
  •   assert(is_power_of_2(ObjectAlignmentInBytes), "ObjectAlignmentInBytes must be power of 2");     
  •   MinObjAlignmentInBytes     = ObjectAlignmentInBytes;     
  •   assert(MinObjAlignmentInBytes >= HeapWordsPerLong * HeapWordSize, 
    "ObjectAlignmentInBytes value is too small");     
  •   MinObjAlignment         = MinObjAlignmentInBytes / HeapWordSize;     
  •   assert(MinObjAlignmentInBytes == MinObjAlignment * HeapWordSize, 
    "ObjectAlignmentInBytes value is incorrect");     
  •   MinObjAlignmentInBytesMask = MinObjAlignmentInBytes - 1;     
  •     
  •   LogMinObjAlignmentInBytes  = exact_log2(ObjectAlignmentInBytes);     
  •   LogMinObjAlignment         = LogMinObjAlignmentInBytes - LogHeapWordSize;     
  •     
  •   // Oop encoding heap max     
  •   OopEncodingHeapMax = (uint64_t(max_juint) + 1) << LogMinObjAlignmentInBytes;     
  • }     
  •     
  • inline uintx max_heap_for_compressed_oops() {     
  •   // Avoid sign flip.     
  •   if (OopEncodingHeapMax < MaxPermSize + os::vm_page_size()) {     
  •     return 0;     
  •   }     
  •   LP64_ONLY(return OopEncodingHeapMax - MaxPermSize - os::vm_page_size());     
  •   NOT_LP64(ShouldNotReachHere(); return 0);     
  • }
  •   (注:其中 (uint64_t(max_juint) + 1) 的值也被稱為NarrowOopHeapMax,也就是2的32次方,0x100000000;

      ObjectAlignmentInBytes在64位HotSpot上默認為8;

      HeapWord在globalDefinitions.hpp里定義,大小跟一個char*一樣;

      HeapWordSize在同一個文件里定義,等于sizeof(HeapWord),在64位系統上值為8;

      LogHeapWordSize也在同一文件里,在64位系統上定義為3)

      跟蹤一下里面幾個參數的計算,在64位HotSpot上有,

      C++代碼

    1. ObjectAlignmentInBytes = 8     
    2. MinObjAlignmentInBytes = 8     
    3. HeapWordSize = 8     
    4. MinObjAlignment = 1     
    5. MinObjAlignmentInBytesMask = 0x0111     
    6. LogMinObjAlignmentInBytes = 3     
    7. LogHeapWordSize = 3 // _LP64     
    8. LogMinObjAlignment = 0     
    9. OopEncodingHeapMax = 0x800000000 // 32GB    

      于是,前面提到的第2個條件在64位HotSpot VM上默認是:

      C++代碼

  • MaxHeapSize + MaxPermSize + os::vm_page_size() <= 32GB
  •   os::vm_page_size()是操作系統的虛擬內存的分頁大小,在Linux上等于sysconf(_SC_PAGESIZE)的值;在x86_64上的Linux默認分頁大小為4KB.

      MaxHeapSize的值基本上等于-Xmx參數設置的值(會根據分頁大小、對齊等因素做調整)。

      MaxPermSize就是perm gen設置的最大大小。

      這下可以確認,在我現在用的環境里,當包括perm gen在內的GC堆大小在32GB - 4KB以下的時候,使用64位的JDK 6 update 23或更高版本就會自動開啟UseCompressedOops功能


    posted @ 2012-03-02 11:07 cangshi 閱讀(2249) | 評論 (0)編輯 收藏

    深入解析Java核心內容:JVM中的棧和局部變量
            總的來說,深入Java核心其實最主要包含個方面的內容:JVM中的棧和局部變量 Java內存分配原理  Java垃圾回收機制  Java中多態的實現機制

    Java中的棧

    每當啟用一個線程時,JVM就為他分配一個Java棧,棧是以幀為單位保存當前線程的運行狀態。某個線程正在執行的方法稱為當前方法,當前方法使用的棧幀稱為當前幀,當前方法所屬的類稱為當前類,當前類的常量池稱為當前常量池。當線程執行一個方法時,它會跟蹤當前常量池。

    每當線程調用一個Java方法時,JVM就會在該線程對應的棧中壓入一個幀,這個幀自然就成了當前幀。當執行這個方法時,它使用這個幀來存儲參數、局部變量、中間運算結果等等。

    Java棧上的所有數據都是私有的。任何線程都不能訪問另一個線程的棧數據。所以我們不用考慮多線程情況下棧數據訪問同步的情況。

    像方法區和堆一樣,Java棧和幀在內存中也不必是連續的,幀可以分布在連續的棧里,也可以分布在堆里

    Java棧的組成元素——棧幀

    棧幀由三部分組成:局部變量區、操作數棧、幀數據區。局部變量區和操作數棧的大小要視對應的方法而定,他們是按字長計算的。但調用一個方法時,它從類型信息中得到此方法局部變量區和操作數棧大小,并據此分配棧內存,然后壓入Java棧。

    局部變量區 局部變量區被組織為以一個字長為單位、從0開始計數的數組,類型為short、byte和char的值在存入數組前要被轉換成int值,而long和 double在數組中占據連續的兩項,在訪問局部變量中的long或double時,只需取出連續兩項的第一項的索引值即可,如某個long值在局部變量區中占據的索引時3、4項,取值時,指令只需取索引為3的long值即可。

    下面就看個例子,好讓大家對局部變量區有更深刻的認識。這個圖來自《深入JVM》:

    1. public static int runClassMethod(int i,long l,float f,double d,Object o,byte b) {     
    2.         return 0;     
    3.     }     
    4.          
    5.     public int runInstanceMethod(char c,double d,short s,boolean b) {     
    6.         return 0;     
    7.     }    

    上面代碼片的方法參數和局部變量在局部變量區中的存儲結構如下圖:

    局部變量區的存儲結構

    上面這個圖沒什么好說的,大家看看就會懂。但是,在這個圖里,有一點需要注意:

    runInstanceMethod的局部變量區第一項是個reference(引用),它指定的就是對象本身的引用,也就是我們常用的this,但是在runClassMethod方法中,沒這個引用,那是因為runClassMethod是個靜態方法。


    操作數棧和局部變量區一樣,操作數棧也被組織成一個以字長為單位的數組。但和前者不同的是,它不是通過索引來訪問的,而是通過入棧和出棧來訪問的。可把操作數棧理解為存儲計算時,臨時數據的存儲區域。下面我們通過一段簡短的程序片段外加一幅圖片來了解下操作數棧的作用。

    int a = 100;

    int b = 98;

    int c = a+b;

    操作數棧的結構

    從圖中可以得出:操作數棧其實就是個臨時數據存儲區域,它是通過入棧和出棧來進行操作的。

    幀數據區除了局部變量區和操作數棧外,Java棧幀還需要一些數據來支持常量池解析、正常方法返回以及異常派發機制。這些數據都保存在Java棧幀的幀數據區中。
    當JVM執行到需要常量池數據的指令時,它都會通過幀數據區中指向常量池的指針來訪問它。

    除了處理常量池解析外,幀里的數據還要處理Java方法的正常結束和異常終止。如果是通過return正常結束,則當前棧幀從Java棧中彈出,恢復玻璃鋼液下泵發起調用的方法的棧。如果方法又返回值,JVM會把返回值壓入到發起調用方法的操作數棧。

    為了處理Java方法中的異常情況,幀數據區還必須保存一個對此方法異常引用表的引用。當異常拋出時,JVM給catch塊中的代碼。如果沒發現,方法立即終止,然后JVM用幀區數據的信息恢復發起調用的方法的幀。然后再發起調用方法的上下文重新拋出同樣的異常。

    棧的整個結構

    在前面就描述過:棧是由棧幀組成,每當線程調用一個Java方法時,JVM就會在該線程對應的棧中壓入一個幀,而幀是由局部變量區、操作數棧和幀數據區組成。那在一個代碼塊中,棧到底是什么形式呢?下面是我從《深入JVM》中摘抄的一個例子,大家可以看看:

    代碼片段:

    棧的整個結構代碼示例

     

    執行過程中的三個快照:

     

    上面所給的圖,只想說明兩件事情,我們也可用此來理解Java中的棧:

    1、只有在調用一個方法時,才為當前棧分配一個幀,然后將該幀壓入棧。

    2、幀中存儲了對應方法的局部數據,方法執行完,對應的幀則從棧中彈出,并把返回結果存儲在調用方法的幀的操作數棧中。


    posted @ 2012-02-29 10:52 cangshi 閱讀(565) | 評論 (0)編輯 收藏

        加密利用:DES加密Java源碼的原因應用分析
      Java源代碼經過編譯以后在JVM中執行。由于JVM界面是完全透明的,Java類文件能夠很容易通過反編譯器重新轉換成源代碼。因此,所有的算法、類文件等都可以以源代碼的形式被公開,使得軟件不能受到保護,為了保護產權,一般可以有以下幾種方法:

      (1)"模糊"類文件,加大反編譯器反編譯源代碼文件的難度。然而,可以修改反編譯器,使之能夠處理這些模糊類文件。所以僅僅依賴"模糊類文件"來保證代碼的安全是不夠的。

      (2)流行的加密工具對源文件進行加密,比如PGP(Pretty Good Privacy)或GPG(GNU Privacy Guard)。這時,最終用戶在運行應用之前必須先進行解密。但解密之后,最終用戶就有了一份不加密的類文件,這和事先不進行加密沒有什么差別。

      (3)加密類文件,在運行中JVM用定制的類裝載器(Class Loader)解密類文件。Java運行時裝入字節碼的機制隱含地意味著可以對字節碼進行修改。JVM每次裝入類文件時都需要一個稱為ClassLoader的對象,這個對象負責把新的類裝入正在運行的JVM。JVM給ClassLoader一個包含了待裝入類(例如java.lang.Object)名字的字符串,然后由ClassLoader負責找到類文件,裝入原始數據,并把它轉換成一個Class對象。

      用戶下載的是加密過的類文件,在加密類文件裝入之時進行解密,因此可以看成是一種即時解密器。由于解密后的字節碼文件永遠不會保存到文件系統,所以竊密者很難得到解密后的代碼。

      由于把原始字節碼轉換成Class對象的過程完全由系統負責,所以創建定制ClassLoader對象其實并不困難,只需先獲得原始數據,接著就可以進行包含解密在內的任何轉換。

      Java密碼體系和Java密碼擴展

      Java密碼體系(JCA)和Java密碼擴展(JCE)的設計目的是為Java提供與實現無關的加密函數API。它們都用factory方法來創建類的例程,然后把實際的加密函數委托給提供者指定的底層引擎,引擎中為類提供了服務提供者接口在Java中實現數據的加密/解密,是使用其內置的JCE(Java加密擴展)來實現的。Java開發工具集1.1為實現包括數字簽名和信息摘要在內的加密功能,推出了一種基于供應商的新型靈活應用編程接口。Java密碼體系結構支持供應商的互操作,同時支持硬件和軟件實現。

      Java密碼學結構設計遵循兩個原則:

      (1)算法的獨立性和可靠性。

      (2)實現的獨立性和相互作用性。

      算法的獨立性是通過定義密碼服務類來獲得。用戶只需了解密碼算法的概念,而不用去關心如何實現這些概念。實現的獨立性和相互作用性通過密碼服務提供器來實現。密碼服務提供器是實現一個或多個密碼服務的一個或多個程序包。軟件開發商根據一定接口,將各種算法實現后,打包成一個提供器,用戶可以安裝不同的提供器。安裝和配置提供器,可將包含提供器的ZIP和JAR文件放在CLASSPATH下,再編輯Java安全屬性文件來設置定義一個提供器。Java運行環境Sun版本時, 提供一個缺省的提供器Sun。

      下面介紹DES算法及如何利用DES算法加密和解密類文件的步驟。

      DES算法簡介

      DES(Data Encryption Standard)是發明最早的最廣泛使用的分組對稱加密算法。DES算法的入口參數有三個:Key、Data、Mode。其中Key為8個字節共64位,是DES算法的工作密鑰;Data也為8個字節64位,是要被加密或被解密的數據;Mode為DES的工作方式,有兩種:加密或解密。

      DES算法工作流程如下:若Mode為加密模式,則利用Key 對數據Data進行加密, 生成Data的密碼形式(64位)作為DES的輸出結果;如Mode為解密模式,則利用Key對密碼形式的數據Data進行解密,還原為Data的明碼形式(64位)作為DES的輸出結果。在上海針型閥通信網絡的兩端,雙方約定一致的Key,在通信的源點用Key對核心數據進行DES加密,然后以密碼形式在公共通信網(如電話網)中傳輸到通信網絡的終點,數據到達目的地后,用同樣的Key對密碼數據進行解密,便再現了明碼形式的核心數據。這樣,便保證了核心數據在公共通信網中傳輸的安全性和可靠性。

      也可以通過定期在通信網絡的源端和目的端同時改用新的Key,便能更進一步提高數據的保密性。
      利用DES算法加密的步驟

      (1)生成一個安全密鑰。在加密或解密任何數據之前需要有一個密鑰。密鑰是隨同被加密的應用程序一起發布的一段數據,密鑰代碼如下所示。

      【生成一個密鑰代碼】

    view plaincopy to clipboardprint?
    // 生成一個可信任的隨機數源
    SecureRandom sr = new SecureRandom();
    // 為我們選擇的DES算法生成一個KeyGenerator對象
    KeyGenerator kg = KeyGenerator.getInstance ("DES" );
    Kg.init (sr);
    // 生成密鑰
    Secret Key key = kg.generateKey();
    // 將密鑰數據保存為文件供以后使用,其中key Filename為保存的文件名
    Util.writeFile (key Filename, key.getEncoded () );
    // 生成一個可信任的隨機數源
    SecureRandom sr = new SecureRandom();
    // 為我們選擇的DES算法生成一個KeyGenerator對象
    KeyGenerator kg = KeyGenerator.getInstance ("DES" );
    Kg.init (sr);
    // 生成密鑰
    Secret Key key = kg.generateKey();
    // 將密鑰數據保存為文件供以后使用,其中key Filename為保存的文件名
    Util.writeFile (key Filename, key.getEncoded () );

      (2)加密數據。得到密鑰之后,接下來就可以用它加密數據。如下所示。

      【用密鑰加密原始數據】

     

    view plaincopy to clipboardprint?
    // 產生一個可信任的隨機數源
    SecureRandom sr = new SecureRandom();
    //從密鑰文件key Filename中得到密鑰數據
    Byte rawKeyData = Util.readFile (key Filename);
    // 從原始密鑰數據創建DESKeySpec對象
    DESKeySpec dks = new DESKeySpec (rawKeyData);
    // 創建一個密鑰工廠,然后用它把DESKeySpec轉換成Secret Key對象
    SecretKeyFactory key Factory = SecretKeyFactory.getInstance("DES" );
    Secret Key key = keyFactory.generateSecret( dks );
    // Cipher對象實際完成加密操作
    Cipher cipher = Cipher.getInstance( "DES" );
    // 用密鑰初始化Cipher對象
    cipher.init( Cipher.ENCRYPT_MODE, key, sr );
    // 通過讀類文件獲取需要加密的數據
    Byte data = Util.readFile (filename);
    // 執行加密操作
    Byte encryptedClassData = cipher.doFinal(data );
    // 保存加密后的文件,覆蓋原有的類文件。
    Util.writeFile( filename, encryptedClassData );
    // 產生一個可信任的隨機數源
    SecureRandom sr = new SecureRandom();
    //從密鑰文件key Filename中得到密鑰數據
    Byte rawKeyData = Util.readFile (key Filename);
    // 從原始密鑰數據創建DESKeySpec對象
    DESKeySpec dks = new DESKeySpec (rawKeyData);
    // 創建一個密鑰工廠,然后用它把DESKeySpec轉換成Secret Key對象
    SecretKeyFactory key Factory = SecretKeyFactory.getInstance("DES" );
    Secret Key key = keyFactory.generateSecret( dks );
    // Cipher對象實際完成加密操作
    Cipher cipher = Cipher.getInstance( "DES" );
    // 用密鑰初始化Cipher對象
    cipher.init( Cipher.ENCRYPT_MODE, key, sr );
    // 通過讀類文件獲取需要加密的數據
    Byte data = Util.readFile (filename);
    // 執行加密操作
    Byte encryptedClassData = cipher.doFinal(data );
    // 保存加密后的文件,覆蓋原有的類文件。
    Util.writeFile( filename, encryptedClassData );

     

      (3)解密數據。運行經過加密的程序時,ClassLoader分析并解密類文件。操作步驟如下所示。

      【用密鑰解密數據】

    view plaincopy to clipboardprint?
    // 生成一個可信任的隨機數源
    SecureRandom sr = new SecureRandom();
    // 從密鑰文件中獲取原始密鑰數據
    Byte rawKeyData = Util.readFile( keyFilename );
    // 創建一個DESKeySpec對象
    DESKeySpec dks = new DESKeySpec (rawKeyData);
    // 創建一個密鑰工廠,然后用它把DESKeySpec對象轉換成Secret Key對象
    SecretKeyFactory key Factory = SecretKeyFactory.getInstance( "DES" );
    SecretKey key = keyFactory.generateSecret( dks );
    // Cipher對象實際完成解密操作
    Cipher cipher = Cipher.getInstance( "DES" );
    // 用密鑰初始化Cipher對象
    Cipher.init( Cipher.DECRYPT_MODE, key, sr );
    // 獲得經過加密的數據
    Byte encrypted Data = Util.readFile (Filename);
    //執行解密操作
    Byte decryptedData = cipher.doFinal( encryptedData );
    // 然后將解密后的數據轉化成原來的類文件。
    // 生成一個可信任的隨機數源
    SecureRandom sr = new SecureRandom();
    // 從密鑰文件中獲取原始密鑰數據
    Byte rawKeyData = Util.readFile( keyFilename );
    // 創建一個DESKeySpec對象
    DESKeySpec dks = new DESKeySpec (rawKeyData);
    // 創建一個密鑰工廠,然后用它把DESKeySpec對象轉換成Secret Key對象
    SecretKeyFactory key Factory = SecretKeyFactory.getInstance( "DES" );
    SecretKey key = keyFactory.generateSecret( dks );
    // Cipher對象實際完成解密操作
    Cipher cipher = Cipher.getInstance( "DES" );
    // 用密鑰初始化Cipher對象
    Cipher.init( Cipher.DECRYPT_MODE, key, sr );
    // 獲得經過加密的數據
    Byte encrypted Data = Util.readFile (Filename);
    //執行解密操作
    Byte decryptedData = cipher.doFinal( encryptedData );
    // 然后將解密后的數據轉化成原來的類文件。

      將上述代碼與自定義的類裝載器結合就可以做到邊解密邊運行,從而起到保護源代碼的作用。

      結束語

      加密/解密是數據傳輸中保證數據安全性和完整性的常用方法,Java語言因其平臺無關性,在Internet上的應用非常之廣泛。使用DES算法加密Java源碼在一定程度上能保護軟件的產權。

     

    posted @ 2012-02-09 13:34 cangshi 閱讀(507) | 評論 (0)編輯 收藏

    公司做web service的時候,看了一下資料,當時看見一個叫rmi的東西(遠程方法調用),最近閑著,所以看了一下 ,感覺挺簡單的!所以寫了一個例子提供給大家把!

    rmi的服務端,必須要使用接口,同時還有接口的實現類!所以下面的兩個文件是接口類和接口的實現類!

    UserDao 接口:

    1. /**  
    2.  * 遠程接口     必須繼承與Remote對象  
    3.  * @author spring sky  
    4.  * date: 2012年2月7日 10:55:05  
    5.  * Email:vipa1888@163.com  
    6.  * QQ:840950105  
    7.  */ 
    8. public interface UserDao extends Remote{  
    9.     /**  
    10.      * 簡單的測試方法  
    11.      * @param name  
    12.      */ 
    13.     public void sayName(String name) throws RemoteException;   
    14.  
    15.  

    UserDaoImpl實現類

    1. /**  
    2.  *   
    3.  *  接口的實現類    必須繼承UnicastRemoteObject(單一遠程對象)   實現UserDao自己的接口  
    4.  * @author spring sky  
    5.  * date: 2012年2月7日 10:56:05  
    6.  * Email:vipa1888@163.com  
    7.  * QQ:840950105  
    8.  */ 
    9. public class UserDaoImpl extends UnicastRemoteObject implements UserDao {  
    10.  
    11.     public UserDaoImpl() throws RemoteException {  
    12.     }  
    13.     @Override 
    14.     public void sayName(String name) {  
    15.         if(name!=null&&!name.equals(""))  
    16.         {  
    17.             System.out.println("我的名字是:"+name);  
    18.         }else{  
    19.             System.err.println("名字不為空....");  
    20.         }  
    21.     }  
    22.  

    對外的提供一個服務,服務中已經共享了url給外界訪問

    1. /**  
    2.  * 使用main方法啟動一個服務,用于外界環境訪問  
    3.  * @author spring sky  
    4.  * date:2012年2月7日 10:57:37  
    5.  * Email:vipa1888@163.com  
    6.  * QQ:840950105  
    7.  */ 
    8. public class StartService {  
    9.     private static final String IP = "127.0.0.1";  
    10.     private static final int PORT = 9999;  
    11.     private static final String REMOTE_NAME = "userDao";  
    12.     private static final String REMOTE_URL = "rmi://"+IP+":"+PORT+"/"+REMOTE_NAME;  
    13.     public static void main(String[] args) {  
    14.         try {  
    15.             UserDao userDao = new UserDaoImpl();    //實例化對象  
    16.             LocateRegistry.createRegistry(PORT);    //注冊端口  
    17.             Naming.bind(REMOTE_URL, userDao);       //綁定遠程服務對象  
    18.             System.out.println("遠程"+REMOTE_NAME+"啟動成功....");  
    19.         } catch (RemoteException e) {  
    20.             System.err.println("遠程對象出錯");  
    21.             e.printStackTrace();  
    22.         } catch (MalformedURLException e) {  
    23.             System.err.println("URL出錯了");  
    24.             e.printStackTrace();  
    25.         } catch (AlreadyBoundException e) {  
    26.             System.err.println("綁定的對象已經存在了");  
    27.             e.printStackTrace();  
    28.         }  
    29.     }  

    上面是服務端的代碼,如果啟動沒有任何問題,就可以做客戶端訪問了,其實上海旋塞閥客戶端的訪問更加的簡單,只需要遠程的接口類和查詢rmi中的url就可以了!

    代碼如下:

    1. /**  
    2.  * 遠程方法調用測試  
    3.  * @author spring sky  
    4.  * date:2012年2月7日 11:12:46  
    5.  * Email:vipa1888@163.com  
    6.  * QQ:840950105  
    7.  * name:石明政  
    8.  */ 
    9. public class TestRemote {  
    10.     public static void main(String[] args) {  
    11.         try {  
    12.             //在rmi服務中查詢userdao的對象  
    13.             UserDao userDao = (UserDao) Naming.lookup("rmi://127.0.0.1:9999/userDao");     
    14.             //調用遠程服務的方法  
    15.             userDao.sayName("spring sky");  
    16.         } catch (MalformedURLException e) {  
    17.             System.err.println("URL出錯");  
    18.             e.printStackTrace();  
    19.         } catch (RemoteException e) {  
    20.             System.err.println("遠程對象出錯");  
    21.             e.printStackTrace();  
    22.         } catch (NotBoundException e) {  
    23.             System.err.println("沒有找到綁定的對象");  
    24.             e.printStackTrace();  
    25.         }  
    26.     }  

    以上就是所有的rmi遠程調用代碼了!運行結果如下:

    好了,本人也只是簡單的了解了rmi,如果以后有項目做rmi就可以深入了! 呵呵  ,在這里我突然感覺,想web service也應該和他一樣的原理的把!


    posted @ 2012-02-09 10:53 cangshi 閱讀(273) | 評論 (0)編輯 收藏

    僅列出標題
    共3頁: 上一頁 1 2 3 下一頁 
    主站蜘蛛池模板: 亚洲色无码国产精品网站可下载| 永久免费视频网站在线观看| 亚洲一区二区三区免费在线观看 | 亚洲日韩激情无码一区| 四虎www成人影院免费观看| 99久久精品免费视频| 国产免费播放一区二区| 亚洲色成人WWW永久在线观看| 久久亚洲成a人片| 中文字幕在线亚洲精品 | 黄色一级视频免费| 亚洲色大情网站www| 亚洲综合激情视频| 亚洲成熟xxxxx电影| 亚洲线精品一区二区三区| 免费人妻av无码专区| 国产成人在线观看免费网站| 女人18毛片水真多免费播放| 国产福利在线免费| 亚洲成人在线免费观看| 中文字幕无码免费久久| 十八禁在线观看视频播放免费| 九九久久精品国产免费看小说| 久久亚洲精品11p| 中文字幕在线观看亚洲日韩| 亚洲av无码国产综合专区| 亚洲电影唐人社一区二区| 亚洲一区二区成人| 亚洲国产一区在线| 亚洲视频一区网站| 亚洲欧洲国产成人精品| 亚洲国色天香视频| 国产成人精品日本亚洲专| 亚洲中文字幕无码久久| 亚洲日韩精品国产3区| 亚洲人成色777777老人头| 亚洲av无码专区国产不乱码| 自拍偷自拍亚洲精品播放| 免费看黄网站在线看| 久久国产精品免费一区| 在线观看片免费人成视频播放|