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

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

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

    posts - 193,  comments - 520,  trackbacks - 0

    原文作者: 陳亞強(qiáng)

    原文鏈接:http://www.ibm.com/developerworks/cn/webservices/ws-handler/index.html
    高級軟件工程師北京華園天一科技有限公司 2003  8  

    一、Handler的基本概念

    J2EE Web 
    服務(wù)中的Handler技術(shù)特點(diǎn)非常像Servlet技術(shù)中的Filter。我們知道,在Servlet中,當(dāng)一個(gè)HTTP到達(dá)服務(wù)端時(shí),往往要經(jīng)過多個(gè)Filter對請求進(jìn)行過濾,然后才到達(dá)提供服務(wù)的Servlet,這些Filter的功能往往是對請求進(jìn)行統(tǒng)一編碼,對用戶進(jìn)行認(rèn)證,把用戶的訪問寫入系統(tǒng)日志等。相應(yīng)的,Web服務(wù)中的Handler通常也提供一下的功能: 

    對客戶端進(jìn)行認(rèn)證、授權(quán); 
    把用戶的訪問寫入系統(tǒng)日志; 
    對請求的SOAP消息進(jìn)行加密,解密; 
    Web Services對象做緩存。 
    SOAP
    消息Handler能夠訪問代表RPC請求或者響應(yīng)的SOAP消息。在JAX-RPC技術(shù)中,SOAP消息Handler可以部署在服務(wù)端,也可以在客戶端使用。 

    下面我們來看一個(gè)典型的SOAP消息Handler處理順序: 
    某個(gè)在線支付服務(wù)需要防止非授權(quán)的用戶訪問或者撰改服務(wù)端和客戶端傳輸?shù)男畔?,從而使用消息摘要?/span>Message Digest)的方法對請求和響應(yīng)的SOAP消息進(jìn)行加密。當(dāng)客戶端發(fā)送SOAP?Ф?andler把請求消息中的某些敏感的信息(如信用卡密碼)進(jìn)行加密,然后把加密后的SOAP消息傳輸?shù)椒?wù)端;服務(wù)端的SOAP消息Handler截取客戶端的請求,把請求的SOAP 消息進(jìn)行解密,然后把解密后的SOAP消息派發(fā)到目標(biāo)的Web服務(wù)端點(diǎn)。 

    Apache axis
    是我們當(dāng)前開發(fā)Web服務(wù)的較好的選擇,使用axisWeb服務(wù)開發(fā)工具,可以使用Handler來對服務(wù)端的請求和響應(yīng)進(jìn)行處理。典型的情況下,請求傳遞如圖1所示。 



    1 SOAP消息的傳遞順序


    在圖中,軸心點(diǎn)(pivot point)是Apache與提供程序功能相當(dāng)?shù)牟糠?,通過它來和目標(biāo)的Web服務(wù)進(jìn)行交互,它通常稱為Provider。axis中常用的ProviderJavaRPC,javaMSG,javaEJB。一個(gè)Web服務(wù)可以部署一個(gè)或者多個(gè)Handler 

    Apache axis
    中的Handler體系結(jié)構(gòu)和JAX-RPC 1.0JSR101)中的體系結(jié)構(gòu)稍有不同,需要聲明的是,本文的代碼在axis中開發(fā),故需要在axis環(huán)境下運(yùn)行。 

    axis環(huán)境下,SOAP消息Handler必須實(shí)現(xiàn)org.apache.axis.Handler接口(在JAX-RPC 1.0規(guī)范中,SOAP消息Handler必須實(shí)現(xiàn)javax.xml.rpc.handler.Handler接口),org.apache.axis.Handler接口的部分代碼如下: 

    例程1 org.apache.axis.Handle的部分代碼

    public interface Handler extends Serializable {
        
    public void init();  
        
    public void cleanup();
        
    public void invoke(MessageContext msgContext) throws AxisFault ;

        
    public void onFault(MessageContext msgContext);
        
    public void setOption(String name, Object value);    
        
    public Object getOption(String name);
       
        
    public void setName(String name);   
        
    public String getName();     
        
    public Element getDeploymentData(Document doc);
        
    public void generateWSDL(MessageContext msgContext) throws AxisFault;
       …
    }

     
    為了提供開發(fā)的方便,在編寫Handler時(shí),只要繼承org.apache.axis.handlers. BasicHandler即可,BasicHandlerHandler的一個(gè)模板,我們看它的部分代碼: 

    例程2 BasicHandler的部分代碼

    public abstract class BasicHandler implements Handler {
        
    protected static Log log =
            LogFactory.getLog(BasicHandler.
    class.getName());
        
    protected Hashtable options;
        
    protected String name;
        
    //這個(gè)方法必須在Handler中實(shí)現(xiàn)。
    public abstract void invoke(MessageContext msgContext) throws AxisFault;
    public void setOption(String name, Object value) {
            
    if ( options == null ) initHashtable();
            options.put( name, value );
        }

    }
     

    BasicHandler
    中的(MessageContext msgContext)方法是Handler實(shí)現(xiàn)類必須實(shí)現(xiàn)的方法,它通過MessageContext來獲得請求或者響應(yīng)的SOAPMessage對象,然后對SOAPMessage進(jìn)行處理。 

    在介紹Handler的開發(fā)之前,我們先來看一下目標(biāo)Web服務(wù)的端點(diǎn)實(shí)現(xiàn)類的代碼,如例程3所示。 

    例程目標(biāo)Web服務(wù)的端點(diǎn)實(shí)現(xiàn)類

    package com.hellking.webservice;
    public class HandleredService 
    {
     
    //一個(gè)簡單的Web服務(wù)
     public String publicMethod(String name)
     {
      
    return "Hello!"+name;
     }
    }
    //另一個(gè)Web服務(wù)端點(diǎn):
    package com.hellking.webservice;
    public class OrderService 
    {
           
    //web服務(wù)方法:獲得客戶端的訂單信息,并且對訂單信息進(jìn)行對應(yīng)的處理,
    通常情況是把訂單的信息寫入數(shù)據(jù)庫,然后可客戶端返回確認(rèn)信息。
     
    public String orderProduct(String name,String address,String item,int quantity,Card card)
     {
      String cardId
    =card.getCardId();
      String cardType
    =card.getCardType();
      String password
    =card.getPassword();
      String rderInfo
    ="name="+name+",address="+address+",item="+item+",quantity="+quantity+"
    ,cardId="+cardId+",cardType="+cardType+",password="+password;
      System.out.println("這里是客戶端發(fā)送來的信息:");
      System.out.println(orderInfo);  
      
    return orderInfo;
     } 
    }

     
    二、下面我們分不同情況討論Handler的使用實(shí)例。

    使用Handler為系統(tǒng)做日志

    Handler
    為系統(tǒng)做日志是一種比較常見而且簡單的使用方式。和Servlet中的Filter一樣,我們可以使用Handler來把用戶的訪問寫入系統(tǒng)日志。下面我們來看日志Handler的具體代碼,如例程4所示。 

    例程4 LogHandler的代碼

    package com.hellking.webservice;

    import java.io.FileOutputStream;
    import java.io.PrintWriter;
    import java.util.Date;

    import org.apache.axis.AxisFault;
    import org.apache.axis.Handler;
    import org.apache.axis.MessageContext;
    import org.apache.axis.handlers.BasicHandler;

    public class LogHandler extends BasicHandler {
      
       
    /**invoke,每一個(gè)handler都必須實(shí)現(xiàn)的方法。
      
    */
        
    public void invoke(MessageContext msgContext) throws AxisFault
        {
           
    //每當(dāng)web服務(wù)被調(diào)用,都記錄到log中。
            try {
                Handler handler 
    = msgContext.getService();
                String filename 
    = (String)getOption("filename");
                
    if ((filename == null|| (filename.equals("")))
                    
    throw new AxisFault("Server.NoLogFile",
                                     
    "No log file configured for the LogHandler!",
                                        
    nullnull);
                FileOutputStream fos 
    = new FileOutputStream(filename, true);            
                PrintWriter writer 
    = new PrintWriter(fos);            
                Integer counter 
    = (Integer)handler.getOption("accesses");
                
    if (counter == null)
                    counter 
    = new Integer(0);
                
                counter 
    = new Integer(counter.intValue() + 1);            
                Date date 
    = new Date();
                msgContext.getMessage().writeTo(System.out);
               
                String result 
    = ""+date + ": Web 服務(wù) " +
                                msgContext.getTargetService() 
    +
                                
    " 被調(diào)用,現(xiàn)在已經(jīng)共調(diào)用了 " + counter + " 次.";
                handler.setOption(
    "accesses", counter);            
                writer.println(result);            
                writer.close();
            } 
    catch (Exception e) {
                
    throw AxisFault.makeFault(e);
            }
        }
    }
     

    前面我們說過,Handler實(shí)現(xiàn)類必須實(shí)現(xiàn)invoke方法,invoke方法是Handler處理其業(yè)務(wù)的入口點(diǎn)。LogHandler的主要功能是把客戶端訪問的Web服務(wù)的名稱和訪問時(shí)間、訪問的次數(shù)記錄到一個(gè)日志文件中。 

    下面部署這個(gè)前面開發(fā)的Web服務(wù)對像,然后為Web服務(wù)指定Handler。編輯Axis_Home/WEB-INF/ server-config.wsdd文件,在其中加入以下的內(nèi)容:
    <service name="HandleredService" provider="java:RPC">
      
    <parameter name="allowedMethods" value="*"/>
      
    <parameter name="className" value="com.hellking.webservice.HandleredService"/>
      
    <parameter name="allowedRoles" value="chen"/>
      
    <beanMapping languageSpecificType="java:com.hellking.webservice.Card"
     qname
    ="card:card" xmlns:card="card"/>
      
    <requestFlow>
    <handler name="logging" type="java:com.hellking.webservice.LogHandler">
      
    <parameter name="filename" value="c:\\MyService.log"/>
     
    </handler>
      
    </requestFlow>
     
    </service>

     



    </globalConfiguration>

      
    <handler name="logging" type="java:com.hellking.webservice.LogHandler">
      
    <parameter name="filename" value="c:\\MyService.log"/>
     
    </handler>

    <service name="HandleredService" provider="java:RPC">

      
    <requestFlow>
      
    <handler type="logging"/>
       …
    <!--在這里可以指定多個(gè)Handler-->
      
    </requestFlow>
     
    </service>


    http://127.0.0.1:8080/handler/services/HandleredService?wsdl&method=publicMethod&name=chen
    注意:這個(gè)URL需要根據(jù)具體情況改變。
    Sun Jul 06 22:42:03 CST 2003: Web 服務(wù) HandleredService 被調(diào)用,現(xiàn)在已經(jīng)共調(diào)用了 1 .
    Sun Jul 06 22:42:06 CST 2003: Web 服務(wù) HandleredService 被調(diào)用,現(xiàn)在已經(jīng)共調(diào)用了 2 .
    Sun Jul 06 22:42:13 CST 2003: Web 服務(wù) HandleredService 被調(diào)用,現(xiàn)在已經(jīng)共調(diào)用了 3 .

    使用Handler對用戶的訪問認(rèn)證

    使用Handler為用戶訪問認(rèn)證也是它的典型使用,通過它,可以減少在Web服務(wù)端代碼中認(rèn)證的麻煩,同時(shí)可以在部署描述符中靈活改變用戶的訪問權(quán)限。 

    對用戶認(rèn)證的Handler代碼如下:

    例程認(rèn)證的Handler
    package com.hellking.webservice;
    import….

    //此handler的目的是對用戶認(rèn)證,只有認(rèn)證的用戶才能訪問目標(biāo)服務(wù)。
    public class AuthenticationHandler extends BasicHandler
    {
     
    /**invoke,每一個(gè)handler都必須實(shí)現(xiàn)的方法。
      
    */
     
    public void invoke(MessageContext msgContext)throws AxisFault
     {  
            SecurityProvider provider 
    = (SecurityProvider)msgContext.getProperty("securityProvider");
      
    if(provider==null)
      {
       provider
    = new SimpleSecurityProvider();
                 msgContext.setProperty(
    "securityProvider", provider);
             }
            
    if(provider!=null)
            {         
             String userId
    =msgContext.getUsername();
             String password
    =msgContext.getPassword();
             
             
    //對用戶進(jìn)行認(rèn)證,如果authUser==null,表示沒有通過認(rèn)證,
    拋出Server.Unauthenticated異常。
                org.apache.axis.security.AuthenticatedUser authUser 
    = provider.authenticate(msgContext);
                
    if(authUser==null)
                  
    throw new AxisFault("Server.Unauthenticated"
    Messages.getMessage(
    "cantAuth01", userId), null,null);
                
    //用戶通過認(rèn)證,把用戶的設(shè)置成認(rèn)證了的用戶。
                msgContext.setProperty("authenticatedUser", authUser);
            } 
        }
    }


    AuthenticationHandler代碼里,它從MessageContext中獲得用戶信息,然后進(jìn)行認(rèn)證,如果認(rèn)證成功,那么就使用msgContext.setProperty("authenticatedUser", authUser)方法把用戶設(shè)置成認(rèn)證了的用戶,如果認(rèn)證不成功,那么就拋出Server.Unauthenticated異常。 

    部署這個(gè)Handler,同樣,在server-config里加入以下的內(nèi)容:


    <handler name="authen" type="java:com.hellking.webservice.AuthenticationHandler"/>

    <service name="HandleredService" provider="java:RPC">
    <parameter name="allowedRoles" value="chen"/>

    </service>
     

    WEB-INF/users.lst
    文件中加入以下用戶:

    hellking hellking
    chen chen

    http://127.0.0.1:8080/handler/services/HandleredService?wsdl&method=publicMethod&name=chen

    將會(huì)提示輸入用戶名和密碼,如圖2所示。


     

    訪問web服務(wù)時(shí)的驗(yàn)證 

    如果客戶端是應(yīng)用程序,那么可以這樣在客戶端設(shè)置用戶名和密碼:

    例程在客戶端設(shè)置用戶名和密碼

    http://127.0.0.1:808
         
    String endpointURL = "http://127.0.0.1:8080/handler/services/HandleredService?wsdl";            
                Service  service 
    = new Service();
                Call     call    
    = (Call) service.createCall();
                call.setTargetEndpointAddress( 
    new java.net.URL(endpointURL) );
                call.setOperationName( 
    new
     QName(
    "HandleredService""orderProduct") );//設(shè)置操作的名稱。
                
    //由于需要認(rèn)證,故需要設(shè)置調(diào)用的用戶名和密碼。
                call.getMessageContext().setUsername("chen");
                call.getMessageContext().setPassword(
    "chen");  
     

    使用Handler對用戶的訪問授權(quán)

    對于已經(jīng)認(rèn)證了的用戶,有時(shí)在他們操作某個(gè)特定的服務(wù)時(shí),還需要進(jìn)行授權(quán),只有授權(quán)的用戶才能繼續(xù)進(jìn)行操作。我們看對用戶進(jìn)行授權(quán)的Handler的代碼。 

    例程對用戶進(jìn)行授權(quán)的代碼

    package com.hellking.webservice;

    import

    //此handler的目的是對認(rèn)證的用戶授權(quán),只有授權(quán)的用戶才能訪問目標(biāo)服務(wù)。
    public class AuthorizationHandler extends BasicHandler
    {
     
    /**invoke,每一個(gè)handler都必須實(shí)現(xiàn)的方法。
      
    */
     
    public void invoke(MessageContext msgContext)
            
    throws AxisFault
        {
          
            AuthenticatedUser user 
    = (AuthenticatedUser)msgContext.getProperty("authenticatedUser");
            
    if(user == null)
                
    throw new AxisFault("Server.NoUser", Messages.getMessage("needUser00"), nullnull);
            String userId 
    = user.getName();
            Handler serviceHandler 
    = msgContext.getService();
            
    if(serviceHandler == null)
                
    throw new AxisFault(Messages.getMessage("needService00"));
            String serviceName 
    = serviceHandler.getName();
            String allowedRoles 
    = (String)serviceHandler.getOption("allowedRoles");
            
    if(allowedRoles == null)
            {          
                
    return;
            }
            SecurityProvider provider 
    = (SecurityProvider)msgContext.getProperty("securityProvider");
            
    if(provider == null)
                
    throw new AxisFault(Messages.getMessage("noSecurity00"));
            
    for(StringTokenizer st = new StringTokenizer(allowedRoles, ","); st.hasMoreTokens();)
            {
                String thisRole 
    = st.nextToken();
                
    if(provider.userMatches(user, thisRole))
                {
                    
    return;//訪問授權(quán)通過。
                }
            }
            
    //沒有通過授權(quán),不能訪問目標(biāo)服務(wù),拋出Server.Unauthorized異常。
            throw new AxisFault("Server.Unauthorized"
    Messages.getMessage(
    "cantAuth02", userId, serviceName), nullnull);
        }     
    }


    service-config.wsdd文件中,我們?yōu)?/span>Web服務(wù)指定了以下的用戶:

    <parameter name="allowedRoles" value="chen,hellking"/>


    provider.userMatches(user, thisRole)
    將匹配允許訪問Web服務(wù)的用戶,如果匹配成功,那么授權(quán)通過,如果沒有授權(quán)成功,那么拋出Server.Unauthorized異常。 

    使用HandlerSOAP消息進(jìn)行加密、解密

    由于SOAP消息在HTTP協(xié)議中傳輸,而HTTP協(xié)議的安全度是比較低的,怎么保證信息安全到達(dá)對方而不泄漏或中途被撰改,將是Web服務(wù)必須解決的問題。圍繞Web服務(wù)的安全,有很多相關(guān)的技術(shù),比如WS-Security,WS-Trace等,另外,還有以下相關(guān)技術(shù): 

    XML Digital Signature
    XML數(shù)字簽名) 
    XML Encryption 
    XML加密) 
    XKMS (XML Key Management Specification) 
    XACML (eXtensible Access Control Markup Language) 
    SAML (Secure Assertion Markup Language) 
    ebXML Message Service Security 
    Identity Management & Liberty Project 
    不管使用什么技術(shù),要使信息安全到達(dá)對方,必須把它進(jìn)行加密,然后在對方收到信息后解密。為了提供開發(fā)的方便,可以使用Handler技術(shù),在客戶端發(fā)送信息前,使用客戶端的HandlerSOAP消息中的關(guān)鍵信息進(jìn)行加密;在服務(wù)端接收到消息后,有相應(yīng)的Handler把消息進(jìn)行解密,然后才把SOAP消息派發(fā)到目標(biāo)服務(wù)。 

    下面我們來看一個(gè)具體的例子。加入使用SOAP消息發(fā)送訂單的信息,訂單的信息如下:

    例程要發(fā)送的訂單SOAP消息

    <soap-env:Envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/">
        
    <soap-env:Header/>
        
    <soapenv:Body>
       
    <ns1:orderProduct soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encod
     ing/" xmlns:ns1="HandleredService">
        <arg0 xsi:type="xsd:string">hellking</arg0>
        
    <arg1 xsi:type="xsd:string">beijing</arg1>
        
    <arg2 xsi:type="xsd:string">music-100</arg2>
        
    <arg3 xsi:type="xsd:int">10</arg3>
        
    <arg4 href="#id0"/>
       
    </ns1:orderProduct>
       
    <multiRef id="id0" soapenc:root="0" soapenv:encodingStyle="http://schemas.xmls
     oap.org/soap/encoding/" xsi:type="ns2:card" xmlns:soapenc="http://schemas.xmlsoa
     p.org/soap/encoding/" xmlns:ns2="card">
        
            
    <cardId xsi:type="xsd:string">234230572</cardId>
                    
            
    <cardType xsi:type="xsd:string">visa</cardType>
                    
            
    <password xsi:type="xsd:string">234kdsjf</password>
       
    </multiRef>
      
    </soapenv:Body>
       
    </soap-env:Envelope>
         

    上面的黑體字是傳輸?shù)拿舾行畔ⅲ市枰用?。我們可以使?/span>Message Digest之類的方法進(jìn)行加密。加密之后的信息結(jié)構(gòu)如下: 

    例程SOAP消息某些部分加密

    <?xml version="1.0" encoding="UTF-8"?>
    <soapenv:Envelope …
    <soapenv:Body>
      
    <ns1:orderProduct …>
       …
       
    <arg4 href="#id0"/>
      
    </ns1:orderProduct>
      
    <multiRef …>
       
    <ns3:EncryptedData xmlns:ns3="http://www.w3.org/2000/11/temp-xmlenc">
        
    <ns3:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
        
    <ns3:DigestValue>rO0ABXQAkyA8Y2FyZ…….
    </ns3:DigestValue>
       
    </ns3:EncryptedData>
      
    </multiRef>
     
    </soapenv:Body>
    </soapenv:Envelope>

     

    3是使用HandlerSOAP消息進(jìn)行加密、解密后,SOAP消息在傳遞過程中結(jié)構(gòu)的改變。 


    3 SOAP消息的加密和解密 

    從上圖可以看出,通過使用加密、解密的Handler,可以確保消息的安全傳遞。進(jìn)一步說,如果把這種Handler做成通用的組件,那么就可以靈活地部署到不同的服務(wù)端和客戶端。 

    客戶端的Handler的功能是把SOAP消息使用一定的規(guī)則加密,假如使用Message Digest加密方式,那么可以這樣對敏感的信息加密: 

    例程10 SOAP消息的敏感部分加密

             SOAPElement ele
    = soapBodyElement.addChildElement(envelope.createName
    (
    "EncryptedData","","http://www.w3.org/2000/11/temp-xmlenc")); 
    ele.addChildElement(
    "DigestMethod").addAttribute(envelope.createName
    (
    "Algorithm"),"http://www.w3.org/2000/09/xmldsig#sha1");
       
       
    byte[] digest=new byte[100];
       ByteArrayOutputStream  out
    =new  ByteArrayOutputStream (100);
       MessageDigest md 
    = MessageDigest.getInstance("SHA");
       ObjectOutputStream oos 
    = new ObjectOutputStream(out);
       
    //要加密的信息
        String data = " <cardId xsi:type='xsd:string'>234230572
                            </cardId><cardType xsi:type='xsd:string'>visa</cardType>
                            
    <password     xsi:type='xsd:string'>234kdsjf</password>";

       
    byte buf[] = data.getBytes();
       md.update(buf);
       oos.writeObject(data);
       oos.writeObject(md.digest());  
       digest
    =out.toByteArray();
       out.close();      
          ele.addChildElement(
    "DigestValue").addTextNode(new 
    sun.misc.BASE64Encoder().encode(digest));
    //對加密的信息編碼


    在客戶端發(fā)送出SOAP消息時(shí),客戶端的Handler攔截發(fā)送的SOAP消息,然后對它們進(jìn)行加密,最后把加密的信息傳送到服務(wù)端。

    服務(wù)端接收到加密的信息后,解密的Handler會(huì)把對應(yīng)的加密信息解密。服務(wù)端Handler代碼如例程11所示。 

    例程11 服務(wù)端解密Handler

    package com.hellking.webservice;
    import
    //此handler的目的是把加密的SOAP消息解密成目標(biāo)服務(wù)可以使用的SOAP消息。
    public class MessageDigestHandler extends BasicHandler
    {
     
    /**invoke,每一個(gè)handler都必須實(shí)現(xiàn)的方法。
      
    */
     
    public void invoke(MessageContext msgContext)throws AxisFault
     {
      
    try
      {   
       
    //從messageContext例取得SOAPMessage對象。
       SOAPMessage msg=msgContext.getMessage();
       SOAPEnvelope env
    =msg.getSOAPPart().getEnvelope();
       Iterator it
    =env.getBody().getChildElements();   
       SOAPElement multi
    =null;
       
    while(it.hasNext())
        {
         multi
    =(SOAPElement)it.next();//multi是soapbody的最后一個(gè)child。
        }
       String value
    ="";//value表示加密后的值。
       SOAPElement digestValue=null;
       Iterator it2
    =multi.getChildElements();
       
    while(it2.hasNext())
       {
        SOAPElement temp
    =(SOAPElement)it2.next();
        Iterator it3
    =temp.getChildElements(env.createName("DigestValue",
    "ns3","http://www.w3.org/2000/11/temp-xmlenc"));
        
    if(it3.hasNext())
        value
    =((SOAPElement)it3.next()).getValue();//獲得加密的值    
       }   
        
    //把加密的SOAPMessage解密成目標(biāo)服務(wù)可以調(diào)用的SOAP消息。
        SOAPMessage   msg2=convertMessage(msg,this.decrypte(value));
        msgContext.setMessage(msg2);        
          }
          
    catch(Exception e)
          {
           e.printStackTrace();
          }      
     } 
     
    //這個(gè)方法是把加密的數(shù)據(jù)進(jìn)行解密,返回明文。
     public String decrypte(String value)
     {
      String data
    =null;
      
    try
      {
       ByteArrayInputStream fis 
    = new 
    ByteArrayInputStream(
    new sun.misc.BASE64Decoder().decodeBuffer(value));
       ObjectInputStream ois 
    = new ObjectInputStream(fis);
       Object o 
    = ois.readObject();
       
    if (!(o instanceof String)) {
        System.out.println(
    "Unexpected data in string");
        System.exit(
    -1);
       }
       data 
    = (String) o;
       System.out.println(
    "解密后的值:" + data);
       o 
    = ois.readObject();
       
    if (!(o instanceof byte[])) {
        System.out.println(
    "Unexpected data in string");
        System.exit(
    -1);
       }   
       
    byte origDigest[] = (byte []) o;
       MessageDigest md 
    = MessageDigest.getInstance("SHA");
       md.update(data.getBytes());
      }
             …
      
    return data;
      }
        
    //把解密后的信息重新組裝成服務(wù)端能夠使用的SOAP消息。
     public SOAPMessage convertMessage(SOAPMessage msg,String data)
     {    
       ….
     }
    }  
      
    可以看出,服務(wù)端解密的Handler和客戶端加密的Handler的操作是相反的過程。

    總結(jié)
    通過以上的討論,相信大家已經(jīng)掌握了Handler的基本使用技巧。可以看出,通過使用Handler,可以給Web服務(wù)提供一些額外的功能。在實(shí)際的開發(fā)中,我們可以開發(fā)出一些通用的Handler,然后通過不同的搭配方式把它們部署到不同的Web服務(wù)中。



    http://www.tkk7.com/ronghao 榮浩原創(chuàng),轉(zhuǎn)載請注明出處:)
    posted on 2007-06-12 16:01 ronghao 閱讀(3142) 評論(1)  編輯  收藏 所屬分類: SOA、BPM

    FeedBack:
    # re: 使用Handler來增強(qiáng)Web服務(wù)的功能
    2014-10-28 19:53 | ads
    asdfasfd  回復(fù)  更多評論
      
    <2014年10月>
    2829301234
    567891011
    12131415161718
    19202122232425
    2627282930311
    2345678

    關(guān)注工作流和企業(yè)業(yè)務(wù)流程改進(jìn)?,F(xiàn)就職于ThoughtWorks。新浪微博:http://weibo.com/ronghao100

    常用鏈接

    留言簿(38)

    隨筆分類

    隨筆檔案

    文章分類

    文章檔案

    常去的網(wǎng)站

    搜索

    •  

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: EEUSS影院WWW在线观看免费| 麻豆91免费视频| 无码的免费不卡毛片视频| 花蝴蝶免费视频在线观看高清版| 91频在线观看免费大全| 亚洲国产一级在线观看| 亚洲精品国产成人中文| 黄色免费网址在线观看| 1000部拍拍拍18勿入免费视频下载| 国产三级电影免费观看| 91情国产l精品国产亚洲区 | 一个人免费观看视频在线中文 | 亚洲av无码成人精品区| 亚洲欧洲尹人香蕉综合| 一日本道a高清免费播放| 无码av免费毛片一区二区| 国产午夜亚洲精品午夜鲁丝片| 日本亚洲精品色婷婷在线影院| 91成人免费福利网站在线| 日产乱码一卡二卡三免费| 精品亚洲aⅴ在线观看| fc2免费人成在线视频| 免费毛片网站在线观看| 亚洲AV人人澡人人爽人人夜夜| 美女扒开尿口给男人爽免费视频 | 亚洲AV无码久久寂寞少妇| 青草久久精品亚洲综合专区| 18女人毛片水真多免费| 国产AV无码专区亚洲AWWW| 亚洲爆乳无码专区www| 国产一卡二卡四卡免费| 亚洲va中文字幕无码久久不卡| 男女超爽视频免费播放| 一二三四视频在线观看中文版免费| 无人视频免费观看免费视频| 羞羞视频免费观看| 亚洲国产精品一区二区九九| 亚洲一级毛片免费看| 七色永久性tv网站免费看| 久久久久亚洲AV无码专区桃色| 亚洲国产精品久久久久秋霞小|