国产98在线,日韩欧美二区,日韩综合一区http://www.aygfsteel.com/agun/激情成就夢想,努力創(chuàng)造未來zh-cnSat, 03 May 2025 19:46:21 GMTSat, 03 May 2025 19:46:21 GMT60java web 導(dǎo)出excel http://www.aygfsteel.com/agun/archive/2012/11/03/390722.htmlagunagunSat, 03 Nov 2012 04:45:00 GMThttp://www.aygfsteel.com/agun/archive/2012/11/03/390722.htmlhttp://www.aygfsteel.com/agun/comments/390722.htmlhttp://www.aygfsteel.com/agun/archive/2012/11/03/390722.html#Feedback1http://www.aygfsteel.com/agun/comments/commentRss/390722.htmlhttp://www.aygfsteel.com/agun/services/trackbacks/390722.html看到這個(gè)標(biāo)題,會(huì)很疑問,java導(dǎo)出excel 有很多文章呀,都知道怎么用呀,呵呵,我也是這么認(rèn)為,我們常用的就是jxl 或者poi ,現(xiàn)在jxl 代碼不在更新不支持2007,一般都采用poi 進(jìn)行excel的操作,今天在看系統(tǒng)(架構(gòu)struts+ spring+ hibernate),需要做一個(gè)excel導(dǎo)出,一個(gè)簡單的方法,這個(gè)方法只適用于excel簡單的導(dǎo)出,直接通過輸出的頁面,然后設(shè)置頁面為輸出流的文件格式,這樣當(dāng)action轉(zhuǎn)向到j(luò)sp頁面的時(shí)候,直接就是將頁面輸出。

 

jsp頁面的代碼:

Java代碼 復(fù)制代碼
  1. <%@ page language="java" pageEncoding="UTF8"%>   
  2. <html:html locale="true">   
  3.     <head>      
  4.         <title>LogExport</title>   
  5.         <meta http-equiv="pragma" content="no-cache">   
  6.         <meta http-equiv="cache-control" content="no-cache">   
  7.         <meta http-equiv="expires" content="0">   
  8.         <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">   
  9.         <%   
  10.           response.setCharacterEncoding("UTF-8");   
  11.           response.setContentType("application/vnd.ms-excel;");      
  12.           response.setHeader("Content-Disposition""attachment;filename=\""+new String("Log.xls".getBytes(),"ISO-8859-1")+"\"");   
  13.         %>     
  14.     </head>   
  15.     <body>   
  16.         <form action="/Action_export.do">   
  17.             <table width="100%" border="1" cellspacing="0" cellpadding="0" id="datagrid">   
  18.                 <thead>   
  19.                     <tr class="HeaderStyle" style="font-weight: normal;">   
  20.                         <th>用戶</th>   
  21.                         <th>姓名</th>   
  22.                         <th>日期</th>   
  23.                         <th>登錄IP</th>   
  24.                         <th>主機(jī)名</th>   
  25.                         <th colspan="3">   
  26.                          <table width='100%'  border="1" cellspacing="3" cellpadding="0" frame='void' >    
  27.                                 <tr><td colspan="3" style='background:transparent;' align="center">操作信息</td></tr>   
  28.                                 <tr style='background:transparent;'>   
  29.                                     <td width="40px" align="center">操作</td>   
  30.                                     <td width="100px" align="center">標(biāo)題</td>   
  31.                                     <td align="center">擴(kuò)展信息</td>   
  32.                                 </tr>   
  33.                             </table>   
  34.                         </th>   
  35.                     </tr>   
  36.                 </thead>   
  37.                 <jsp:include page="common.jsp" flush="true" />   
  38.             </table>   
  39.         </form>   
  40.     </body>   
  41. </html:html>  


agun 2012-11-03 12:45 發(fā)表評論
]]>
vb控件開發(fā)隨筆http://www.aygfsteel.com/agun/archive/2012/02/29/370953.htmlagunagunWed, 29 Feb 2012 01:03:00 GMThttp://www.aygfsteel.com/agun/archive/2012/02/29/370953.htmlhttp://www.aygfsteel.com/agun/comments/370953.htmlhttp://www.aygfsteel.com/agun/archive/2012/02/29/370953.html#Feedback0http://www.aygfsteel.com/agun/comments/commentRss/370953.htmlhttp://www.aygfsteel.com/agun/services/trackbacks/370953.html項(xiàng)目需要使用一些本地控件,所以這幾天又折騰把以前的vb拿出來,做一個(gè)空間的例子。vb制作控件很簡單,這里也不再多說,我開發(fā)的控件名稱叫做test.ocx發(fā)布好,會(huì)生成相應(yīng)的test.cab和test.hmtl測試頁面。

 

我要把這個(gè)控件發(fā)布的web工程中

 

1,首先復(fù)制cab到web目錄下,然后再頁面中添加控件信息,如下圖,

Html代碼 復(fù)制代碼
  1. <!-- 如果這頁上的任何控件需要授權(quán),您必須   
  2.     創(chuàng)建一個(gè)授權(quán)包文件。 運(yùn)行 LPK_TOOL.EXE 來創(chuàng)建   
  3.     要求的 LPK 文件。 LPK_TOOL.EXE 將從 ActiveX SDK 中找到,   
  4.     http://www.microsoft.com/intdev/sdk/sdk.htm. 如果您有 Visual   
  5.     Basic 6.0 CD, 您可以在\Tools\LPK_TOOL 目錄下找到它。   
  6.   
  7.     下面是對象標(biāo)記的例子:   
  8.   
  9. <OBJECT CLASSID="clsid:5220cb21-c88d-11cf-b347-00aa00a28331">  
  10.     <PARAM NAME="LPKPath" VALUE="LPKfilename.LPK">  
  11. </OBJECT>  
  12. -->  
  13.   
  14. <OBJECT ID="test"  
  15. CLASSID="CLSID:7E0ED402-E1D4-4E40-95C2-FEA17B4FA60E"  
  16. CODEBASE="test.CAB#version=1,0,0,1">  
  17. </OBJECT>  

 其中上面注釋掉的lpk這段根據(jù)他的描述生成了相應(yīng)的lpk文件,將代碼放到j(luò)sp頁面中,部署。

 

2,部署后查看測試效果,但是效果不盡如人意,提示“非安全控件”而且也無法安裝,這是由于控件沒有認(rèn)證,認(rèn)證還是需要花錢的,自然不行。

 

3,只能通過本地注冊控件的方式,這樣就不需要ie的認(rèn)證,但是控件提示的信息也是“無法識別的控件”。

4,使用installshield9來制作客戶端注冊包,具體的不說了只要注意一個(gè)個(gè)問題。注冊控件的腳步

 

C代碼 復(fù)制代碼
  1. function OnEnd()     
  2.     string szDLL, szReg, szCmd;    
  3. begin      
  4.     szReg = WINSYSDIR ^ "regsvr32.exe";   
  5.     szDLL = TARGETDIR ^ "test.ocx"//如果是MSI工程,可以用INSTALLDIR代替TARGETDIR   
  6.     szCmd = "/s \"" + szDLL + "\""//增加靜默參數(shù)s, 增加 \” 防止目錄路徑含空格的情況。     
  7.        
  8.     if (!REMOVEONLY) then    
  9.         LaunchAppAndWait(szReg, szCmd, WAIT);        
  10.     endif;       
  11. end;  

 

這樣注冊后,客戶端使用就不會(huì)有提示,我上面提到了,我自己生成了lpk文件,我也加到頁面中了。

Html代碼 復(fù)制代碼
  1. <OBJECT CLASSID="clsid:5220cb21-c88d-11cf-b347-00aa00a28331">  
  2.     <PARAM NAME="LPKPath" VALUE="LPKfilename.LPK">  
  3. </OBJECT>  

 

但是如果加這句雖然控件可以使用,但是總會(huì)有安全提示,很影響使用效果。所以暫時(shí)把它去掉了。



agun 2012-02-29 09:03 發(fā)表評論
]]>
list合并單元格http://www.aygfsteel.com/agun/archive/2011/10/17/361437.htmlagunagunMon, 17 Oct 2011 06:44:00 GMThttp://www.aygfsteel.com/agun/archive/2011/10/17/361437.htmlhttp://www.aygfsteel.com/agun/comments/361437.htmlhttp://www.aygfsteel.com/agun/archive/2011/10/17/361437.html#Feedback0http://www.aygfsteel.com/agun/comments/commentRss/361437.htmlhttp://www.aygfsteel.com/agun/services/trackbacks/361437.html

1,在今天整理代碼的時(shí)候,發(fā)現(xiàn)原來的一段代碼,前臺合并單元格。

 

需要在后端,原來的列表基礎(chǔ)上,再增加一層。

Java代碼 復(fù)制代碼
  1. List<CASEListVO> list2 = super.doFind(hql.toString(), params.toArray(), currPage, pageSize);   
  2.    ArrayList<List<CASEListVO>> linkedList = new ArrayList<List<CASEListVO>>();   
  3. List<String> keyList = new ArrayList<String>();   
  4. for (CASEListVO vo : list2)   
  5. {   
  6.    String key = vo.getItemCode();   
  7.    List<CASEListVO> tempList = new ArrayList<CASEListVO>();   
  8.    if (keyList.indexOf(key) == -1)   
  9.    {   
  10.       keyList.add(key);   
  11.    }   
  12.    else  
  13.    {   
  14.       continue;   
  15.    }   
  16.    for (CASEListVO vo1 : list2)   
  17.    {   
  18.       if (vo1.getItemCode().endsWith(key))   
  19.       {   
  20.          tempList.add(vo1);   
  21.       }   
  22.    }   
  23.    linkedList.add(tempList);   
  24. }   
  25. page.setList(linkedList);//返回的列表  

 頁面上操作,struts2

Html代碼 復(fù)制代碼
  1. <s:iterator value="page" id="list">  
  2.                 <c:forEach var="recordList" items="${list}" varStatus="varStatus">  
  3.                     <c:forEach var="record" items="${recordList}" varStatus="status">  
  4.                         <tr>  
  5.                             <td>  
  6.                                 <input name="selectIds" type="checkbox" value="${record.ltVo.listTmpId}"  
  7.                                     oldValue="${record.estTmpId }" />  
  8.                             </td>  
  9.                             ${status.index }--   
  10.                             <%=((List) pageContext.getAttribute("recordList")).size()%>  
  11.                             <c:if test="${status.index eq 0}">  
  12.                                 <td rowspan="<%=((List) pageContext.getAttribute("recordList")).size()%>" style="width: 240px;text-align: center;">  
  13.                                     ${record.listName}   
  14.                                 </td>  
  15.                             </c:if>  
  16.                             <td style="text-align: center;width:200px;">  
  17.                                 ${record.itemCode}   
  18.                             </td>  
  19.                             <td style="text-align: center;width: 200px;">  
  20.                                 ${record.projectName}   
  21.                             </td>  
  22.                             <td style="text-align: right;width: 200px">  
  23.                                 <fmt:formatNumber value="${record.rate}" pattern="##0.00" />  
  24.                             </td>  
  25.                         </tr>  
  26.                     </c:forEach>  
  27.                 </c:forEach>  
  28.             </s:iterator>  

 

這樣根據(jù)code在頁面上就會(huì)顯示分組合并單元格的效果。



agun 2011-10-17 14:44 發(fā)表評論
]]>
hibernate 一對多集合 set查詢問題http://www.aygfsteel.com/agun/archive/2011/08/19/356882.htmlagunagunFri, 19 Aug 2011 09:21:00 GMThttp://www.aygfsteel.com/agun/archive/2011/08/19/356882.htmlhttp://www.aygfsteel.com/agun/comments/356882.htmlhttp://www.aygfsteel.com/agun/archive/2011/08/19/356882.html#Feedback0http://www.aygfsteel.com/agun/comments/commentRss/356882.htmlhttp://www.aygfsteel.com/agun/services/trackbacks/356882.html

今天解決了一個(gè)問題(如題),這個(gè)問題一致沒有解決,以前的項(xiàng)目中也遇到過但是都沒有花時(shí)間去研究,這回徹底的整理了一下。問題如:一個(gè)老師類(Teacher)和一個(gè)學(xué)生類(User),一個(gè)老師有多個(gè)學(xué)生,當(dāng)然這個(gè)例子不夠好,不管怎樣就是這個(gè)意思,老是對應(yīng)多個(gè)學(xué)生,oneto many

 

        <set name="users" inverse="true" order-by="column" ><!-- sort="natural"   -->
            <key>
                <column name="teacher_id" length="36">
                    <comment>老師表主鍵</comment>
                </column>
            </key>
            <one-to-many class="User" />
        </set>

 

以前遇到這個(gè)問題,都是通過lazy=false來實(shí)現(xiàn),雖然能實(shí)現(xiàn)效果但是效率上會(huì)有問題也會(huì)產(chǎn)生N+1的查詢問題。

我一致比較喜歡使用 hibernate的 left join fetch 方式來抓取結(jié)構(gòu),但是我現(xiàn)在是要在查詢老師的列表中顯示他所有的學(xué)生,如果用 select teacher from Teacher teacher left join fetch teacher.users這樣的方式來得到學(xué)生集合,這樣老師的數(shù)據(jù)集合會(huì)有重復(fù)數(shù)據(jù),不知我這樣說是否理解,如果遇到我這樣的問題應(yīng)該比較了解了,使用了很多方法也沒有通過,當(dāng)然實(shí)現(xiàn)這個(gè)效果可以有別的方式(虛列方式,或這采用 native sql ),我現(xiàn)在就是針對這種抓取的方式(暫時(shí)還是沒有找到方案,如果知道的可以告訴我),我現(xiàn)在采用的方式還是上面的抓取方式,出現(xiàn)的重復(fù)數(shù)據(jù),我把結(jié)果集拿出來之后,把重復(fù)的數(shù)據(jù)過濾掉,這樣暫時(shí)能解決問題。然后是后面的出去的users 排序的問題,默認(rèn)我們使用的set set大家都知道是沒有順序的,我們一種方式是 order-by="column" 上面的,采用這種方式來實(shí)現(xiàn)排序,另一種方式是采用 sort="natural" 方式來實(shí)現(xiàn),但是如果要用sort方式就需要實(shí)現(xiàn)compareble 接口 實(shí)現(xiàn) compareTo 方法 來自定義比較的規(guī)則,第二種方式我試驗(yàn)一下有點(diǎn)問題,他們的原理都是通過這兩個(gè)規(guī)則 指定set最后的實(shí)現(xiàn)類 。



agun 2011-08-19 17:21 發(fā)表評論
]]>
hibernate lazyhttp://www.aygfsteel.com/agun/archive/2011/08/12/356365.htmlagunagunFri, 12 Aug 2011 05:17:00 GMThttp://www.aygfsteel.com/agun/archive/2011/08/12/356365.htmlhttp://www.aygfsteel.com/agun/comments/356365.htmlhttp://www.aygfsteel.com/agun/archive/2011/08/12/356365.html#Feedback0http://www.aygfsteel.com/agun/comments/commentRss/356365.htmlhttp://www.aygfsteel.com/agun/services/trackbacks/356365.html今天項(xiàng)目組有要使用的hibernate lazy的,我一直對這種lazy的方式是不贊成使用的,所以我的項(xiàng)目組內(nèi)是明確不能使lazy,包括true和false當(dāng)然hibernate 默認(rèn)的模式是true ,但是在程序中我們是可以控制,當(dāng)然如果不做配置話,也無法在前端使用,其實(shí)在項(xiàng)目中,用到lazy的時(shí)候并不是特別多(個(gè)人觀點(diǎn)),大部分的數(shù)據(jù)都是明確的要在后臺查詢出來的。用lazy也并不復(fù)雜,在web.xml中配置

Xml代碼 復(fù)制代碼
  1. <filter>  
  2.     <filter-name>hibernateFilter</filter-name>  
  3.     <filter-class>  
  4.         org.springframework.orm.hibernate3.support.OpenSessionInViewFilter   
  5.     </filter-class>  
  6.     <init-param>  
  7.         <param-name>singleSession</param-name>  
  8.         <param-value>false</param-value>  
  9.     </init-param>  
  10. </filter>  
  11.   
  12. <filter-mapping>  
  13.     <filter-name>hibernateFilter</filter-name>  
  14.     <url-pattern>*.do</url-pattern>  
  15. </filter-mapping>  

 

就可以使用延遲加載了,spring通過filter的方式對綁定hibernate session 到request的線程中。

that binds a Hibernate Session to the thread for the entire processing of the request

 

剛開始我是把上面這段配置隨便放到web.xml中,一致不成功總報(bào)session 關(guān)閉,不起作用,最后查了一下,我把這個(gè)filter放到了struts的filter之上,就可以了。

 

 

說明FlushMode有五種屬性

1 NEVEL  

已經(jīng)廢棄了,被MANUAL取代了


2 MANUAL

spring3.x中的opensessioninviewfilter已經(jīng)將默認(rèn)的FlushMode設(shè)置為MANUAL了;
如果FlushMode是MANUAL或NEVEL,在操作過程中hibernate會(huì)將事務(wù)設(shè)置為readonly,所以在
增加、刪除或修改操作過程中會(huì)出現(xiàn)如下錯(cuò)誤
org.springframework.dao.InvalidDataAccessApiUsageException: Write operations are not allowed in read
-only mode (FlushMode.NEVER) - turn your Session into FlushMode.AUTO or remove 'readOnly' marker from transaction definition;
解決辦法網(wǎng)上有很多;
1 配置事務(wù),spring會(huì)讀取事務(wù)中的各種配置來覆蓋hibernate的session中的FlushMode;
2 先編程式修改FlushMode,比如session.setFlushMode(FlushMode.AUTO); 這樣hibernate就會(huì)自動(dòng)去除readonly限制;
3 直接修改opensessioninviewfilter過濾器的配置,配置過濾器的時(shí)候配置
<filter>
      
<filter-name>openSession</filter-name>
      
<filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
      
<init-param>
          
<param-name>flushMode</param-name>
          
<param-value>AUTO</param-value>
      
</init-param>
  
</filter>

3 AUTO

設(shè)置成auto之后,當(dāng)程序進(jìn)行查詢、提交事務(wù)或者調(diào)用session.flush()的時(shí)候,都會(huì)使緩存和數(shù)據(jù)庫進(jìn)行同步,也就是刷新數(shù)據(jù)庫

4 COMMIT

提交事務(wù)或者session.flush()時(shí),刷新數(shù)據(jù)庫;查詢不刷新


5 ALWAYS

每次進(jìn)行查詢、提交事務(wù)、session.flush()的時(shí)候都會(huì)刷數(shù)據(jù)庫
這里需要說一下和AUTO的區(qū)別,當(dāng)hibernate緩存中的對象被改動(dòng)之后,會(huì)被標(biāo)記為臟數(shù)據(jù)(即與數(shù)據(jù)庫不同步了)。當(dāng)session設(shè)置為FlushMode.AUTO時(shí),hibernate在進(jìn)行查詢的時(shí)候會(huì)判斷緩存中的數(shù)據(jù)是否為臟數(shù)據(jù),是則刷數(shù)據(jù)庫,不是則不刷,而always是直接刷新,不進(jìn)行任何判斷。很顯然auto比always要高效得多。

 



agun 2011-08-12 13:17 發(fā)表評論
]]>
struts2 泛型 Hibernatehttp://www.aygfsteel.com/agun/archive/2011/05/08/349767.htmlagunagunSun, 08 May 2011 01:20:00 GMThttp://www.aygfsteel.com/agun/archive/2011/05/08/349767.htmlhttp://www.aygfsteel.com/agun/comments/349767.htmlhttp://www.aygfsteel.com/agun/archive/2011/05/08/349767.html#Feedback0http://www.aygfsteel.com/agun/comments/commentRss/349767.htmlhttp://www.aygfsteel.com/agun/services/trackbacks/349767.html今天在整理代碼的時(shí)候,我的Action 和 DAO基類都是使用的泛型:如Action<T> DAO<T>。

 

我用的是Struts2基類代碼,如下

Java代碼 復(fù)制代碼 收藏代碼
  1. public abstract class BaseStrutsAction extends ActionSupport implements ModelDriven<BaseStrutsForm>   
  2. {   
  3.    public static final Logger log = Logger.getLogger(BaseStrutsAction.class);   
  4.   
  5. }  

 先說一下:

一,struts2的ModelDriven (下面來源網(wǎng)絡(luò))

 

可以根據(jù)Action屬性的不同將它分為兩類:Field-Driven(屬性驅(qū)動(dòng)) Action和Model-Driven(模型驅(qū)動(dòng)) Action。
一、Field-Driven(屬性驅(qū)動(dòng))Action,Action擁有自己的屬性,這些屬性一般是Java的基本類型。表單字段直接和Action的屬性 對應(yīng)。

二、實(shí)現(xiàn)了modelDriven接口可以在action中直接獲得例如User對象,它會(huì)將Object getModel()取得的User放到ValueStack中??梢岳斫鉃閷⑦@個(gè)User的屬性追加到Action中。它主要是作用是實(shí)現(xiàn)類似 Struts的FormBean功能。

在struts2中,提供了一種直接使用領(lǐng)域?qū)ο蟮姆绞?,就是讓action實(shí)現(xiàn)com.opensymphony.xwork2.ModelDriven接口,ModelDriven讓你可以直接操作應(yīng)用程序中的領(lǐng)域?qū)ο螅试S你在web層和業(yè)務(wù)層使用相同的對象。

ModelDriven接口只有一個(gè)方法

        public Object getModel() {
return null;
}

該方法返回一個(gè)用于接收用戶輸入數(shù)據(jù)的對象模型,在這個(gè)模型對象中的屬性可以直接通過(屬性名)userName來訪問,而不需要使用(對象名.屬 性名)user.userName這種格式來訪問了,在action也不需要對對象提供getter和setter方法了,但是必須要在action中進(jìn) 行new操作

如下

// ModelDriven要使用泛型哦

public class LoginAction extends ActionSupport implements ModelDriven<User>{

private static final long serialVersionUID = -6434128483294080524L;

//這里必須要new
private User user=new User();
public String login() throws Exception {
// TODO Auto-generated method stub  
return SUCCESS;
}

//這里是實(shí)現(xiàn)接口方法

@Override
public User getModel() {
// TODO Auto-generated method stub

//別忘記了,要把返回值寫上哦
return user;
}
}

這樣一個(gè)ModelDriven就實(shí)現(xiàn)完畢了

和屬性驅(qū)動(dòng)的Action有很大的區(qū)別,下面一一列舉:

(1)模型驅(qū)動(dòng)的Action必須實(shí)現(xiàn)ModelDriven接口,而且要提供相應(yīng)的泛型,這里當(dāng)然就是具體使用的Java Bean了。

(2)實(shí)現(xiàn)ModelDriven的getModel方法,其實(shí)就是簡單的返回泛型的一個(gè)對象。

(3)在Action提供一個(gè)泛型的私有對象,這里就是定義一個(gè)User的user對象,并提供相應(yīng)的getter與setter。

好了,上面的三件事做完之后,Action就會(huì)去自動(dòng)調(diào)用User的setter將表單中的name屬性的值賦給User中的屬性。而Action的后續(xù)處理的Jsp頁面后者是Servlet就可以使用user對象了。

到底是用屬性驅(qū)動(dòng)和是模型驅(qū)動(dòng)呢?

這個(gè)問題困擾了很多Struts2的初學(xué)者,我這里提供一些建議:

(1)請你統(tǒng)一整個(gè)系統(tǒng)中的Action使用的驅(qū)動(dòng)模型,即要么都是用屬性驅(qū)動(dòng),要么都是用模型驅(qū)動(dòng)。

(2)如果你的DB中的持久層的對象與表單中的屬性都是一一對應(yīng)的話,那么就使用模型驅(qū)動(dòng)吧,畢竟看起來代碼要整潔得多。

(3)如果表單的屬性不是一一對應(yīng)的話,那么就應(yīng)該使用屬性驅(qū)動(dòng),否則,你的系統(tǒng)就必須提供兩個(gè)Bean,一個(gè)對應(yīng)表單提交的數(shù)據(jù),另一個(gè)用與持久層。

二,持久層基類 HibernateDao

 

代碼如:

Java代碼 復(fù)制代碼 收藏代碼
  1. public class HibernateDao<T, PK extends Serializable>  {   
  2.     /**  
  3.      * 用于Dao層子類的構(gòu)造函數(shù).  
  4.      * 通過子類的泛型定義取得對象類型Class.  
  5.      * eg.  
  6.      * public class UserDao extends HibernateDao<User, Long>{  
  7.      * }  
  8.      */  
  9.     public HibernateDao() {   
  10.         super();   
  11.     }  

 

上面的代碼,基類沒有使用HibernateDaoSupport,我們需要自己引入SessionFactory。

持久層基類,一般Spring的Hibernate ORM 框架帶來了方便的HibernateDaoSupport類,你的DAO類可以繼承它:

  public class DaoHibernate extends HibernateDaoSupport {

  .................

  }

  如果你選擇這種設(shè)計(jì),就需要?jiǎng)討B(tài)注入SessionFactory而HibernateDaoSupport包含這個(gè)屬性.這個(gè)類提供了一個(gè)方便的方法getHibernateTemplate(); 就能得到HibernateTemplate的一個(gè)實(shí)例.它也有g(shù)etSession()和releaseSession,以便于你應(yīng)為某些原因而不使用HibernateTempate的情況下執(zhí)行Hibernate操作。

  HibernateDaoSupport提供了基于AOP事務(wù)的自動(dòng)處理,程序員完全可以不用理會(huì)事務(wù)的開始與提交。在JDBC中一個(gè)Connection對象使用一個(gè)事務(wù),那么在Hibernate中一個(gè)事務(wù)肯定要關(guān)聯(lián)一個(gè)SessionFactory了,然而這個(gè)SessionFactory卻沒有在DAO中體現(xiàn)。其實(shí)主要的原因是HibernateDaoSupport類已經(jīng)默默地做了封裝的工作,它用一個(gè)setSessionFactory方法將SessionFactory進(jìn)行注入,所以繼承自HibernateDaoSupport類的DAO都會(huì)具有SessionFactory的屬性,從而可以通過SessionFactory創(chuàng)建Session實(shí)例操作數(shù)據(jù)庫。

 

如果使用像 public class HibernateDao<T, PK extends Serializable>  這樣的泛型基類就會(huì)有問題,可以拿個(gè)T代表任意類型,Java的泛型拿不到T.class,就無法得到類對象, 如下面的clazz,

public T get(final PK id) {
  Assert.notNull(id, "id不能為空");
  return (T) getSession().load(clazz, id);
 }

最后在網(wǎng)上找到了解決方案,可以使用泛型public class HibernateDao<T, PK extends Serializable>基類了。

Java代碼 復(fù)制代碼 收藏代碼
  1. abstract public class BaseHibernateEntityDao<T> extends HibernateDaoSupport {   
  2.  private Class<T> entityClass;   
  3.  public BaseHibernateEntityDao() {   
  4.         <SPAN style="COLOR: #000000">entityClass =(Class<T>) ((ParameterizedType) getClass()   
  5.                                 .getGenericSuperclass()).getActualTypeArguments()[0];</SPAN>   
  6.     }   
  7.  public T get(Serializable id) {   
  8.         T o = (T) getHibernateTemplate().get(entityClass, id);   
  9. }   
  10. }  

重點(diǎn)這句: entityClass =(Class<T>) ((ParameterizedType) getClass()
                                .getGenericSuperclass()).getActualTypeArguments()[0];



agun 2011-05-08 09:20 發(fā)表評論
]]>
數(shù)字簽名流程http://www.aygfsteel.com/agun/archive/2011/04/24/348921.htmlagunagunSun, 24 Apr 2011 08:27:00 GMThttp://www.aygfsteel.com/agun/archive/2011/04/24/348921.htmlhttp://www.aygfsteel.com/agun/comments/348921.htmlhttp://www.aygfsteel.com/agun/archive/2011/04/24/348921.html#Feedback0http://www.aygfsteel.com/agun/comments/commentRss/348921.htmlhttp://www.aygfsteel.com/agun/services/trackbacks/348921.html

數(shù)字簽名流程個(gè)圖

 

上面的圖描述了用戶A和用戶B間通訊流程。

1,用戶A將明文通過hash運(yùn)算(散列)生成數(shù)字摘要1,用戶A用自己的私鑰對摘要進(jìn)行加密生成數(shù)字簽名1.

2,用戶A將明文+數(shù)字簽名1+A用戶的公鑰(證書),準(zhǔn)備將這些信息發(fā)到B用戶,但是這個(gè)過程中,用戶A明文是不安全的是可見的,我們需要對這三個(gè)文件進(jìn)行加密。

3,用戶A通過一個(gè)“對稱加密”(對稱加密速度很快,知道密鑰就可以解密)對其進(jìn)行加密將其生成秘文1,要想這次加密成功關(guān)鍵就是要保護(hù)這個(gè)對稱加密的密鑰1

4,為了保證上面的加密安全,使用用戶B的公鑰對“對稱加密的密鑰1”進(jìn)行了一次加密處理,生成一個(gè)數(shù)字信封1,此時(shí)這個(gè)數(shù)字信封1+秘文1打包裝入就可以發(fā)送給用B了。

5,用戶B接收到信,看到數(shù)字信封1+秘文1,用戶B用私鑰解密數(shù)字信封1,得到了“對稱加密的密鑰1”,通過這個(gè)對稱加密密鑰對秘文1解密,就可以解開密文。

6,解開秘文1解則看到了A將明文+數(shù)字簽名1+A用戶的公鑰(證書),這三個(gè)文件,這個(gè)時(shí)候已經(jīng)可以確認(rèn)是用戶A發(fā)的信息了,但是還要驗(yàn)證文件在傳輸過程中是否被篡改。

7,用戶B將明文通過hash運(yùn)算(散列)生成數(shù)字摘要2,同時(shí)用得到的A用戶的公鑰(證書)對數(shù)字簽名1進(jìn)行解密生成原來的數(shù)字摘要1,如果此時(shí)的數(shù)字摘要1數(shù)字摘要2相同那么說明整個(gè)過程是安全而有效的。

 



agun 2011-04-24 16:27 發(fā)表評論
]]>
數(shù)字簽名http://www.aygfsteel.com/agun/archive/2011/04/24/348918.htmlagunagunSun, 24 Apr 2011 06:40:00 GMThttp://www.aygfsteel.com/agun/archive/2011/04/24/348918.htmlhttp://www.aygfsteel.com/agun/comments/348918.htmlhttp://www.aygfsteel.com/agun/archive/2011/04/24/348918.html#Feedback1http://www.aygfsteel.com/agun/comments/commentRss/348918.htmlhttp://www.aygfsteel.com/agun/services/trackbacks/348918.html

好的文章 http://www.ibm.com/developerworks/cn/java/l-security/

 

數(shù)字簽名以電子形式存在于數(shù)據(jù)信息之中的,或作為其附件的或邏輯上與之有聯(lián)系的數(shù)據(jù),可用于辨別數(shù)據(jù)簽署人的身份,并表明簽署人對數(shù)據(jù)信息中包含的信息的認(rèn)可。(摘自百度)

 

數(shù)字簽名(又稱公鑰數(shù)字簽名、電子簽章)是一種類似寫在紙上的普通的物理簽名,但是使用了公鑰加密領(lǐng)域的技術(shù)實(shí)現(xiàn),用于鑒別數(shù)字信息的方法。一套數(shù)字簽名通常定義兩種互補(bǔ)的運(yùn)算,一個(gè)用于簽名,另一個(gè)用于驗(yàn)證

 

基本介紹  數(shù)字簽名不是指將你的簽名掃描成數(shù)字圖像,或者用觸摸板獲取的簽名,更不是你的落款。

  數(shù)字簽名了的文件的完整性是很容易驗(yàn)證的(不需要騎縫章,騎縫簽名,也不需要筆跡專家),而且數(shù)字簽名具有不可抵賴性(不需要筆跡專家來驗(yàn)證)。

  簡單地說,所謂數(shù)字簽名就是附加在數(shù)據(jù)單元上的一些數(shù)據(jù),或是對數(shù)據(jù)單元所作的密碼變換。這種數(shù)據(jù)或變換允許數(shù)據(jù)單元的接收者用以確認(rèn)數(shù)據(jù)單元的來源和數(shù)據(jù)單元的完整性并保護(hù)數(shù)據(jù),防止被人(例如接收者)進(jìn)行偽造。它是對電子形式的消息進(jìn)行簽名的一種方法,一個(gè)簽名消息能在一個(gè)通信網(wǎng)絡(luò)中傳輸。基于公鑰密碼體制和私鑰密碼體制都可以獲得數(shù)字簽名,目前主要是基于公鑰密碼體制的數(shù)字簽名。包括普通數(shù)字簽名和特殊數(shù)字簽名。普通數(shù)字簽名算法有RSA、ElGamal、Fiat-Shamir、Guillou- Quisquarter、Schnorr、Ong-Schnorr-Shamir數(shù)字簽名算法、Des/DSA,橢圓曲線數(shù)字簽名算法和有限自動(dòng)機(jī)數(shù)字簽名算法等。特殊數(shù)字簽名有盲簽名、代理簽名、群簽名、不可否認(rèn)簽名、公平盲簽名、門限簽名、具有消息恢復(fù)功能的簽名等,它與具體應(yīng)用環(huán)境密切相關(guān)。顯然,數(shù)字簽名的應(yīng)用涉及到法律問題,美國聯(lián)邦政府基于有限域上的離散對數(shù)問題制定了自己的數(shù)字簽名標(biāo)準(zhǔn)(DSS)。

  數(shù)字簽名(Digital Signature)技術(shù)是不對稱加密算法的典型應(yīng)用。數(shù)字簽名的應(yīng)用過程是,數(shù)據(jù)源發(fā)送方使用自己的私鑰對數(shù)據(jù)校驗(yàn)和或其他與數(shù)據(jù)內(nèi)容有關(guān)的變量進(jìn)行加密處理,完成對數(shù)據(jù)的合法“簽名”,數(shù)據(jù)接收方則利用對方的公鑰來解讀收到的“數(shù)字簽名”,并將解讀結(jié)果用于對數(shù)據(jù)完整性的檢驗(yàn),以確認(rèn)簽名的合法性。數(shù)字簽名技術(shù)是在網(wǎng)絡(luò)系統(tǒng)虛擬環(huán)境中確認(rèn)身份的重要技術(shù),完全可以代替現(xiàn)實(shí)過程中的“親筆簽字”,在技術(shù)和法律上有保證。在數(shù)字簽名應(yīng)用中,發(fā)送者的公鑰可以很方便地得到,但他的私鑰則需要嚴(yán)格保密。

主要功能

  保證信息傳輸?shù)耐暾浴l(fā)送者的身份認(rèn)證、防止交易中的抵賴發(fā)生。

  數(shù)字簽名技術(shù)是將摘要信息用發(fā)送者的私鑰加密,與原文一起傳送給接收者。接收者只有用發(fā)送的公鑰才能解密被加密的摘要信息,然后用HASH函數(shù)對收到的原文產(chǎn)生一個(gè)摘要信息,與解密的摘要信息對比。如果相同,則說明收到的信息是完整的,在傳輸過程中沒有被修改,否則說明信息被修改過,因此數(shù)字簽名能夠驗(yàn)證信息的完整性。

  數(shù)字簽名是個(gè)加密的過程,數(shù)字簽名驗(yàn)證是個(gè)解密的過程。

簽名過程

  報(bào)文的發(fā)送方用一個(gè)哈希函數(shù)從報(bào)文文本中生成報(bào)文摘要(散列值)。發(fā)送方用自己的私人密鑰對這個(gè)散列值進(jìn)行加密。然后,這個(gè)加密后的散列值將作為報(bào)文的附件和報(bào)文一起發(fā)送給報(bào)文的接收方。報(bào)文的接收方首先用與發(fā)送方一樣的哈希函數(shù)從接收到的原始報(bào)文中計(jì)算出報(bào)文摘要,接著再用發(fā)送方的公用密鑰來對報(bào)文附加的數(shù)字簽名進(jìn)行解密。如果兩個(gè)散列值相同、那么接收方就能確認(rèn)該數(shù)字簽名是發(fā)送方的。通過數(shù)字簽名能夠?qū)崿F(xiàn)對原始報(bào)文的鑒別。

  數(shù)字簽名有兩種功效:一是能確定消息確實(shí)是由發(fā)送方簽名并發(fā)出來的,因?yàn)閯e人假冒不了發(fā)送方的簽名。二是數(shù)字簽名能確定消息的完整性。因?yàn)閿?shù)字簽名的特點(diǎn)是它代表了文件的特征,文件如果發(fā)生改變,數(shù)字簽名的值也將發(fā)生變化。不同的文件將得到不同的數(shù)字簽名。 一次數(shù)字簽名涉及到一個(gè)哈希函數(shù)、發(fā)送者的公鑰、發(fā)送者的私鑰。

個(gè)人安全郵件證書

  具有數(shù)字簽名功能的個(gè)人安全郵件證書是用戶證書的一種,是指單位用戶收發(fā)電子郵件時(shí)采用證書機(jī)制保證安全所必須具備的證書。個(gè)人安全電子郵件證書是符合x.509標(biāo)準(zhǔn)的數(shù)字安全證書,結(jié)合數(shù)字證書S/MIME技術(shù)對普通電子郵件做加密和數(shù)字簽名處理,確保電子郵件內(nèi)容的安全性、機(jī)密性、發(fā)件人身份確認(rèn)性和不可抵賴性。 具有數(shù)字簽名功能的 個(gè)人安全郵件證書中包含證書持有人的電子郵件地址、證書持有人的公鑰、頒發(fā)者(CA)以及頒發(fā)者對該證書的簽名。個(gè)人安全郵件證書功能的實(shí)現(xiàn)決定于用戶使用的郵件系統(tǒng)是否支持相應(yīng)功能。目前, MS Outlook 、Outlook Express、Foxmail及CA安全電子郵件系統(tǒng)均支持相應(yīng)功能。使用個(gè)人安全郵件證書可以收發(fā)加密和數(shù)字簽名郵件,保證電子郵件傳輸中的機(jī)密性、完整性和不可否認(rèn)性,確保電子郵件通信各方身份的真實(shí)性。

用數(shù)字簽名識別病毒

  [1][2]如何區(qū)分?jǐn)?shù)字簽名攻擊呢?有兩個(gè)方法:

  1.查看數(shù)字簽名的詳細(xì)信息,我們應(yīng)該查看該數(shù)字簽名的詳細(xì)信息,點(diǎn)擊“詳細(xì)信息”按鈕即可。

  我們會(huì)發(fā)現(xiàn)正常EXE和感染(或捆綁木馬)后的EXE數(shù)字簽名的區(qū)別

  正常EXE的數(shù)字簽名詳細(xì)信息

  被篡改后的EXE數(shù)字簽名信息無效

  方法2,使用數(shù)字簽名驗(yàn)證程序sigcheck.exe (可以百度一下找這個(gè)工具,著名系統(tǒng)工具包Sysinternals Suite的組件之一。)

  數(shù)字簽名異常的結(jié)果為:

  C:\Documents and Settings\litiejun\??\modify.exe:

  Verified: Unsigned

  File date: 15:46 2008-5-23

  Publisher: n/a

  Description: n/a

  Product: n/a

  Version: n/a

  File version: n/a

  數(shù)字簽名正常的結(jié)果為:

  C:\Documents and Settings\litiejun\??\che.exe:

  Verified: Signed

  Signing date: 16:28 2008-4-29

  Publisher: n/a

  Description: n/a

  Product: n/a

  Version: n/a

  File version: n/a

原因分析

  1,精心設(shè)計(jì)的感染

  當(dāng)EXE被感染時(shí),是很容易破壞文件的數(shù)字簽名信息的,如果攻擊者感染或破壞文件時(shí),有意不去破壞EXE中有關(guān)數(shù)字簽名的部分,就可能出現(xiàn)感染后,數(shù)字簽名看上去正常的情況。但認(rèn)真查看文件屬性或校驗(yàn)文件的HASH值,你會(huì)發(fā)現(xiàn)該EXE程序已經(jīng)不是最原始的版本了。

  2.該軟件發(fā)行商的數(shù)字簽名文件被盜,攻擊者可以把捆綁木馬或感染病毒后的EXE程序,也打包上數(shù)字簽名,這種情況下就更嚴(yán)重了。企業(yè)如果申請了數(shù)字簽名證書,一定要妥善保管,否則后患無窮。

使用方法

  你可以對你發(fā)出的每一封電子郵件進(jìn)行數(shù)字簽名。這不是指落款,普遍把落款訛誤成簽名。

  在我國大陸,數(shù)字簽名是具法律效力的,正在被普遍使用。2000年,中華人民共和國的新《合同法》首次確認(rèn)了電子合同、電子簽名的法律效力。2005年4月1日起,中華人民共和國首部《電子簽名法》正式實(shí)施。

原理特點(diǎn)

  每個(gè)人都有一對“鑰匙”(數(shù)字身份),其中一個(gè)只有她/他本人知道(密鑰),另一個(gè)公開的(公鑰)。簽名的時(shí)候用密鑰,驗(yàn)證簽名的時(shí)候用公鑰。又因?yàn)槿魏稳硕伎梢月淇钌攴Q她/他就是你,因此公鑰必須向接受者信任的人(身份認(rèn)證機(jī)構(gòu))來注冊。注冊后身份認(rèn)證機(jī)構(gòu)給你發(fā)一數(shù)字證書。對文件簽名后,你把此數(shù)字證書連同文件及簽名一起發(fā)給接受者,接受者向身份認(rèn)證機(jī)構(gòu)求證是否真地是用你的密鑰簽發(fā)的文件。

  在通訊中使用數(shù)字簽名一般基于以下原因:

鑒權(quán)

  公鑰加密系統(tǒng)允許任何人在發(fā)送信息時(shí)使用公鑰進(jìn)行加密,數(shù)字簽名能夠讓信息接收者確認(rèn)發(fā)送者的身份。當(dāng)然,接收者不可能百分之百確信發(fā)送者的真實(shí)身份,而只能在密碼系統(tǒng)未被破譯的情況下才有理由確信。

  鑒權(quán)的重要性在財(cái)務(wù)數(shù)據(jù)上表現(xiàn)得尤為突出。舉個(gè)例子,假設(shè)一家銀行將指令由它的分行傳輸?shù)剿闹醒牍芾硐到y(tǒng),指令的格式是(a,b),其中a是賬戶的賬號,而b是賬戶的現(xiàn)有金額。這時(shí)一位遠(yuǎn)程客戶可以先存入100元,觀察傳輸?shù)慕Y(jié)果,然后接二連三的發(fā)送格式為(a,b)的指令。這種方法被稱作重放攻擊

完整性

  傳輸數(shù)據(jù)的雙方都總希望確認(rèn)消息未在傳輸?shù)倪^程中被修改。加密使得第三方想要讀取數(shù)據(jù)十分困難,然而第三方仍然能采取可行的方法在傳輸?shù)倪^程中修改數(shù)據(jù)。一個(gè)通俗的例子就是同形攻擊:回想一下,還是上面的那家銀行從它的分行向它的中央管理系統(tǒng)發(fā)送格式為(a,b)的指令,其中a是賬號,而b是賬戶中的金額。一個(gè)遠(yuǎn)程客戶可以先存100元,然后攔截傳輸結(jié)果,再傳輸(a,b3),這樣他就立刻變成百萬富翁了。

不可抵賴

  在密文背景下,抵賴這個(gè)詞指的是不承認(rèn)與消息有關(guān)的舉動(dòng)(即聲稱消息來自第三方)。消息的接收方可以通過數(shù)字簽名來防止所有后續(xù)的抵賴行為,因?yàn)榻邮辗娇梢猿鍪竞灻o別人看來證明信息的來源。

如何實(shí)現(xiàn)

  數(shù)字簽名算法依靠公鑰加密技術(shù)來實(shí)現(xiàn)的。在公鑰加密技術(shù)里,每一個(gè)使用者有一對密鑰:一把公鑰和一把私鑰。公鑰可以自由發(fā)布,但私鑰則秘密保存;還有一個(gè)要求就是要讓通過公鑰推算出私鑰的做法不可能實(shí)現(xiàn)。

  普通的數(shù)字簽名算法包括三種算法:

  1.密碼生成算法 ;

  2.標(biāo)記算法 ;

  3.驗(yàn)證算法 。

Java數(shù)字簽名步驟

  1、將applet的class文件打包成*.jar(不會(huì)的可以在命令行中輸入jar查看幫助) [3]

  2 首先我們要生成一個(gè)keystore 否則在簽名的時(shí)候報(bào)如下錯(cuò)誤

  jarsigner 錯(cuò)誤: java.lang.RuntimeException: 密鑰庫裝入: C:\Documents and Settings\ij2ee\.keystore (系統(tǒng)找不到指定的文件。). (這邊的ij2ee 是我當(dāng)前系統(tǒng)用戶名)

  生成keystore的語句:keytool -genkey -alias 別名你可以自己寫 -keyalg RSA -keystore .keystore

  比如我的就是 keytool -genkey -alias ij2ee -keyalg RSA -keystore .keystore

  下面是會(huì)出現(xiàn)的數(shù)字簽名的一些步驟操作:

  輸入keystore密碼:

  再次輸入新密碼:

  您的名字與姓氏是什么?

  [Unknown]: ij2ee

  您的組織單位名稱是什么?

  [Unknown]: mtk

  您的組織名稱是什么?

  [Unknown]: mtk

  您所在的城市或區(qū)域名稱是什么?

  [Unknown]: suzhou

  您所在的州或省份名稱是什么?

  [Unknown]: jiangsu

  該單位的兩字母國家代碼是什么

  [Unknown]: cn

  CN=jeson, OU=mtk, O=mtk, L=suzhou, ST=jiangsu, C=cn 正確嗎?

  [否]: y

  輸入<sfcs>的主密碼

 ?。ㄈ绻?keystore 密碼相同,按回車):

  這時(shí)候會(huì)在jdk的bin目錄下生成 .keystore 。把這個(gè).keystore文件移動(dòng)到 C:\Documents and Settings\當(dāng)前系統(tǒng)用戶 的目錄下面。

  3、創(chuàng)建一個(gè)數(shù)字證書

  在命令行中輸入如下指令,peakCA和peakCALib自己起名字好了,3650是有效天數(shù),就是10年左右,在創(chuàng)建證書的的時(shí)候,需要填寫證書的一些信息和證書對應(yīng)的私鑰密碼。這些信息包括 CN=xx,OU=xx,O=xx,L=xx,ST=xx,C=xx,都是中文,一看就懂的

  keytool -genkey -alias peakCA -keyalg RSA -keysize 1024 -keystore peakCALib -validity 3650

  4、將證書導(dǎo)出到證書文件中

  在命令行中輸入如下指令,peakCA和peakCALib自己起名字好了,******是你輸入的密碼

  keytool -export -alias peakCA -file peakCA.cer -keystore peakCALib -storepass ****** -rfc

  5、授權(quán)jar文件,在命令行中輸入如下指令

  jarsigner -keystore peakCALib myapplet.jar peakCA



agun 2011-04-24 14:40 發(fā)表評論
]]>
加密算法http://www.aygfsteel.com/agun/archive/2011/04/24/348915.htmlagunagunSun, 24 Apr 2011 06:19:00 GMThttp://www.aygfsteel.com/agun/archive/2011/04/24/348915.htmlhttp://www.aygfsteel.com/agun/comments/348915.htmlhttp://www.aygfsteel.com/agun/archive/2011/04/24/348915.html#Feedback0http://www.aygfsteel.com/agun/comments/commentRss/348915.htmlhttp://www.aygfsteel.com/agun/services/trackbacks/348915.html 

一.        簡介

這段時(shí)間在看書的時(shí)候,看到相關(guān)章節(jié)關(guān)于的安全方面的,里面涉及到了一些加密的算法,正好我現(xiàn)在的項(xiàng)目中也用到了相關(guān)的的東西,數(shù)字簽名等。今天把相關(guān)的搜集起來。以備后用。

二.          加密算法介紹

根據(jù)密鑰類型不同將現(xiàn)代密碼技術(shù)分為兩類:對稱加密算法(秘密鑰匙加密)和非對稱加密算法(公開密鑰加密)。

對稱鑰匙加密系統(tǒng)是加密和解密均采用同一把秘密鑰匙,而且通信雙方都必須獲得這把鑰匙,并保持鑰匙的秘密。

非對稱密鑰加密系統(tǒng)采用的加密鑰匙(公鑰)和解密鑰匙(私鑰)是不同的。

對稱加密算法

對稱加密算法用來對敏感數(shù)據(jù)等信息進(jìn)行加密,常用的算法包括:

DES(Data Encryption Standard):數(shù)據(jù)加密標(biāo)準(zhǔn),速度較快,適用于加密大量數(shù)據(jù)的場合。

3DES(Triple DES):是基于DES,對一塊數(shù)據(jù)用三個(gè)不同的密鑰進(jìn)行三次加密,強(qiáng)度更高。

AES(Advanced Encryption Standard):高級加密標(biāo)準(zhǔn),是下一代的加密算法標(biāo)準(zhǔn),速度快,安全級別高;

AES

2000年10月,NIST(美國國家標(biāo)準(zhǔn)和技術(shù)協(xié)會(huì))宣布通過從15種侯選算法中選出的一項(xiàng)新的密匙加密標(biāo)準(zhǔn)。Rijndael被選中成為將來的AES。 Rijndael是在 1999 年下半年,由研究員 Joan Daemen 和 Vincent Rijmen 創(chuàng)建的。AES 正日益成為加密各種形式的電子數(shù)據(jù)的實(shí)際標(biāo)準(zhǔn)。

美國標(biāo)準(zhǔn)與技術(shù)研究院 (NIST) 于 2002 年 5 月 26 日制定了新的高級加密標(biāo)準(zhǔn) (AES) 規(guī)范。

算法原理

AES 算法基于排列和置換運(yùn)算。排列是對數(shù)據(jù)重新進(jìn)行安排,置換是將一個(gè)數(shù)據(jù)單元替換為另一個(gè)。AES 使用幾種不同的方法來執(zhí)行排列和置換運(yùn)算。

AES 是一個(gè)迭代的、對稱密鑰分組的密碼,它可以使用128、192 和 256 位密鑰,并且用 128 位(16字節(jié))分組加密和解密數(shù)據(jù)。與公共密鑰密碼使用密鑰對不同,對稱密鑰密碼使用相同的密鑰加密和解密數(shù)據(jù)。通過分組密碼返回的加密數(shù)據(jù)的位數(shù)與輸入數(shù)據(jù)相同。迭代加密使用一個(gè)循環(huán)結(jié)構(gòu),在該循環(huán)中重復(fù)置換和替換輸入數(shù)據(jù)。

AES與3DES的比較

算法名稱

算法類型

密鑰長度

速度

解密時(shí)間(建設(shè)機(jī)器每秒嘗試255個(gè)密鑰)

資源消耗

AES

對稱block密碼

128、192、256位

1490000億年

3DES

對稱feistel密碼

112位或168位

46億年

非對稱算法

常見的非對稱加密算法如下:

RSA:由 RSA 公司發(fā)明,是一個(gè)支持變長密鑰的公共密鑰算法,需要加密的文件塊的長度也是可變的;

DSA(Digital Signature Algorithm):數(shù)字簽名算法,是一種標(biāo)準(zhǔn)的 DSS(數(shù)字簽名標(biāo)準(zhǔn));

ECC(Elliptic Curves Cryptography):橢圓曲線密碼編碼學(xué)。

ECC

在1976年,由于對稱加密算法已經(jīng)不能滿足需要,Diffie 和Hellman發(fā)表了一篇叫《密碼學(xué)新動(dòng)向》的文章,介紹了公匙加密的概念,由Rivet、Shamir、Adelman提出了RSA算法。

隨著分解大整數(shù)方法的進(jìn)步及完善、計(jì)算機(jī)速度的提高以及計(jì)算機(jī)網(wǎng)絡(luò)的發(fā)展,為了保障數(shù)據(jù)的安全,RSA的密鑰需要不斷增加,但是,密鑰長度的增加導(dǎo)致了其加解密的速度大為降低,硬件實(shí)現(xiàn)也變得越來越難以忍受,這對使用RSA的應(yīng)用帶來了很重的負(fù)擔(dān),因此需要一種新的算法來代替RSA。

1985年N.Koblitz和Miller提出將橢圓曲線用于密碼算法,根據(jù)是有限域上的橢圓曲線上的點(diǎn)群中的離散對數(shù)問題ECDLP。ECDLP是比因子分解問題更難的問題,它是指數(shù)級的難度。

原理——橢圓曲線上的難題

 橢圓曲線上離散對數(shù)問題ECDLP定義如下:給定素?cái)?shù)p和橢圓曲線E,對Q=kP,在已知P,Q 的情況下求出小于p的正整數(shù)k??梢宰C明由k和P計(jì)算Q比較容易,而由Q和P計(jì)算k則比較困難。

將橢圓曲線中的加法運(yùn)算與離散對數(shù)中的模乘運(yùn)算相對應(yīng),將橢圓曲線中的乘法運(yùn)算與離散對數(shù)中的模冪運(yùn)算相對應(yīng),我們就可以建立基于橢圓曲線的對應(yīng)的密碼體制。

例如,對應(yīng)Diffie-Hellman公鑰系統(tǒng),我們可以通過如下方式在橢圓曲線上予以實(shí)現(xiàn):在E上選取生成元P,要求由P產(chǎn)生的群元素足夠多,通信雙方A和B分別選取a和b,a和b 予以保密,但將aP和bP公開,A和B間通信用的密鑰為abP,這是第三者無法得知的。

對應(yīng)ELGamal密碼系統(tǒng)可以采用如下的方式在橢圓曲線上予以實(shí)現(xiàn):

將明文m嵌入到E上Pm點(diǎn),選一點(diǎn)B∈E,每一用戶都選一整數(shù)a,0<a<N,N為階數(shù)已知,a保密,aB公開。欲向A送m,可送去下面一對數(shù)偶:[kB,Pm+k(aAB)],k是隨機(jī)產(chǎn)生的整數(shù)。A可以從kB求得k(aAB)。通過:Pm+k(aAB)- k(aAB)=Pm恢復(fù)Pm。同樣對應(yīng)DSA,考慮如下等式:

K=kG  [其中 K,G為Ep(a,b)上的點(diǎn),k為小于n(n是點(diǎn)G的階)的整數(shù)]

不難發(fā)現(xiàn),給定k和G,根據(jù)加法法則,計(jì)算K很容易;但給定K和G,求k就相對困難了。

這就是橢圓曲線加密算法采用的難題。我們把點(diǎn)G稱為基點(diǎn)(base point),k(k<n,n為基點(diǎn)G的階)稱為私有密鑰(privte key),K稱為公開密鑰(public key)。

ECC與RSA的比較

ECC和RSA相比,在許多方面都有對絕對的優(yōu)勢,主要體現(xiàn)在以下方面:

抗攻擊性強(qiáng)。相同的密鑰長度,其抗攻擊性要強(qiáng)很多倍。

計(jì)算量小,處理速度快。ECC總的速度比RSA、DSA要快得多。

存儲(chǔ)空間占用小。ECC的密鑰尺寸和系統(tǒng)參數(shù)與RSA、DSA相比要小得多,意味著它所占的存貯空間要小得多。這對于加密算法在IC卡上的應(yīng)用具有特別重要的意義。

帶寬要求低。當(dāng)對長消息進(jìn)行加解密時(shí),三類密碼系統(tǒng)有相同的帶寬要求,但應(yīng)用于短消息時(shí)ECC帶寬要求卻低得多。帶寬要求低使ECC在無線網(wǎng)絡(luò)領(lǐng)域具有廣泛的應(yīng)用前景。

ECC的這些特點(diǎn)使它必將取代RSA,成為通用的公鑰加密算法。比如SET協(xié)議的制定者已把它作為下一代SET協(xié)議中缺省的公鑰密碼算法。

下面兩張表示是RSA和ECC的安全性和速度的比較。

攻破時(shí)間(MIPS年)

RSA/DSA(密鑰長度)

ECC密鑰長度

RSA/ECC密鑰長度比

104

512

106

5:1

108

768

132

6:1

1011

1024

160

7:1

1020

2048

210

10:1

1078

21000

600

35:1

RSA和ECC安全模長得比較

功能

Security Builder 1.2

BSAFE 3.0

163位ECC(ms)

1,023位RSA(ms)

密鑰對生成

3.8

4,708.3

簽名

2.1(ECNRA)

228.4

3.0(ECDSA)

認(rèn)證

9.9(ECNRA)

12.7

10.7(ECDSA)

Diffie—Hellman密鑰交換

7.3

1,654.0

RSA和ECC速度比較

散列算法

散列是信息的提煉,通常其長度要比信息小得多,且為一個(gè)固定長度。加密性強(qiáng)的散列一定是不可逆的,這就意味著通過散列結(jié)果,無法推出任何部分的原始信息。任何輸入信息的變化,哪怕僅一位,都將導(dǎo)致散列結(jié)果的明顯變化,這稱之為雪崩效應(yīng)。散列還應(yīng)該是防沖突的,即找不出具有相同散列結(jié)果的兩條信息。具有這些特性的散列結(jié)果就可以用于驗(yàn)證信息是否被修改。

單向散列函數(shù)一般用于產(chǎn)生消息摘要,密鑰加密等,常見的有:

l         MD5(Message Digest Algorithm 5):是RSA數(shù)據(jù)安全公司開發(fā)的一種單向散列算法。

l         SHA(Secure Hash Algorithm):可以對任意長度的數(shù)據(jù)運(yùn)算生成一個(gè)160位的數(shù)值;

SHA-1

在1993年,安全散列算法(SHA)由美國國家標(biāo)準(zhǔn)和技術(shù)協(xié)會(huì)(NIST)提出,并作為聯(lián)邦信息處理標(biāo)準(zhǔn)(FIPS PUB 180)公布;1995年又發(fā)布了一個(gè)修訂版FIPS PUB 180-1,通常稱之為SHA-1。SHA-1是基于MD4算法的,并且它的設(shè)計(jì)在很大程度上是模仿MD4的?,F(xiàn)在已成為公認(rèn)的最安全的散列算法之一,并被廣泛使用。

原理

SHA-1是一種數(shù)據(jù)加密算法,該算法的思想是接收一段明文,然后以一種不可逆的方式將它轉(zhuǎn)換成一段(通常更?。┟芪?,也可以簡單的理解為取一串輸入碼(稱為預(yù)映射或信息),并把它們轉(zhuǎn)化為長度較短、位數(shù)固定的輸出序列即散列值(也稱為信息摘要或信息認(rèn)證代碼)的過程。

單向散列函數(shù)的安全性在于其產(chǎn)生散列值的操作過程具有較強(qiáng)的單向性。如果在輸入序列中嵌入密碼,那么任何人在不知道密碼的情況下都不能產(chǎn)生正確的散列值,從而保證了其安全性。SHA將輸入流按照每塊512位(64個(gè)字節(jié))進(jìn)行分塊,并產(chǎn)生20個(gè)字節(jié)的被稱為信息認(rèn)證代碼或信息摘要的輸出。

該算法輸入報(bào)文的最大長度不超過264位,產(chǎn)生的輸出是一個(gè)160位的報(bào)文摘要。輸入是按512 位的分組進(jìn)行處理的。SHA-1是不可逆的、防沖突,并具有良好的雪崩效應(yīng)。

通過散列算法可實(shí)現(xiàn)數(shù)字簽名實(shí)現(xiàn),數(shù)字簽名的原理是將要傳送的明文通過一種函數(shù)運(yùn)算(Hash)轉(zhuǎn)換成報(bào)文摘要(不同的明文對應(yīng)不同的報(bào)文摘要),報(bào)文摘要加密后與明文一起傳送給接受方,接受方將接受的明文產(chǎn)生新的報(bào)文摘要與發(fā)送方的發(fā)來報(bào)文摘要解密比較,比較結(jié)果一致表示明文未被改動(dòng),如果不一致表示明文已被篡改。

MAC (信息認(rèn)證代碼)就是一個(gè)散列結(jié)果,其中部分輸入信息是密碼,只有知道這個(gè)密碼的參與者才能再次計(jì)算和驗(yàn)證MAC碼的合法性。MAC的產(chǎn)生參見下圖。

輸入信息

密碼

散列函數(shù)

信息認(rèn)證代碼

SHA-1與MD5的比較

因?yàn)槎呔蒑D4導(dǎo)出,SHA-1和MD5彼此很相似。相應(yīng)的,他們的強(qiáng)度和其他特性也是相似,但還有以下幾點(diǎn)不同:

l         對強(qiáng)行供給的安全性:最顯著和最重要的區(qū)別是SHA-1摘要比MD5摘要長32 位。使用強(qiáng)行技術(shù),產(chǎn)生任何一個(gè)報(bào)文使其摘要等于給定報(bào)摘要的難度對MD5是2128數(shù)量級的操作,而對SHA-1則是2160數(shù)量級的操作。這樣,SHA-1對強(qiáng)行攻擊有更大的強(qiáng)度。

l         對密碼分析的安全性:由于MD5的設(shè)計(jì),易受密碼分析的攻擊,SHA-1顯得不易受這樣的攻擊。

l         速度:在相同的硬件上,SHA-1的運(yùn)行速度比MD5慢。

對稱與非對稱算法比較

    以上綜述了兩種加密方法的原理,總體來說主要有下面幾個(gè)方面的不同:

l         在管理方面:公鑰密碼算法只需要較少的資源就可以實(shí)現(xiàn)目的,在密鑰的分配上,兩者之間相差一個(gè)指數(shù)級別(一個(gè)是n一個(gè)是n2)。所以私鑰密碼算法不適應(yīng)廣域網(wǎng)的使用,而且更重要的一點(diǎn)是它不支持?jǐn)?shù)字簽名。

l         在安全方面:由于公鑰密碼算法基于未解決的數(shù)學(xué)難題,在破解上幾乎不可能。對于私鑰密碼算法,到了AES雖說從理論來說是不可能破解的,但從計(jì)算機(jī)的發(fā)展角度來看。公鑰更具有優(yōu)越性。

l         從速度上來看:AES的軟件實(shí)現(xiàn)速度已經(jīng)達(dá)到了每秒數(shù)兆或數(shù)十兆比特。是公鑰的100倍,如果用硬件來實(shí)現(xiàn)的話這個(gè)比值將擴(kuò)大到1000倍。

三.          加密算法的選擇

前面的章節(jié)已經(jīng)介紹了對稱解密算法和非對稱加密算法,有很多人疑惑:那我們在實(shí)際使用的過程中究竟該使用哪一種比較好呢?

我們應(yīng)該根據(jù)自己的使用特點(diǎn)來確定,由于非對稱加密算法的運(yùn)行速度比對稱加密算法的速度慢很多,當(dāng)我們需要加密大量的數(shù)據(jù)時(shí),建議采用對稱加密算法,提高加解密速度。

對稱加密算法不能實(shí)現(xiàn)簽名,因此簽名只能非對稱算法。

由于對稱加密算法的密鑰管理是一個(gè)復(fù)雜的過程,密鑰的管理直接決定著他的安全性,因此當(dāng)數(shù)據(jù)量很小時(shí),我們可以考慮采用非對稱加密算法。

在實(shí)際的操作過程中,我們通常采用的方式是:采用非對稱加密算法管理對稱算法的密鑰,然后用對稱加密算法加密數(shù)據(jù),這樣我們就集成了兩類加密算法的優(yōu)點(diǎn),既實(shí)現(xiàn)了加密速度快的優(yōu)點(diǎn),又實(shí)現(xiàn)了安全方便管理密鑰的優(yōu)點(diǎn)。

如果在選定了加密算法后,那采用多少位的密鑰呢?一般來說,密鑰越長,運(yùn)行的速度就越慢,應(yīng)該根據(jù)的我們實(shí)際需要的安全級別來選擇,一般來說,RSA建議采用1024位的數(shù)字,ECC建議采用160位,AES采用128為即可。

四.          密碼學(xué)在現(xiàn)代的應(yīng)用

隨著密碼學(xué)商業(yè)應(yīng)用的普及,公鑰密碼學(xué)受到前所未有的重視。除傳統(tǒng)的密碼應(yīng)用系統(tǒng)外,PKI系統(tǒng)以公鑰密碼技術(shù)為主,提供加密、簽名、認(rèn)證、密鑰管理、分配等功能。

保密通信:保密通信是密碼學(xué)產(chǎn)生的動(dòng)因。使用公私鑰密碼體制進(jìn)行保密通信時(shí),信息接收者只有知道對應(yīng)的密鑰才可以解密該信息。

數(shù)字簽名:數(shù)字簽名技術(shù)可以代替?zhèn)鹘y(tǒng)的手寫簽名,而且從安全的角度考慮,數(shù)字簽名具有很好的防偽造功能。在政府機(jī)關(guān)、軍事領(lǐng)域、商業(yè)領(lǐng)域有廣泛的應(yīng)用環(huán)境。

秘密共享:秘密共享技術(shù)是指將一個(gè)秘密信息利用密碼技術(shù)分拆成n個(gè)稱為共享因子的信息,分發(fā)給n個(gè)成員,只有k(k≤n)個(gè)合法成員的共享因子才可以恢復(fù)該秘密信息,其中任何一個(gè)或m(m≤k)個(gè)成員合作都不知道該秘密信息。利用秘密共享技術(shù)可以控制任何需要多個(gè)人共同控制的秘密信息、命令等。

認(rèn)證功能:在公開的信道上進(jìn)行敏感信息的傳輸,采用簽名技術(shù)實(shí)現(xiàn)對消息的真實(shí)性、完整性進(jìn)行驗(yàn)證,通過驗(yàn)證公鑰證書實(shí)現(xiàn)對通信主體的身份驗(yàn)證。

密鑰管理:密鑰是保密系統(tǒng)中更為脆弱而重要的環(huán)節(jié),公鑰密碼體制是解決密鑰管理工作的有力工具;利用公鑰密碼體制進(jìn)行密鑰協(xié)商和產(chǎn)生,保密通信雙方不需要事先共享秘密信息;利用公鑰密碼體制進(jìn)行密鑰分發(fā)、保護(hù)、密鑰托管、密鑰恢復(fù)等。

基于公鑰密碼體制可以實(shí)現(xiàn)以上通用功能以外,還可以設(shè)計(jì)實(shí)現(xiàn)以下的系統(tǒng):安全電子商務(wù)系統(tǒng)、電子現(xiàn)金系統(tǒng)、電子選舉系統(tǒng)、電子招投標(biāo)系統(tǒng)、電子彩票系統(tǒng)等。

公鑰密碼體制的產(chǎn)生是密碼學(xué)由傳統(tǒng)的政府、軍事等應(yīng)用領(lǐng)域走向商用、民用的基礎(chǔ),同時(shí)互聯(lián)網(wǎng)、電子商務(wù)的發(fā)展為密碼學(xué)的發(fā)展開辟了更為廣闊的前景。

五.          加密算法的未來

隨著計(jì)算方法的改進(jìn),計(jì)算機(jī)運(yùn)行速度的加快,網(wǎng)絡(luò)的發(fā)展,越來越多的算法被破解。

在2004年國際密碼學(xué)會(huì)議(Crypto’2004)上,來自中國山東大學(xué)的王小云教授做的破譯MD5、HAVAL-128、MD4和RIPEMD算法的報(bào)告,令在場的國際頂尖密碼學(xué)專家都為之震驚,意味著這些算法將從應(yīng)用中淘汰。隨后,SHA-1也被宣告被破解。

歷史上有三次對DES有影響的攻擊實(shí)驗(yàn)。1997年,利用當(dāng)時(shí)各國 7萬臺計(jì)算機(jī),歷時(shí)96天破解了DES的密鑰。1998年,電子邊境基金會(huì)(EFF)用25萬美元制造的專用計(jì)算機(jī),用56小時(shí)破解了DES的密鑰。1999年,EFF用22小時(shí)15分完成了破解工作。因此。曾經(jīng)有過卓越貢獻(xiàn)的DES也不能滿足我們?nèi)找嬖鲩L的需求了。

最近,一組研究人員成功的把一個(gè)512位的整數(shù)分解因子,宣告了RSA的破解。

我們說數(shù)據(jù)的安全是相對的,可以說在一定時(shí)期一定條件下是安全的,隨著硬件和網(wǎng)絡(luò)的發(fā)展,或者是另一個(gè)王小云的出現(xiàn),目前的常用加密算法都有可能在短時(shí)間內(nèi)被破解,那時(shí)我們不得不使用更長的密鑰或更加先進(jìn)的算法,才能保證數(shù)據(jù)的安全,因此加密算法依然需要不斷發(fā)展和完善,提供更高的加密安全強(qiáng)度和運(yùn)算速度。

縱觀這兩種算法一個(gè)從DES到3DES再到AES,一個(gè)從RSA到ECC。其發(fā)展角度無不是從密鑰的簡單性,成本的低廉性,管理的簡易性,算法的復(fù)雜性,保密的安全性以及計(jì)算的快速性這幾個(gè)方面去考慮。因此,未來算法的發(fā)展也必定是從這幾個(gè)角度出發(fā)的,而且在實(shí)際操作中往往把這兩種算法結(jié)合起來,也需將來一種集兩種算法優(yōu)點(diǎn)于一身的新型算法將會(huì)出現(xiàn),到那個(gè)時(shí)候,電子商務(wù)的實(shí)現(xiàn)必將更加的快捷和安全。



agun 2011-04-24 14:19 發(fā)表評論
]]>
Cookie 和 Sessionhttp://www.aygfsteel.com/agun/archive/2010/12/04/339792.htmlagunagunSat, 04 Dec 2010 04:14:00 GMThttp://www.aygfsteel.com/agun/archive/2010/12/04/339792.htmlhttp://www.aygfsteel.com/agun/comments/339792.htmlhttp://www.aygfsteel.com/agun/archive/2010/12/04/339792.html#Feedback0http://www.aygfsteel.com/agun/comments/commentRss/339792.htmlhttp://www.aygfsteel.com/agun/services/trackbacks/339792.html一、cookie機(jī)制和session機(jī)制的區(qū)別
*************************************************************************************
具體來說cookie機(jī)制采用的是在客戶端保持狀態(tài)的方案,而session機(jī)制采用的是在服務(wù)器端保持狀態(tài)的方案。
同時(shí)我們也看到,由于才服務(wù)器端保持狀態(tài)的方案在客戶端也需要保存一個(gè)標(biāo)識,所以session
機(jī)制可能需要借助于cookie機(jī)制來達(dá)到保存標(biāo)識的目的,但實(shí)際上還有其他選擇
*************************************************************************************

二、會(huì)話cookie和持久cookie的區(qū)別
*************************************************************************************
如果不設(shè)置過期時(shí)間,則表示這個(gè)cookie生命周期為瀏覽器會(huì)話期間,只要關(guān)閉瀏覽器窗口,cookie就消失了。這種生命期為瀏覽會(huì)話期的cookie被稱為會(huì)話cookie。會(huì)話cookie一般不保存在硬盤上而是保存在內(nèi)存里。
  如果設(shè)置了過期時(shí)間,瀏覽器就會(huì)把cookie保存到硬盤上,關(guān)閉后再次打開瀏覽器,這些cookie依然有效直到超過設(shè)定的過期時(shí)間。
  存儲(chǔ)在硬盤上的cookie可以在不同的瀏覽器進(jìn)程間共享,比如兩個(gè)IE窗口。而對于保存在內(nèi)存的cookie,不同的瀏覽器有不同的處理方式。
*************************************************************************************

三、如何利用實(shí)現(xiàn)自動(dòng)登錄
*************************************************************************************
  當(dāng)用戶在某個(gè)網(wǎng)站注冊后,就會(huì)收到一個(gè)惟一用戶ID的cookie??蛻艉髞碇匦逻B接時(shí),這個(gè)
用戶ID會(huì)自動(dòng)返回,服務(wù)器對它進(jìn)行檢查,確定它是否為注冊用戶且選擇了自動(dòng)登錄,從而使用戶務(wù)需給出明確的用戶名和密碼,就可以訪問服務(wù)器上的資源。
*************************************************************************************

四、如何根據(jù)用戶的愛好定制站點(diǎn)
*************************************************************************************
  網(wǎng)站可以使用cookie記錄用戶的意愿。對于簡單的設(shè)置,網(wǎng)站可以直接將頁面的設(shè)置存儲(chǔ)在cookie中完成定制。然而對于更復(fù)雜的定制,網(wǎng)站只需僅將一個(gè)惟一的標(biāo)識符發(fā)送給用戶,由服務(wù)器端的數(shù)據(jù)庫存儲(chǔ)每個(gè)標(biāo)識符對應(yīng)的頁面設(shè)置。
*************************************************************************************

五、cookie的發(fā)送
*************************************************************************************
1.創(chuàng)建Cookie對象
2.設(shè)置最大時(shí)效
3.將Cookie放入到HTTP響應(yīng)報(bào)頭
如果你創(chuàng)建了一個(gè)cookie,并將他發(fā)送到瀏覽器,默認(rèn)情況下它是一個(gè)會(huì)話級別的cookie:存儲(chǔ)在瀏覽器的內(nèi)存中,用戶退出瀏覽器之后被刪除。如果你希望瀏覽器將該cookie存儲(chǔ)在磁盤上,則
需要使用maxAge,并給出一個(gè)以秒為單位的時(shí)間。將最大時(shí)效設(shè)為0則是命令瀏覽器刪除該cookie。
發(fā)送cookie需要使用HttpServletResponse的addCookie方法,將cookie插入到一個(gè)Set-Cookie HTTP請求報(bào)頭中。由于這個(gè)方法并不修改任何之前指定的Set-Cookie報(bào)頭,而是創(chuàng)建新的報(bào)頭,因此我們將這個(gè)方法稱為是addCookie,而非setCookie。同樣要記住響應(yīng)報(bào)頭必須在任何文檔內(nèi)容發(fā)送到客戶端之前設(shè)置。

六、cookie的讀取
*************************************************************************************
1.調(diào)用request.getCookie
要獲取有瀏覽器發(fā)送來的cookie,需要調(diào)用HttpServletRequest的getCookies方法,這個(gè)調(diào)用返回Cookie對象的數(shù)組,對應(yīng)由HTTP請求中Cookie報(bào)頭輸入的值。
2.對數(shù)組進(jìn)行循環(huán),調(diào)用每個(gè)cookie的getName方法,直到找到感興趣的cookie為止
 cookie與你的主機(jī)(域)相關(guān),而非你的servlet或JSP頁面。因而,盡管你的servlet可能只發(fā)送了單個(gè)cookie,你也可能會(huì)得到許多不相關(guān)的cookie。
例如:
  String cookieName = “userID”;
    Cookie cookies[] = request.getCookies();
    if (cookies!=null){
        for(int i=0;i<cookies.length;i++){
    Cookie cookie = cookies[i];
    if (cookieName.equals(cookie.getName())){
        doSomethingWith(cookie.getValue());
}
}
}
*************************************************************************************

七、如何使用cookie檢測初訪者
*************************************************************************************
A.調(diào)用HttpServletRequest.getCookies()獲取Cookie數(shù)組
B.在循環(huán)中檢索指定名字的cookie是否存在以及對應(yīng)的值是否正確
C.如果是則退出循環(huán)并設(shè)置區(qū)別標(biāo)識
D.根據(jù)區(qū)別標(biāo)識判斷用戶是否為初訪者從而進(jìn)行不同的操作
*************************************************************************************

八、使用cookie檢測初訪者的常見錯(cuò)誤
*************************************************************************************
不能僅僅因?yàn)閏ookie數(shù)組中不存在在特定的數(shù)據(jù)項(xiàng)就認(rèn)為用戶是個(gè)初訪者。如果cookie數(shù)組為null,客戶可能是一個(gè)初訪者,也可能是由于用戶將cookie刪除或禁用造成的結(jié)果。
但是,如果數(shù)組非null,也不過是顯示客戶曾經(jīng)到過你的網(wǎng)站或域,并不能說明他們曾經(jīng)訪問過你的servlet。其它servlet、JSP頁面以及非Java Web應(yīng)用都可以設(shè)置cookie,依據(jù)路徑的設(shè)置,其中的任何cookie都有可能返回給用戶的瀏覽器。
正確的做法是判斷cookie數(shù)組是否為空且是否存在指定的Cookie對象且值正確。
*************************************************************************************

九、使用cookie屬性的注意問題
*************************************************************************************
  屬性是從服務(wù)器發(fā)送到瀏覽器的報(bào)頭的一部分;但它們不屬于由瀏覽器返回給服務(wù)器的報(bào)頭?!?br />   因此除了名稱和值之外,cookie屬性只適用于從服務(wù)器輸出到客戶端的cookie;服務(wù)器端來自于瀏覽器的cookie并沒有設(shè)置這些屬性?!?br />   因而不要期望通過request.getCookies得到的cookie中可以使用這個(gè)屬性。這意味著,你不能僅僅通過設(shè)置cookie的最大時(shí)效,發(fā)出它,在隨后的輸入數(shù)組中查找適當(dāng)?shù)腸ookie,讀取它的值,修改它并將它存回Cookie,從而實(shí)現(xiàn)不斷改變的cookie值。
*************************************************************************************

十、如何使用cookie記錄各個(gè)用戶的訪問計(jì)數(shù)
*************************************************************************************
1.獲取cookie數(shù)組中專門用于統(tǒng)計(jì)用戶訪問次數(shù)的cookie的值
2.將值轉(zhuǎn)換成int型
3.將值加1并用原來的名稱重新創(chuàng)建一個(gè)Cookie對象
4.重新設(shè)置最大時(shí)效
5.將新的cookie輸出
*************************************************************************************

十一、session在不同環(huán)境下的不同含義
*************************************************************************************
session,中文經(jīng)常翻譯為會(huì)話,其本來的含義是指有始有終的一系列動(dòng)作/消息,比如打電話是從拿起電話撥號到掛斷電話這中間的一系列過程可以稱之為一個(gè)session。
然而當(dāng)session一詞與網(wǎng)絡(luò)協(xié)議相關(guān)聯(lián)時(shí),它又往往隱含了“面向連接”和/或“保持狀態(tài)”這樣兩個(gè)含義。
  session在Web開發(fā)環(huán)境下的語義又有了新的擴(kuò)展,它的含義是指一類用來在客戶端與服務(wù)器端之間保持狀態(tài)的解決方案。有時(shí)候Session也用來指這種解決方案的存儲(chǔ)結(jié)構(gòu)。
*************************************************************************************

十二、session的機(jī)制
*************************************************************************************
  session機(jī)制是一種服務(wù)器端的機(jī)制,服務(wù)器使用一種類似于散列表的結(jié)構(gòu)(也可能就是使用散列表)來保存信息。
但程序需要為某個(gè)客戶端的請求創(chuàng)建一個(gè)session的時(shí)候,服務(wù)器首先檢查這個(gè)客戶端的請求里是否包含了一個(gè)session標(biāo)識-稱為session id,如果已經(jīng)包含一個(gè)session id則說明以前已經(jīng)為此客戶創(chuàng)建過session,服務(wù)器就按照session id把這個(gè)session檢索出來使用(如果檢索不到,可能會(huì)新建一個(gè),這種情況可能出現(xiàn)在服務(wù)端已經(jīng)刪除了該用戶對應(yīng)的session對象,但用戶人為地在請求的URL后面附加上一個(gè)JSESSION的參數(shù))。
如果客戶請求不包含session id,則為此客戶創(chuàng)建一個(gè)session并且生成一個(gè)與此session相關(guān)聯(lián)的session id,這個(gè)session id將在本次響應(yīng)中返回給客戶端保存。
*************************************************************************************

十三、保存session id的幾種方式
*************************************************************************************
A.保存session id的方式可以采用cookie,這樣在交互過程中瀏覽器可以自動(dòng)的按照規(guī)則把這個(gè)標(biāo)識發(fā)送給服務(wù)器。
B.由于cookie可以被人為的禁止,必須有其它的機(jī)制以便在cookie被禁止時(shí)仍然能夠把session id傳遞回服務(wù)器,經(jīng)常采用的一種技術(shù)叫做URL重寫,就是把session id附加在URL路徑的后面,附加的方式也有兩種,一種是作為URL路徑的附加信息,另一種是作為查詢字符串附加在URL后面。網(wǎng)絡(luò)在整個(gè)交互過程中始終保持狀態(tài),就必須在每個(gè)客戶端可能請求的路徑后面都包含這個(gè)session id。
C.另一種技術(shù)叫做表單隱藏字段。就是服務(wù)器會(huì)自動(dòng)修改表單,添加一個(gè)隱藏字段,以便在表單提交時(shí)能夠把session id傳遞回服務(wù)器。
*************************************************************************************

十四、session什么時(shí)候被創(chuàng)建
*************************************************************************************
一個(gè)常見的錯(cuò)誤是以為session在有客戶端訪問時(shí)就被創(chuàng)建,然而事實(shí)是直到某server端程序(如Servlet)調(diào)用HttpServletRequest.getSession(true)這樣的語句時(shí)才會(huì)被創(chuàng)建。
*************************************************************************************

十五、session何時(shí)被刪除
*************************************************************************************
session在下列情況下被刪除:
A.程序調(diào)用HttpSession.invalidate()
B.距離上一次收到客戶端發(fā)送的session id時(shí)間間隔超過了session的最大有效時(shí)間
C.服務(wù)器進(jìn)程被停止

再次注意關(guān)閉瀏覽器只會(huì)使存儲(chǔ)在客戶端瀏覽器內(nèi)存中的session cookie失效,不會(huì)使服務(wù)器端的session對象失效。
*************************************************************************************

十六、URL重寫有什么缺點(diǎn)
*************************************************************************************
   對所有的URL使用URL重寫,包括超鏈接,form的action,和重定向的URL。每個(gè)引用你的站點(diǎn)的URL,以及那些返回給用戶的URL(即使通過間接手段,比如服務(wù)器重定向中的Location字段)都要添加額外的信息。
   這意味著在你的站點(diǎn)上不能有任何靜態(tài)的HTML頁面(至少靜態(tài)頁面中不能有任何鏈接到站點(diǎn)動(dòng)態(tài)頁面的鏈接)。因此,每個(gè)頁面都必須使用servlet或JSP動(dòng)態(tài)生成。即使所有的頁面都動(dòng)態(tài)生成,如果用戶離開了會(huì)話并通過書簽或鏈接再次回來,會(huì)話的信息都會(huì)丟失,因?yàn)榇鎯?chǔ)下來的鏈接含有錯(cuò)誤的標(biāo)識信息-該URL后面的SESSION ID已經(jīng)過期了?! ?br /> *************************************************************************************

十七、使用隱藏的表單域有什么缺點(diǎn)
*************************************************************************************
    僅當(dāng)每個(gè)頁面都是有表單提交而動(dòng)態(tài)生成時(shí),才能使用這種方法。單擊常規(guī)的<A HREF..>超文本鏈接并不產(chǎn)生表單提交,因此隱藏的表單域不能支持通常的會(huì)話跟蹤,只能用于一系列特定的操作中,比如在線商店的結(jié)賬過程
*************************************************************************************

十八、會(huì)話跟蹤的基本步驟
*************************************************************************************
1.訪問與當(dāng)前請求相關(guān)的會(huì)話對象
2.查找與會(huì)話相關(guān)的信息
3.存儲(chǔ)會(huì)話信息
4.廢棄會(huì)話數(shù)據(jù)
*************************************************************************************

十九、getSession()/getSession(true)、getSession(false)的區(qū)別
*************************************************************************************
getSession()/getSession(true):當(dāng)session存在時(shí)返回該session,否則新建一個(gè)session并返回該對象
getSession(false):當(dāng)session存在時(shí)返回該session,否則不會(huì)新建session,返回null
*************************************************************************************

二十、如何將信息于會(huì)話關(guān)聯(lián)起來
*************************************************************************************
  setAttribute會(huì)替換任何之前設(shè)定的值;如果想要在不提供任何代替的情況下移除某個(gè)值,則應(yīng)使用removeAttribute。這個(gè)方法會(huì)觸發(fā)所有實(shí)現(xiàn)了HttpSessionBindingListener接口的值的valueUnbound
方法。
*************************************************************************************

二十一、會(huì)話屬性的類型有什么限制嗎
*************************************************************************************
通常會(huì)話屬性的類型只要是Object就可以了。除了null或基本類型,如int,double,boolean。
如果要使用基本類型的值作為屬性,必須將其轉(zhuǎn)換為相應(yīng)的封裝類對象
*************************************************************************************

二十二、如何廢棄會(huì)話數(shù)據(jù)
*************************************************************************************
A.只移除自己編寫的servlet創(chuàng)建的數(shù)據(jù):
   調(diào)用removeAttribute(“key”)將指定鍵關(guān)聯(lián)的值廢棄
B.刪除整個(gè)會(huì)話(在當(dāng)前Web應(yīng)用中):
   調(diào)用invalidate,將整個(gè)會(huì)話廢棄掉。這樣做會(huì)丟失該用戶的所有會(huì)話數(shù)據(jù),而非僅僅由我們
servlet或JSP頁面創(chuàng)建的會(huì)話數(shù)據(jù)
C.將用戶從系統(tǒng)中注銷并刪除所有屬于他(或她)的會(huì)話
   調(diào)用logOut,將客戶從Web服務(wù)器中注銷,同時(shí)廢棄所有與該用戶相關(guān)聯(lián)的會(huì)話(每個(gè)Web應(yīng)用至多一個(gè))。這個(gè)操作有可能影響到服務(wù)器上多個(gè)不同的Web應(yīng)用
*************************************************************************************

二十三、使用isNew來判斷用戶是否為新舊用戶的錯(cuò)誤做法
*************************************************************************************
public boolean isNew()方法如果會(huì)話尚未和客戶程序(瀏覽器)發(fā)生任何聯(lián)系,則這個(gè)方法返回true,這一般是因?yàn)闀?huì)話是新建的,不是由輸入的客戶請求所引起的。
但如果isNew返回false,只不過是說明他之前曾經(jīng)訪問該Web應(yīng)用,并不代表他們曾訪問過我們的servlet或JSP頁面。
因?yàn)閟ession是與用戶相關(guān)的,在用戶之前訪問的每一個(gè)頁面都有可能創(chuàng)建了會(huì)話。因此isNew為false只能說用戶之前訪問過該Web應(yīng)用,session可以是當(dāng)前頁面創(chuàng)建,也可能是由用戶之前訪問過的頁面創(chuàng)建的。
正確的做法是判斷某個(gè)session中是否存在某個(gè)特定的key且其value是否正確
*************************************************************************************

二十四、Cookie的過期和Session的超時(shí)有什么區(qū)別
*************************************************************************************
會(huì)話的超時(shí)由服務(wù)器來維護(hù),它不同于Cookie的失效日期。首先,會(huì)話一般基于駐留內(nèi)存的cookie
不是持續(xù)性的cookie,因而也就沒有截至日期。即使截取到JSESSIONID cookie,并為它設(shè)定一個(gè)失效日期發(fā)送出去。瀏覽器會(huì)話和服務(wù)器會(huì)話也會(huì)截然不同。
*************************************************************************************

二十五、session cookie和session對象的生命周期是一樣的嗎
*************************************************************************************
當(dāng)用戶關(guān)閉了瀏覽器雖然session cookie已經(jīng)消失,但session對象仍然保存在服務(wù)器端
*************************************************************************************

二十六、是否只要關(guān)閉瀏覽器,session就消失了
*************************************************************************************
程序一般都是在用戶做log off的時(shí)候發(fā)個(gè)指令去刪除session,然而瀏覽器從來不會(huì)主動(dòng)在關(guān)閉之前通知服務(wù)器它將要被關(guān)閉,因此服務(wù)器根本不會(huì)有機(jī)會(huì)知道瀏覽器已經(jīng)關(guān)閉。服務(wù)器會(huì)一直保留這個(gè)會(huì)話對象直到它處于非活動(dòng)狀態(tài)超過設(shè)定的間隔為止。
之所以會(huì)有這種錯(cuò)誤的認(rèn)識,是因?yàn)榇蟛糠謘ession機(jī)制都使用會(huì)話cookie來保存session id,而關(guān)閉瀏覽器后這個(gè)session id就消失了,再次連接到服務(wù)器時(shí)也就無法找到原來的session。
如果服務(wù)器設(shè)置的cookie被保存到硬盤上,或者使用某種手段改寫瀏覽器發(fā)出的HTTP請求報(bào)頭,把原來的session id發(fā)送到服務(wù)器,則再次打開瀏覽器仍然能夠找到原來的session。
恰恰是由于關(guān)閉瀏覽器不會(huì)導(dǎo)致session被刪除,迫使服務(wù)器為session設(shè)置了一個(gè)失效時(shí)間,當(dāng)距離客戶上一次使用session的時(shí)間超過了這個(gè)失效時(shí)間時(shí),服務(wù)器就可以認(rèn)為客戶端已經(jīng)停止了活動(dòng),才會(huì)把session刪除以節(jié)省存儲(chǔ)空間。
  由此我們可以得出如下結(jié)論:
  關(guān)閉瀏覽器,只會(huì)是瀏覽器端內(nèi)存里的session cookie消失,但不會(huì)使保存在服務(wù)器端的session對象消失,同樣也不會(huì)使已經(jīng)保存到硬盤上的持久化cookie消失。
*************************************************************************************


二十七、打開兩個(gè)瀏覽器窗口訪問應(yīng)用程序會(huì)使用同一個(gè)session還是不同的session
*************************************************************************************
通常session cookie是不能跨窗口使用的,當(dāng)你新開了一個(gè)瀏覽器窗口進(jìn)入相同頁面時(shí),系統(tǒng)會(huì)賦予你一個(gè)新的session id,這樣我們信息共享的目的就達(dá)不到了。
此時(shí)我們可以先把session id保存在persistent cookie中(通過設(shè)置session的最大有效時(shí)間),然后在新窗口中讀出來,就可以得到上一個(gè)窗口的session id了,這樣通過session cookie和persistent cookie的結(jié)合我們就可以實(shí)現(xiàn)了跨窗口的會(huì)話跟蹤。
*************************************************************************************

二十八、如何使用會(huì)話顯示每個(gè)客戶的訪問次數(shù)
*************************************************************************************
由于客戶的訪問次數(shù)是一個(gè)整型的變量,但session的屬性類型中不能使用int,double,boolean等基本類型的變量,所以我們要用到這些基本類型的封裝類型對象作為session對象中屬性的值
  但像Integer是一種不可修改(Immutable)的數(shù)據(jù)結(jié)構(gòu):構(gòu)建后就不能更改。這意味著每個(gè)請求都必須創(chuàng)建新的Integer對象,之后使用setAttribute來代替之前存在的老的屬性的值。例如:
HttpSession session = request.getSession();
SomeImmutalbeClass value = (SomeImmutableClass)session.getAttribute(“SomeIdentifier”);
if (value= =null){
    value = new SomeImmutableClass(…); // 新創(chuàng)建一個(gè)不可更改對象
}else{
    value = new SomeImmutableClass(calculatedFrom(value)); // 對value重新計(jì)算后創(chuàng)建新的對象
}
session.setAttribute(“someIdentifier”,value); // 使用新創(chuàng)建的對象覆蓋原來的老的對象
*************************************************************************************

二十九、如何使用會(huì)話累計(jì)用戶的數(shù)據(jù)
*************************************************************************************
使用可變的數(shù)據(jù)結(jié)構(gòu),比如數(shù)組、List、Map或含有可寫字段的應(yīng)用程序?qū)S械臄?shù)據(jù)結(jié)構(gòu)。通過這種方式,除非首次分配對象,否則不需要調(diào)用setAttribute。例如

HttpSession session = request.getSession();
SomeMutableClass value = (SomeMutableClass)session.getAttribute(“someIdentifier”);
if(value = = null){
    value = new SomeMutableClass(…);
    session.setAttribute(“someIdentifier”,value);
}else{
    value.updateInternalAttribute(…);     // 如果已經(jīng)存在該對象則更新其屬性而不需重新設(shè)置屬性
}
*************************************************************************************

三十、不可更改對象和可更改對象在會(huì)話數(shù)據(jù)更新時(shí)的不同處理
*************************************************************************************
不可更改對象因?yàn)橐坏﹦?chuàng)建之后就不能更改,所以每次要修改會(huì)話中屬性的值的時(shí)候,都需要
調(diào)用setAttribute(“someIdentifier”,newValue)來代替原有的屬性的值,否則屬性的值不會(huì)被更新
可更改對象因?yàn)槠渥陨硪话闾峁┝诵薷淖陨韺傩缘姆椒?,所以每次要修改?huì)話中屬性的值的時(shí)
候,只要調(diào)用該可更改對象的相關(guān)修改自身屬性的方法就可以了。這意味著我們就不需要調(diào)
用setAttribute方法了
*************************************************************************************



agun 2010-12-04 12:14 發(fā)表評論
]]>
spring 常識2http://www.aygfsteel.com/agun/archive/2010/12/04/339788.htmlagunagunSat, 04 Dec 2010 03:52:00 GMThttp://www.aygfsteel.com/agun/archive/2010/12/04/339788.htmlhttp://www.aygfsteel.com/agun/comments/339788.htmlhttp://www.aygfsteel.com/agun/archive/2010/12/04/339788.html#Feedback0http://www.aygfsteel.com/agun/comments/commentRss/339788.htmlhttp://www.aygfsteel.com/agun/services/trackbacks/339788.html1, Spring bean 定義

spring bean 定義可能包含大量的配置信息,包括容器相關(guān)的信息(比如初始化方法,靜態(tài)工廠方法

等)、構(gòu)造函數(shù)參數(shù)、屬性等。如果兩個(gè)bean之間的配置信息大同小異,可采用bean的繼承來減少重

復(fù)配置工作。子bean定義可以從父bean定義繼承部分配置。它也可覆蓋一些配置,或者添加一些配置

。使用繼承配置可以節(jié)省很多輸入工作,實(shí)際上就是一種模板形式。

spring中事務(wù)配置中就有這樣例子,為了使用事務(wù)只要父配置了事務(wù)代理就可以了,所有需要事務(wù)的

bean只要繼承父就可以了。說到這個(gè)就在多說幾句,父bean通常不需要實(shí)例化的,而僅僅作為子bean

定的的模板使用;而ApplicationContext默認(rèn)預(yù)初始化所有的singleton bean。為了阻止父bean被預(yù)

初始化,可以使用abstract屬性設(shè)置父bean為抽象bean。容器會(huì)忽略所有的抽象bean定義,預(yù)初始化

時(shí)不初始化抽象bean。

 

2, spring 事務(wù)管理

傳統(tǒng)的J2EE開發(fā)者對事務(wù)管理可能采用兩種策略

(1),全局事務(wù):全局事務(wù)通常由應(yīng)用服務(wù)器管理,使用JTA。全局事務(wù)可跨越多個(gè)事務(wù)性的資源,保證

在多個(gè)事務(wù)性資源間跨越時(shí)資源一致性。
(2),局部事務(wù):局部事務(wù)和特定資源相關(guān),如,一個(gè)和JDBC鏈接關(guān)聯(lián)的事務(wù)。該事務(wù)盡能保證對該

JDBC連接數(shù)據(jù)庫的一致性,對局部事務(wù),應(yīng)用服務(wù)器不需要參與事務(wù)管理,不能保證跨越多個(gè)資源的

事務(wù)正確性。

 

3,編程式事務(wù)

Spring 提供兩種編程式的事務(wù)管理

 

(1)使用TransactionTemplate事務(wù)管理

(2)直接使用一個(gè)PlatformTransactionManager實(shí)現(xiàn)類管理事務(wù)。

 

兩種編程式的事務(wù)都不需要與特定的事務(wù)API耦合,第一種更符合Spring模板式的編程模型,因此通常推薦采用第一種方式,第二種非常類似于JTA的UserTransaction的API編程,區(qū)別是減少了異常處理。

 

 

 

4,聲明式事務(wù)

Spring的聲明式事務(wù)是通過面向切面(AOP)實(shí)現(xiàn)。

(1)使用聲明式事務(wù)管理

通常,通過TransactionPoxyFactoryBean為目標(biāo)Bean生成Spring事務(wù)代理。當(dāng)bean實(shí)例的方法需要事務(wù)管理時(shí),采用TransactionPoxyFactoryBean來自目標(biāo)bean生成事務(wù)代理。每個(gè)TransactionPoxyFactoryBean為一個(gè)具體的目標(biāo)bean生成代理對象,代理對象的方法改寫了目標(biāo)bean的方法,就是在目標(biāo)bean的方法執(zhí)行之前加入開始事務(wù),在目標(biāo)bean方法結(jié)束之后提交事務(wù),遇到指定異?;貪L事務(wù)

 

    定義事務(wù)代理bean模板

Xml代碼 復(fù)制代碼
  1. <bean id="txProxyTemplate" abstract="true"  
  2.     class="<SPAN style="COLOR: #ff0000">org.springframework.transaction.interceptor.TransactionProxyFactoryBean</SPAN>">  
  3.     <property name="transactionManager">  
  4.         <ref bean="transactionManager" />  
  5.     </property>  
  6.     <property name="transactionAttributes">  
  7.         <props>  
  8.             <prop key="trans_*">PROPAGATION_REQUIRED</prop>  
  9.             <prop key="query*">  
  10.                 PROPAGATION_REQUIRED,readOnly,-Exception   
  11.             </prop>  
  12.             <prop key="find*">  
  13.                 PROPAGATION_REQUIRED,readOnly,-Exception   
  14.             </prop>  
  15.             <prop key="load*">  
  16.                 PROPAGATION_REQUIRED,readOnly,-Exception   
  17.             </prop>  
  18.             <prop key="*">PROPAGATION_REQUIRED,-Exception</prop>  
  19.         </props>  
  20.     </property>  
  21. </bean>  

 

 

(2)根據(jù)BeanName自動(dòng)創(chuàng)建事務(wù)代理

如果同一個(gè)應(yīng)用中有很多目標(biāo)bean需要生成事務(wù)代理,當(dāng)然可以為每個(gè)目標(biāo)bean額外配置一個(gè)TransactionPoxyFactoryBean bean.這樣做的缺點(diǎn)是,配置文件相當(dāng)臃腫而且難以維護(hù),此時(shí)可以考慮使用自動(dòng)事務(wù)代理。自動(dòng)事務(wù)代理的思路是,當(dāng)ApplicationContext初始化完成后,由上下文中的某個(gè)bean"后處理"每個(gè)目標(biāo)bean,為這些目標(biāo)bean生成事務(wù)代理。

能為目標(biāo)bean執(zhí)行"后處理"的bean必須實(shí)現(xiàn)BeanFactoryPostProcessor接口,ApplicationContext完成初始化后,會(huì)自動(dòng)初始化所有實(shí)現(xiàn)BeanFactoryPostProcessor接口的bean,并且讓它“后處理”其他bean.Spring提供BeanFactoryPostProcessor的實(shí)現(xiàn)類BeanNameAutoPoxyCreator,BeanNameAutoPoxyCreator可以用來處理ApplicationContext中其他bean,方法是通過名稱來識別,并且把他們用事務(wù)代理包裝起來。BeanNameAutoPoxyCreator生成的事務(wù)代理,和使用TransactionPoxyFactoryBean生成的事務(wù)代理基本一致。

 

    定義事務(wù)攔截bean

Xml代碼 復(fù)制代碼
  1.  <bean id="transactionInterceptor"  
  2.   class="<SPAN style="COLOR: #ff0000">org.springframework.transaction.interceptor.TransactionInterceptor</SPAN>">  
  3.   <property name="transactionManager" ref="TransactionManager" />  
  4.      
  5.   <property name="transactionAttributes">  
  6.    <props>  
  7.     <prop key="create*">  
  8.      PROPAGATION_REQUIRED,-Exception   
  9.     </prop>  
  10.     <prop key="delete*">  
  11.      PROPAGATION_REQUIRED,-Exception   
  12.     </prop>    
  13.     <prop key="update*">  
  14.      PROPAGATION_REQUIRED,-Exception   
  15.     </prop>           
  16.     <prop key="get*">PROPAGATION_REQUIRED</prop>  
  17.    </props>  
  18.   </property>  
  19.  </bean>  
Xml代碼 復(fù)制代碼
  1.  <bean  
  2.   class="<SPAN style="COLOR: #ff0000">org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator</SPAN>">  
  3.   <property name="beanNames">  
  4.    <value>*Service</value>  
  5.   </property>  
  6.   <property name="interceptorNames">  
  7.    <list>  
  8.     <value>transactionInterceptor</value>  
  9.    </list>  
  10.   </property>  
  11.  </bean>   

 

次配置關(guān)鍵在兩個(gè)bean

TransactionInterceptor

BeanNameAutoProxyCreator

 

(3)基于注釋式事務(wù)代理配置



agun 2010-12-04 11:52 發(fā)表評論
]]>
spring 常識1http://www.aygfsteel.com/agun/archive/2010/12/04/339787.htmlagunagunSat, 04 Dec 2010 03:50:00 GMThttp://www.aygfsteel.com/agun/archive/2010/12/04/339787.htmlhttp://www.aygfsteel.com/agun/comments/339787.htmlhttp://www.aygfsteel.com/agun/archive/2010/12/04/339787.html#Feedback0http://www.aygfsteel.com/agun/comments/commentRss/339787.htmlhttp://www.aygfsteel.com/agun/services/trackbacks/339787.html1,實(shí)例化bean
就Spring IoC容器而言,bean定義基本上描述了創(chuàng)建一個(gè)或多個(gè)實(shí)際bean對象的內(nèi)容。當(dāng)需要的時(shí)候,容器會(huì)從bean定義列表中取得一個(gè)指定的bean定義,并根據(jù)bean定義里面的配置元數(shù)據(jù)使用反射機(jī)制來創(chuàng)建一個(gè)實(shí)際的對象。因此這一節(jié)將講解如何告知Spring IoC容器我們將要實(shí)例化的對象的類型以及如何實(shí)例化對象。

當(dāng)采用XML描述配置元數(shù)據(jù)時(shí),將通過<bean/>元素的class屬性來指定實(shí)例化對象的類型。class 屬性 (對應(yīng)BeanDefinition實(shí)例的Class屬性)通常是必須的(不過也有兩種例外的情形,“使用實(shí)例工廠方法實(shí)例化”和“bean定義的繼承”)。class屬性主要有兩種用途:在大多數(shù)情況下,容器將直接通過反射調(diào)用指定類的構(gòu)造器來創(chuàng)建bean(這有點(diǎn)等類似于在Java代碼中使用new操作符);在極少數(shù)情況下,容器將調(diào)用類的靜態(tài)工廠方法來創(chuàng)建bean實(shí)例,class屬性將用來指定實(shí)際具有靜態(tài)工廠方法的類(至于調(diào)用靜態(tài)工廠方法創(chuàng)建的對象類型是當(dāng)前class還是其他的class則無關(guān)緊要)。

2, 延遲初始化bean
ApplicationContext實(shí)現(xiàn)的默認(rèn)行為就是在啟動(dòng)時(shí)將所有singleton bean提前進(jìn)行實(shí)例化。提前實(shí)例化意味著作為初始化過程的一部分,ApplicationContext實(shí)例會(huì)創(chuàng)建并配置所有的singleton bean。通常情況下這是件好事,因?yàn)檫@樣在配置中的任何錯(cuò)誤就會(huì)即刻被發(fā)現(xiàn)(否則的話可能要花幾個(gè)小時(shí)甚至幾天)。

有時(shí)候這種默認(rèn)處理可能并不是你想要的。如果你不想讓一個(gè)singleton bean在ApplicationContext實(shí)現(xiàn)在初始化時(shí)被提前實(shí)例化,那么可以將bean設(shè)置為延遲實(shí)例化。一個(gè)延遲初始化bean將告訴IoC 容器是在啟動(dòng)時(shí)還是在第一次被用到時(shí)實(shí)例化。

在XML配置文件中,延遲初始化將通過<bean/>元素中的lazy-init屬性來進(jìn)行控制。例如:

<bean id="lazy" class="com.foo.ExpensiveToCreateBean" lazy-init="true">
    <!-- various properties here... -->
</bean>
  <bean name="not.lazy" class="com.foo.AnotherBean">
    <!-- various properties here... -->
</bean>
當(dāng)ApplicationContext實(shí)現(xiàn)加載上述配置時(shí),設(shè)置為lazy的bean將不會(huì)在ApplicationContext啟動(dòng)時(shí)提前被實(shí)例化,而not.lazy卻會(huì)被提前實(shí)例化。

需要說明的是,如果一個(gè)bean被設(shè)置為延遲初始化,而另一個(gè)非延遲初始化的singleton bean依賴于它,那么當(dāng)ApplicationContext提前實(shí)例化singleton bean時(shí),它必須也確保所有上述singleton 依賴bean也被預(yù)先初始化,當(dāng)然也包括設(shè)置為延遲實(shí)例化的bean。因此,如果Ioc容器在啟動(dòng)的時(shí)候創(chuàng)建了那些設(shè)置為延遲實(shí)例化的bean的實(shí)例,你也不要覺得奇怪,因?yàn)槟切┭舆t初始化的bean可能在配置的某個(gè)地方被注入到了一個(gè)非延遲初始化singleton bean里面。

在容器層次中通過在<beans/>元素上使用'default-lazy-init'屬性來控制延遲初始化也是可能的。如下面的配置:
<beans default-lazy-init="true">
    <!-- no beans will be eagerly pre-instantiated... -->
</beans>


3,自動(dòng)裝配(autowire)協(xié)作者
Spring IoC容器可以自動(dòng)裝配(autowire)相互協(xié)作bean之間的關(guān)聯(lián)關(guān)系。因此,如果可能的話,可以自動(dòng)讓Spring通過檢查BeanFactory中的內(nèi)容,來替我們指定bean的協(xié)作者(其他被依賴的bean)。由于autowire可以針對單個(gè)bean進(jìn)行設(shè)置,因此可以讓有些bean使用autowire,有些bean不采用。autowire的方便之處在減少或者消除屬性或構(gòu)造器參數(shù)的設(shè)置,這樣可以給我們的配置文件減減肥![2] 在xml配置文件中,autowire一共有五種類型,可以在<bean/>元素中使用autowire屬性指定:

Table 3.2. Autowiring modes

模式 說明

    no 不使用自動(dòng)裝配。必須通過ref元素指定依賴,這是默認(rèn)設(shè)置。由于顯式指定協(xié)作者可以使配置更靈活、更清晰,因此對于較大的部署配置,推薦采用該設(shè)置。而且在某種程度上,它也是系統(tǒng)架構(gòu)的一種文檔形式。
 
    byName 根據(jù)屬性名自動(dòng)裝配。此選項(xiàng)將檢查容器并根據(jù)名字查找與屬性完全一致的bean,并將其與屬性自動(dòng)裝配。例如,在bean定義中將autowire設(shè)置為by name,而該bean包含master屬性(同時(shí)提供setMaster(..)方法),Spring就會(huì)查找名為master的bean定義,并用它來裝配給master屬性。
 
    byType 如果容器中存在一個(gè)與指定屬性類型相同的bean,那么將與該屬性自動(dòng)裝配。如果存在多個(gè)該類型的bean,那么將會(huì)拋出異常,并指出不能使用byType方式進(jìn)行自動(dòng)裝配。若沒有找到相匹配的bean,則什么事都不發(fā)生,屬性也不會(huì)被設(shè)置。如果你不希望這樣,那么可以通過設(shè)置dependency-check="objects"讓Spring拋出異常。
 
    constructor 與byType的方式類似,不同之處在于它應(yīng)用于構(gòu)造器參數(shù)。如果在容器中沒有找到與構(gòu)造器參數(shù)類型一致的bean,那么將會(huì)拋出異常。
 
    autodetect 通過bean類的自省機(jī)制(introspection)來決定是使用constructor還是byType方式進(jìn)行自動(dòng)裝配。如果發(fā)現(xiàn)默認(rèn)的構(gòu)造器,那么將使用byType方式。
 

如果直接使用property和constructor-arg注入依賴的話,那么將總是覆蓋自動(dòng)裝配。而且目前也不支持簡單類型的自動(dòng)裝配,這里所說的簡單類型包括基本類型、String、Class以及簡單類型的數(shù)組(這一點(diǎn)已經(jīng)被設(shè)計(jì),將考慮作為一個(gè)功能提供)。自動(dòng)裝配還可以與依賴檢查結(jié)合使用,這樣依賴檢查將在自動(dòng)裝配完成之后被執(zhí)行。

理解自動(dòng)裝配的優(yōu)缺點(diǎn)是很重要的。其中優(yōu)點(diǎn)包括:

自動(dòng)裝配能顯著減少配置的數(shù)量。不過,采用bean模板(見這里)也可以達(dá)到同樣的目的。

自動(dòng)裝配可以使配置與java代碼同步更新。例如,如果你需要給一個(gè)java類增加一個(gè)依賴,那么該依賴將被自動(dòng)實(shí)現(xiàn)而不需要修改配置。因此強(qiáng)烈推薦在開發(fā)過程中采用自動(dòng)裝配,而在系統(tǒng)趨于穩(wěn)定的時(shí)候改為顯式裝配的方式。

自動(dòng)裝配的一些缺點(diǎn):

盡管自動(dòng)裝配比顯式裝配更神奇,但是,正如上面所提到的,Spring會(huì)盡量避免在裝配不明確的時(shí)候進(jìn)行猜測,因?yàn)檠b配不明確可能出現(xiàn)難以預(yù)料的結(jié)果,而且Spring所管理的對象之間的關(guān)聯(lián)關(guān)系也不再能清晰的進(jìn)行文檔化。

對于那些根據(jù)Spring配置文件生成文檔的工具來說,自動(dòng)裝配將會(huì)使這些工具沒法生成依賴信息。

如果采用by type方式自動(dòng)裝配,那么容器中類型與自動(dòng)裝配bean的屬性或者構(gòu)造函數(shù)參數(shù)類型一致的bean只能有一個(gè),如果配置可能存在多個(gè)這樣的bean,那么就要考慮采用顯式裝配了。

盡管使用autowire沒有對錯(cuò)之分,但是能在一個(gè)項(xiàng)目中保持一定程度的一致性是最好的做法。例如,通常情況下如果沒有使用自動(dòng)裝配,那么僅自動(dòng)裝配一個(gè)或兩個(gè)bean定義可能會(huì)引起開發(fā)者的混淆。



agun 2010-12-04 11:50 發(fā)表評論
]]>
Ehcache分布式緩存http://www.aygfsteel.com/agun/archive/2010/12/04/339786.htmlagunagunSat, 04 Dec 2010 03:49:00 GMThttp://www.aygfsteel.com/agun/archive/2010/12/04/339786.htmlhttp://www.aygfsteel.com/agun/comments/339786.htmlhttp://www.aygfsteel.com/agun/archive/2010/12/04/339786.html#Feedback0http://www.aygfsteel.com/agun/comments/commentRss/339786.htmlhttp://www.aygfsteel.com/agun/services/trackbacks/339786.htmlEhcache分布式緩存也是我一直比較較關(guān)注的,以前用過oscache的分布式緩存。在網(wǎng)上看到了相關(guān)文章記錄下來。

 

Ehcache支持的分布式緩存支持有三種RMI,JGroups,JMS

 

這里介紹下MRI和JGrpups兩種方式,Ehcache使用版本為1.5.0,關(guān)于ehcache的其他信息請參考http://ehcache.sourceforge.net/EhcacheUserGuide.html,關(guān)于jgroups的信息請參考http://www.jgroups.org/manual/html_single/index.html。

 

原始文章 http://www.javaeye.com/topic/335623



agun 2010-12-04 11:49 發(fā)表評論
]]>
Ehcache緩存配置http://www.aygfsteel.com/agun/archive/2010/12/04/339785.htmlagunagunSat, 04 Dec 2010 03:46:00 GMThttp://www.aygfsteel.com/agun/archive/2010/12/04/339785.htmlhttp://www.aygfsteel.com/agun/comments/339785.htmlhttp://www.aygfsteel.com/agun/archive/2010/12/04/339785.html#Feedback0http://www.aygfsteel.com/agun/comments/commentRss/339785.htmlhttp://www.aygfsteel.com/agun/services/trackbacks/339785.html閱讀全文

agun 2010-12-04 11:46 發(fā)表評論
]]>
Web Serviceshttp://www.aygfsteel.com/agun/archive/2010/12/04/339784.htmlagunagunSat, 04 Dec 2010 03:45:00 GMThttp://www.aygfsteel.com/agun/archive/2010/12/04/339784.htmlhttp://www.aygfsteel.com/agun/comments/339784.htmlhttp://www.aygfsteel.com/agun/archive/2010/12/04/339784.html#Feedback0http://www.aygfsteel.com/agun/comments/commentRss/339784.htmlhttp://www.aygfsteel.com/agun/services/trackbacks/339784.htmlweb 服務(wù)是通過標(biāo)準(zhǔn)的web協(xié)議可以訪問的一個(gè)應(yīng)用程序組件。

它是一種可以接收從internet 或者internet 上的其他系統(tǒng)傳遞過來的請求的輕量級獨(dú)立的通信技術(shù)。這種技術(shù)允許網(wǎng)絡(luò)上的所有系統(tǒng)進(jìn)行交互。

 

j2ee平臺是圍繞web服務(wù)來構(gòu)架的,其中的技術(shù)和web服務(wù)相關(guān)的有JAX-RCP 、Web Service、SAAJ 、JAXR 、EJB 、JAC 等,其中Web Services for J2EE 是WEB服務(wù)總框架,JAX-RCP是J2EE的WEB服務(wù)的核心技術(shù),SAAJ為處理帶附件的SOAP消息提供了JAVA編程API.

 

在J2EE平臺中,要開發(fā)WEB服務(wù)可以使用兩種技術(shù),一種基于XML遠(yuǎn)程調(diào)用的技術(shù)-JAX-RCP,另外一個(gè)基于XML的消息發(fā)送技術(shù)-JAXM.

 

這里主要針對JAX-RCP 詳細(xì)說一下。

 

JAX-RCP( JAVA API FOR XMLBASED RCP) 是一種遠(yuǎn)程方法調(diào)用(或者說遠(yuǎn)程過程調(diào)用),那么它和其他遠(yuǎn)程方法調(diào)用(RPC,COM,CORBA RMI)有什么區(qū)別呢

 

綜合比較長遠(yuǎn)的遠(yuǎn)程方法調(diào)用技術(shù),他們有以下共性。

 

1,在客戶端和服務(wù)端有通用的編程接口。

 

2,在客戶端STUB,在服務(wù)端有SKELETON.

 

3,客戶端和服務(wù)端有專門的協(xié)議進(jìn)行數(shù)據(jù)傳輸。

 

對于通用接口的描述,比如CORBA 有IDL OF CORBA ,JAVA RMI 有JAVA RMI INTERFACE IN RMI ,對于基于XML的RPC 來說,IDL 就是WSDL。那么對于XML-RPC來說,這個(gè)結(jié)構(gòu)中“傳輸協(xié)議”當(dāng)然是SAOP,SOAP消息是將以傳輸文本為基礎(chǔ)的協(xié)議(HTTP,SMTP FTP)作為載體來使用的。也就是說,SOAP消息的傳輸建立在HTTP SMTP FTP之上。

 

 JAX-RCP的客戶端調(diào)用方法:

 

1,基于STUB

2,動(dòng)態(tài)代理

3,動(dòng)態(tài)調(diào)用



agun 2010-12-04 11:45 發(fā)表評論
]]>
主站蜘蛛池模板: 阿图什市| 岳西县| 巴中市| 博白县| 新疆| 肥乡县| 菏泽市| 蓝田县| 泾源县| 东乡族自治县| 沂南县| 上犹县| 高尔夫| 石泉县| 大余县| 彰化县| 沁阳市| 朝阳区| 连城县| 沁源县| 弥渡县| 兖州市| 台中县| 鹰潭市| 汝南县| 石泉县| 昌江| 垣曲县| 江都市| 嘉禾县| 惠来县| 天柱县| 营山县| 巴塘县| 洪雅县| 伊川县| 杭锦后旗| 宁河县| 西安市| 桐柏县| 本溪市|