WebSphere Adapter 客户定制的错误绑定

吴 卫, 软件开发工程师, IBM
王 斌, 高级软件工程师, IBM
邢 常亮, 高级软件工程师, IBM

简介: WebSphere Adapter 6.2 中引入了一个非常重要的功能 — 错误绑定。通过错误绑定, Adapter 能够对异常(Exception)实现不同的处理流程。本文首先介绍错误绑定的工作机制,然后讲述了 WebSphere Adapter 预定义的一些错误绑定以及局限,最后以 JDBC Adapter 为实例讲述了如何配置客户定制的错误绑定。

为什么要错误绑定

关于 WebSphere Adapter 错误绑定原理与应用,可以参加作者的另外一篇文章(链接如下:http://www.ibm.com/developerworks/cn/websphere/library/techarticles/0912_wuwei_adaptererror/),本文中,作者将简单的描述一下为什么客户需要错误绑定,WebSphere Adapter 目前所支持的错误绑定,客户定制的错误绑定的意义与实现方法。

错误绑定是 WebSphere Adapter 提供的一种与编程语言无关的处理业务逻辑异常的机制,通过此错误处理机制,能够将运行时异常和业务逻辑异常进行区分,并给应用系统的调用者提供更为有意义的错误数据。

错误绑定的意义在于,可以提供给客户一种机制来区分运行时异常和业务逻辑异常,用户处理业务逻辑异常时不需要去检查冗长的运行时异常日志,而是直接处理返回的错误业务对象。基于这种机制,可以大大减少用户处理异常的代价,并且所返回的错误数据更加具体,更有意义。

在本章节中,我们将用 WebSphere Adapter for JDBC 为例子,简单回顾一下错误绑定的处理过程,请见下图 1:


图 1. 错误绑定流程图 查看大图
图 1. 错误绑定流程图

如上图所示,当 WebSphere Adapter 遇到异常 (Exception) 时,WebSphere Adapter 先调用错误选择器 (Fault Selector) 判断此异常是否为 WebSphere Adapter 支持的错误,如果不是,则不做处理,如果是,则调用错误选择器生成对应的错误名字 (Fault Name)。然后根据错误名字找到对应的错误绑定类型 (Fault Binding Type),最后调用错误绑定类型生成相应的错误数据 (Fault Data),并将此错误数据返回给调用者。

由此可见,用户可以自定义错误选择器来判断什么类型的异常应该被处理为错误,同时也可以自定义错误绑定实现在错误对象中放置定制的错误信息。

WebSphere Adapter 作为一个与各种 EIS 系统进行连接的产品,支持两大类的产品,一类称作 Application Adapter,用来连接诸如 SAP,Siebel,Oracle EBS 等不同的应用系统,另外一类称为 Technology Adapter,用于通过 JDBC,Email,FTP 等标准与相应的系统交互。各个不同的 Adapter 在其错误绑定上有某些相似之处。基于此种考虑,WebSphere Adapter 在其基础实现类中定义了 5 种通用的错误绑定,每个 Adapter 既可以直接使用这 5 种错误绑定,也可以很方便的定义自己特殊的错误绑定。WebSphere 基础实现类中定义的错误绑定,是最常见错误类型,除了这 5 个错误绑定之外,每个 Adapter 还自己扩展了一些预定义好的错误绑定,来满足自身 adapter 对于错误处理的需要,以 JDBC Adapter 为例,扩展了 IntegrityConstraintFault,ObjectNotFoundFault,UniqueConstraintFault 3 个错误绑定,用以满足 JDBC Adapter 的错误处理的需要。

下表 1 列举了 WebSphere Adapter 基础实现类中定义的错误绑定的类型:


表 1. 基本错误绑定类型

错误类型名称 错误类型实现类 错误类型业务对象
DUPLICATE_RECORD DuplicateRecordException DuplicateRecordFault
MATCHES_EXCEEDED_LIMIT MatchesExceededLimitException MatchesExceededLimitFault
MULTIPLE_MATCHING_RECORDS MultipleMatchingRecordsException MultipleMatchingRecordsFault
RECORD_NOT_FOUND RecordNotFoundException RecordNotFoundFault
MISSING_DATA MissingDataException MissingDataFault

通过前面的章节读者已经可以发现,每个 Adapter 预先定义好的错误绑定数量都是有限的,这样就会带来一个问题,WebSphere Adapter 预定义的错误绑定的类型不能满足客户的所有需求,例如:客户在访问数据库时遇到 Table Locked 这个 SQL 错误信息,显然属于业务层面的异常,但是目前的 WebSphere Adapter for JDBC 就不能够将该类型的异常按照错误绑定的机制进行处理,客户需要按照一般的运行时异常进行处理,造成很大的不便。

问题在于,每个客户所期望的错误绑定类型都不一致,对于 WebSphere Adapter 而言,很难预先定义好所有的错误绑定类型来供用户使用,所以需要有一种机制让客户自己定制相应的错误绑定,这就是我们为什么需要客户定制的错误绑定。

从上面的分析可以看出,实现客户定制的错误绑定所需要的工作是:

1)定制的错误业务对象。

2)定制错误选择器。

3)定制错误绑定实现类

4)配置定制的错误选择器,错误绑定,错误业务对象到需要该定制错误的功能操作上

下面的章节将以 WebSphere Adapter for JDBC 为例,实现一个用户定制的错误绑定。

用户场景中,使用 WebSphere Adapter for JDBC 支持的存储过程业务对象从数据库中提取数据。用户使用的存储过程需要访问多张数据表,由于有并发的应用程序也在同时访问这些数据表,因此在调用存储过程的过程中有时候会得到“Record is already locked”这类 SQL 异常。使用 JDBC Adapter 默认提供的错误绑定,该类 SQL 异常不能被处理为错误,只能当作运行时异常处理,会导致用户的异常处理代码非常复杂。因此用户需要实现自己定制的错误绑定,将这类 SQL 异常处理为错误业务对象,以简化业务流程处理。

根据前文所述,客户的第一个工作是定义错误业务对象,在这个实例中,为了简单起见,我们新定义的错误业务对象直接继承于 Adapter 基础实现类定义的基础错误业务对象,新定义的错误业务对象命名为 myFault,定义清单如下:


清单 1. myFault 错误业务对象定义

				 
 "1.0"encoding="UTF-8"?> 
 "http://testFault"xmlns:Q1="http://com/ibm/j2ca/fault"
 xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
  "http://com/ibm/j2ca/fault"schemaLocation="WBIFault.xsd"/> 
  "myFault"> 
     
      "Q1:WBIFault"> 
         
       
     
   
  


图 2. myFault 错误业务对象示意图
图 2. myFault 错误业务对象示意图

用户定义好错误业务对象之后,将错误业务对象直接放置在需要使用该错误业务对象的模块中即可。

接下来客户需要定制自己的错误选择器,文中的错误选择器命名为 myFaultSelector。错误选择器需要实现 FaultSelector 接口,需要实现的方法包括 isFault, generateFaultName。其中,isFault 方法用于判断一个异常是否为错误,generateFaultName 方法用来生成对应的错误名。在本实例的实现中,为了能够利用 Adapter 已经定义的错误绑定类型,我们实现的错误绑定选择器继承自 WBIFaultSelectorImpl. WBIFaultSelectorImpl 是 Adapter 基础实现类对于 FaultSelector 接口的实现,我们只需要扩展一些自己需要的功能就可以了,而不用重新实现所有的方法。

清单 3 是客户定制的错误选择器的具体实现:


清单 3. myFaultSelector 定义

				 
public classmyFaultSelector extendsWBIFaultSelectorImpl { 
 public
				 booleanisFault(Object[] fault) 
    { 
        if(fault != null&& fault.length > 0) 
        { 
            if(fault[0] instanceofBaseFaultException) 
            { 
                return
				 true; 
            } 
            else
				 if(fault[0] instanceofException) 
            {   // nested exception 
                Exception e = (Exception)fault[0]; 
                Throwable cause = e.getCause(); 
                while(!(cause instanceofBaseFaultException) && cause != null) 
                { 
                    cause = cause.getCause(); 
                } 
                if(cause != null) 
                { 
                    return
				 true; 
                } 
            } 
 // New code for generical fault BO handling 
            try{ 
 String excepInfo = e.getMessage(); 
 booleanresult = false; 
Pattern p = Pattern.compile(“Record is already locked”);

		 Matcher m = p.matcher(excepInfo); 
 booleanresult = m.find(); 
 returnresult; 
            } catch(Exception e) { 
		 e.printStackTrace(); 
   } 
        } 
        
        return
				 false; 
    } 
	
 publicString generateFaultName(Object[] fault) { 
 String faultName = super.generateFaultName(fault); 
 if(faultName !=null&& faultName.equalsIgnoreCase("UNKNOWN")){ 
 return"myFault"; 
 } else{ 
 returnfaultName; 
		 } 
		
	 } 
 } 

至此,我们已经定制了错误业务对象,错误选择器,接下来的步骤是需要实现定制的错误绑定,用于把异常中的信息放置到错误业务对象中。错误绑定实现类需要实现 FaultDataBinding 接口,在我们的实例中,我们自己定义的错误绑定命名为 myGenericalFaultBinding,继承自 Adapter 基础实现类的 WBIFaultDataBindingImpl,客户只需要实现相应的 getDataOject 方法,将异常信息放置到错误业务对象中即可。下述清单是 myGenericalFaultBinding 的实现:


清单 4. myGenericalFaultBinding 定义

				 
public classmyGenericalFaultBinding extendsWBIFaultDataBindingImpl { 
    
    // 从异常中获取错误数据
    publicDataObject getDataObject() throwsDataBindingException { 

        DataObject dataObj = null; 
        BaseFaultException bfe = super.getFaultData(); 
        if(bfe != null){ 
            return
				 super.getDataObject(); 
        } else{ 
   try{ 
    dataObj = SDOFactory.createDataObject("http://testFault", "myFault"); 
 //Need add code to set the exception information into the myFault business object 
   } catch(BusinessObjectDefinitionNotFoundException e) { 
        e.printStackTrace(); 
   } 
 } 
   returndataObj; 
    } 
 } 

至此,我们已经完成了错误业务对象,错误选择器,错误绑定的实现工作,下面的章节将介绍如何将这些实现类和业务对象配置到 JDBC adapter 的 outbound interface 中。

在 JDBC Adapter 的 outbound Interface 中,我们需要配置如下信息:错误选择器,错误类型,错误绑定实现类。请参加如下清单:


清单 5. 自定义错误绑定的应用实例

				 
 "1.0"encoding="UTF-8"?> 
 "JDBCOutboundInterface"> 
   
    "wsdl:WSDLPortType"preferredInteractionStyle="sync"
    portType="ns1:JDBCOutboundInterface"> 
      "scdl:JoinTransaction"value="false"/> 
       
     
   

			 
  "EIS:EISImportBinding"
	faultSelector="testFaultSelector"
	dataBindingType="
  com.ibm.j2ca.jdbc.emd.databinding.JDBCDataBindingGenerator">
			 
    "testFaultApp.IBM WebSphere Adapter for JDBC"
    type="com.ibm.j2ca.jdbc.JDBCResourceAdapter"version="7.0.0.0"> 
       
        001 
       
     
    "com.ibm.j2ca.jdbc.JDBCManagedConnectionFactory"
    interactionType="com.ibm.j2ca.jdbc.JDBCInteractionSpec"> 
       
       .... 
       
     
   .... 
    "com.ibm.xmlns.prod.websphere.j2ca.jdbc.db2adminsp_in_timestampbg.\
Db2adminSp_In_TimestampBGDataBinding"
    method="executeDb2adminSp_In_TimestampBG"outDataBindingType="com.ib
m.xmlns.prod.websphere.j2ca.jdbc.db2adminsp_in_timestampbg.\
Db2adminSp_In_TimestampBGDataBinding"
    > 
      "testFault"faultBindingType="
      myGenericalFaultBinding"/> 
       
         
          Execute 
         
       
     
   
  

至此,我们已经完成了一个简单的客户定制的错误绑定的例子,下面,我们可以来看一下在 WebSphere Integration Developer 中的集成测试工具来看一下运行的结果,请见下图 :


图 3. 自定义错误绑定的调用实例 查看大图
图 3. 自定义错误绑定的调用实例

由于本实例实现的相对简单,因此我们返回的错误业务对象中的数据基本上是空的,真正的客户应用场景中,可以在错误绑定实现中来实现将自定义的错误数据放置到错误业务对象中,来提供更好的出错分析处理。

本文首先介绍了错误绑定的原理,并介绍了 WebSphere Adapter 所支持的错误绑定及其使用场景。最后通过 1 个例子展现了如何实现客户定制的错误绑定在处理。通过本文的介绍,读者能够在实际的应用开发中理解错误绑定,实现定制的客户错误绑定,充分利用错误绑定提供的便利性。

原文链接:http://www.ibm.com/developerworks/cn/websphere/library/techarticles/1006_wuwei_adapterbinding/index.html

请使用浏览器的分享功能分享到微信等