网站地图
  
  高级搜索
  首页   技术论坛   博客 派计划   产品中心   资源中心   银弹在线   商城  





WPS/WESB 6.1 之 SCA 新特性,第 3 部分: HTTP 绑定的高级特性    
#1楼
给作者发送短消息 给作者发送短消息 实名会员 
查看用户其他信息
总分 358 分
财富 828 goCom币
威望 156
排名 第 57 名
段位 新手必读

 

绑定上下文(binding context)是 WebSphere Process Server (WPS) /WebSphere Enterprise Service Bus (WESB) 6.1 中引入的一个新特性。通过绑定上下文,用户可以在一次调用(会话)中实现数据绑定(data binding)和函数选择器(function selector)之间共享数据,只要这些数据绑定和函数选择器实现了接口 commonj.connector.runtime.BindingContext。这个接口只有一个方法:

public void setBindingContext(java.util.Map bindingContext)

比如,用户可以在输入数据绑定中,存储某些数据在共享 java.util.Map 中,然后在输出数据绑定中再使用这些数据。

另外,通过绑定上下文,HTTP 绑定也能够将某些运行时的数据传输给实现了绑定上下文接口 commonj.connector.runtime.BindingContext 的数据绑定和函数选择器。这些数据包括:



键名(Key)
BindingContext.BINDING_NAME Import或者Export的名字
BindingContext.BINDING_TYPE 只能为
BindingContext.BINDING_TYPE_HTTP
BindingContext.BINDING_COMMUNICATION 对Export,值为
BindingContext.BINDING_COMMUNICATION_INBOUND
对Import,值为
BindingContext.BINDING_COMMUNICATION_OUTBOUND
BindingContext.BINDING_INVOCATION 对消息请求,值为
BindingContext.BINDING_INVOCATION_REQUEST
对消息应答,值为
BindingContext.BINDING_INVOCATION_RESPONSE
BindingContext.EXPECTED_TYPE 输入或者输出数据类型
(javax.xml.namespace.QName)

通过绑定上下文,用户就可以在自己的数据绑定或者函数选择器中使用这些数据。



 

虽然 HTTP 绑定提供了一些数据绑定,但这些数据绑定并不能满足用户的所有需求,用户也可以根据自己的需求开发相应的数据绑定。本节将介绍如何开发一个自定义的 HTTP 数据绑定和函数选择器,并通过绑定上下文实现数据的共享。

 

在基础篇中我们已经简单的介绍了 HTTP 绑定的控制数据。为了开发一个数据绑定,我们必须理解每个控制数据的含义,以及它们的适用场景。下面是这些控制数据的基本信息:



名称 缺省值 可能值 Import
输入数据绑定
Import
输出数据绑定
Export
输入数据绑定
Export
输出数据绑定
URL   忽略 忽略 使用 忽略
Version 1.1 1.0,1.1 忽略 忽略 使用 忽略
Method   忽略 忽略 使用 忽略
             
DynamicOverrideURL   使用 忽略 忽略 忽略
DynamicOverrideVersion 1.1 1.0,1.1 使用 忽略 忽略 忽略
DynamicOverrideMethod   使用 忽略 忽略 忽略
             
MediaType   使用 使用 使用 使用
Charset UTF-8   使用 使用 使用 使用
TransferEncoding identity chunked
identity
使用 使用 使用 使用
ContentEncoding identity gzip
x-gzip
deflate
identity
使用 使用 使用 使用
ContentLength     使用 使用 使用 使用
StatusCode 200   忽略 使用 忽略 使用
ReasonPhrase OK   忽略 使用 忽略 使用
Authentication   使用 忽略 使用 忽略
Proxy   使用 忽略 忽略 忽略
SSL   使用 忽略 忽略 忽略

:“忽略”表示用户无论在数据绑定里面如何设置数据的值,HTTP 绑定在发送消息请求或应答时都不会使用这些值。相反,“使用”表示 HTTP 绑定在发送消息请求或应答时将会使用这些值。

根据上表,用户可以根据自己的使用场景来设置这些值。例如,在 Import 中,如果用户希望通过在数据绑定中指定消息请求的 URL,则用户应该在输入数据绑定中修改 DynamicOverrideURL,而不是 URL。

接下来,我们将开发一个新的 HTTP 数据绑定 HTTPStreamDataBindingMap,这个数据绑定能够实现 SDO(Service Data Object)和名值对集合(key/value pair set)之间的转换。我们可以通过绑定上下文的 BindingContext.EXPECTED_TYPE 键值来获取 SDO 的数据类型并创建相应的 SDO 实例。

  • 实现接口

在基础篇中讲过,所有的 HTTP 数据绑定都必须实现接口:

com.ibm.websphere.http.data.bindings.HTTPStreamDataBinding

当然,数据绑定 HTTPStreamDataBindingMap 也要实现这个接口。

另外,为了获取 SDO 的数据类型,这个数据绑定也还必须实现绑定上下文接口:

commonj.connector.runtime.BindingContext

下面清单 1 中是对此数据绑定的定义:

清单 1. 数据绑定定义

public class HTTPStreamDataBindingMap implements HTTPStreamDataBinding, BindingContext {
private DataObject fieldDataObject;
private HTTPControl fieldControl;
private HTTPHeaders fieldHeaders;
//store the native bytes data
transient private ByteArrayOutputStream nativeData = new ByteArrayOutputStream();
//store the bindingContext
private Map bindingContext;
public void setBindingContext(Map bindingContext) {
    this.bindingContext = bindingContext;
}
...
}

  • 数据转换

数据转换包括从原生数据(native data)到 SDO 和从 SDO 到原生数据的转换。

从原生数据到 SDO 的转换中,我们需要知道 SDO 的类型。另外,如何出现业务逻辑异常(Service Business Exception),所创建的 SDO 应该是用来表示异常数据的,否则,所创建的 SDO 应该是用来表示业务数据的。本例中,我们在代码中直接指定了异常 SDO 的数据类型,对应业务数据的类型,我们通过绑定上下文来获取。在绑定上下文中,我们已经介绍过,这些数据是 HTTP 绑定在运行时设置的,因此我们可以在数据绑定的实现中直接使用。下面是从原生数据到 SDO 数据转换的参考代码。

清单 2. 从原生数据到 SDO 的数据转换

public void convertFromNativeData(HTTPInputStream inputStream)
        throws DataBindingException, IOException {
     //read bytes from inputStream into nativeData
    if (nativeData.size() == 0) {
        return;
    }
    // create SDO from native data
    Properties prop = new Properties();
    prop.load(new ByteArrayInputStream(nativeData.toByteArray()));
    if (isBusinessException()) {
        fieldDataObject = 
        DataFactory.INSTANCE.create(“http://OrderLib”, “FaultBO”);
    else {
    QName expectedType = (QName) bindingContext.get(BindingContext.EXPECTED_TYPE);
    fieldDataObject = 
    DataFactory.INSTANCE.create(
    expectedType.getNamespaceURI(), expectedType.getLocalPart());
    }
    List sdoprops = fieldDataObject.getType().getProperties();
    for (int i = 0, size = sdoprops.size(); i < size; ++i) {
        Property each = (Property)sdoprops.get(i);
        String value = prop.getProperty(each.getName());
        if (value != null) {
            fieldDataObject.set(each.getName(), value);
        }
    }
}

相对从原生数据到 SDO 的转换,从 SDO 到原生数据的转换要简单很多,这是因为我们已经知道 SDO 的数据类型,并能够获取 SDO 的相关信息,下面是从 SDO 到原生数据转换的参考代码。值得注意的是,我们必须在控制参数中设置原生数据的内容长度(content length),如果没有设置内容长度,HTTP 接收方将无法接收正确的原生数据。

清单 3. 从 SDO 到原生数据的数据转换

public void convertToNativeData() throws DataBindingException {
    nativeData.reset();
    if (fieldDataObject == null) {
        fieldControl.setContentLength(nativeData.size());
        return;
    }
    List sdoprops = fieldDataObject.getType().getProperties();
    for (int i = 0, size = sdoprops.size(); i < size; ++i) {
        Property each = (Property)sdoprops.get(i);
        Object value = fieldDataObject.get(each);
        if (value != null) {
            String line = each.getName() + " = " + value + "\n";
            try {
                nativeData.write(line.getBytes());
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    fieldControl.setContentLength(nativeData.size());
}

  • 业务异常(Business Exception)处理

我们遵循 HTTP 绑定提供的数据绑定设计原则,用 HTTP 消息头 IsBusinessException 来表示此消息是否为业务逻辑异常消息,对应的值为 True 和 False,另外,如果是业务逻辑异常,还必须将消息的状态编码(Status Code)设置为 500 – 内部服务器错误(Internal Server Error)。

 

下面,我们来开发一个自己的函数选择器 URLQueryHTTPFunctionSelector,此函数选择器将URL 的参数(TargetFunctionName)的值作为本地方法返回。例如 URL:

http://localhost:9080/OrderSystemWeb/OrderExport?TargetFucntionName=orderProcessing

对应的本地方法为 orderProcessing。下面是对应的代码

清单 4. QueryString函数选择器

public class URLQueryHTTPFunctionSelector extends HTTPFunctionSelector {
    public String generateEISFunctionName(HTTPControl control, HTTPHeaders headers,
            HTTPInputStream input) throws SelectorException {
        String urlStr = control.getURL();
        //Uniform Resource Identifiers : Generic * Syntax
        //<scheme>://<authority><path>?<query>#<fragment>
        int startIdx = urlStr.indexOf('?');
        int endIdx = urlStr.indexOf('#');
        String queryString = (endIdx ==-1)
                            ? urlStr.substring(startIdx + 1)
                            : urlStr.substring(startIdx + 1, endIdx);
        String[] params = queryString.split("&+");
        String prefix = "TargetFunctionName=";
        for (int i = 0; i < params.length; ++i) {
            if (params[i].startsWith(prefix)) {
                return params[i].substring(prefix.length());
            }
        }
        return null;
    }
}

前面,我们已经介绍了如何开发一个自定义的 HTTP 数据绑定和函数选择器。接下来,我们将介绍一些 HTTP 绑定的高级配置选项,包括配置验证(authentication)数据和 SSL(Security Socket Layer)数据。


 

本节包括如何配置 HTTP Export,让只有通过验证的客户访问此 HTTP Export 服务,以及如何配置 HTTP Import 去访问需要验证的 URL,包括HTTP Export 的 URL。另外,需要注意的是,验证数据只有 WPS/WESB 的安全管理启动后才起作用,因此,用户必须在打开安全之后才能看到这些配置数据的效果。

 

开发流程

由于 HTTP Export 是以 servlet 的方式呈现给用户的,因此,配置 HTTP Export 的验证数据跟配置普通的 URL 的验证数据一样,并没有特殊的要求。下面我们简单的介绍一下在 WID 中如何配置这些验证数据。

1. 切换到 J2EE 视图。

2. 打开模块 OrderSystem 对应的 Web 工程 OrderSystemWeb 中的 web.xml 文件。

3. 切换到 security 标签页。

4. 在 Security Roles 中添加一个 role--customer。

5. 在 Security Constraints 中添加一个 constraint –PurchaseOrderExportAccess,并在弹出的窗口中配置相应的数据,用于对 HTTP Export servlet 访问的控制,见图 1。




在Security 标签页中,选择 Security Constraints 表单里的 PurchaseOrderExportAccess,在 Authorized Roles 中添加在步骤 4 中创建的 Role customer。下图 2 是配置完后的 security 标签页。




下面是此配置对应的 web.xml 清单

清单5. 验证数据配置清单

<security-constraint>
  <display-name>
  PurchaseOrderExportAccess</display-name>
  <web-resource-collection>
    <web-resource-name>PurchaseOrderExport</web-resource-name>
    <url-pattern>/PurchaseOrderExport</url-pattern>
    <url-pattern>/PurchaseOrderExport/*</url-pattern>
    <http-method>GET</http-method>
    <http-method>HEAD</http-method>
    <http-method>POST</http-method>
  </web-resource-collection>
  <auth-constraint>
    <description>accessRoles</description>
    <role-name>customer</role-name>
  </auth-constraint>
</security-constraint>
<security-role>
  <role-name>customer</role-name>
</security-role>

绑定用户

我们已经开发了一个验证的程序,但是,我们并没有指定角色 customer 对应的用户,这是在应用程序安装后指定的。下面是角色到用户映射的步骤:

  1. 通过浏览器进入 WPS/WESB 管理控制台
  2. 进入 Applications -> Enterprise Applications
  3. 点击安装的 HTTP Export 应用程序 OrderSystemApp 进入此程序的页面
  4. 点击Security role to user/group mapping
  5. 选择角色 customer,点击 Look up users
  6. 点击 search 并添加一个或者多个用户
  7. 保存设置

这样,当 WPS/WESB 的安全管理启动后,只有 customer 角色对应的用户才能够访问此 HTTP Export。

 

当用 HTTP Import 去访问一个需要认证的 URL 时,包括上节配置的 HTTP Export 对应的servlet,我们必须在 Import 中配置相应的验证数据,下面是验证数据的模式(schema)定义:

清单 6. HTTP Import 验证模式定义

<!--
xmlns:http="http://www.ibm.com/xmlns/prod/websphere/scdl/http/6.1.0"
xmlns:scdl="http://www.ibm.com/xmlns/prod/websphere/scdl/6.0.0"
targetNamespace="http://www.ibm.com/xmlns/prod/websphere/scdl/http/6.1.0"
-->
<!--HTTP Authentication -->
<complexType name="HTTPAuthentication">
  <complexContent>
    <extension base="scdl:Describable">
      <sequence>
        <element name="credentials" type="http:HTTPCredentials"/>
        <element name="authenticationType" type="http:HTTPAuthenticationType"/>
      </sequence>
    </extension>
  </complexContent>
</complexType>
<!--HTTP Credentials -->
<complexType name="HTTPCredentials">
  <complexContent>
    <extension base="scdl:Describable">
      <sequence>
        <element name="credentialAlias" type="string"/>
      </sequence>
    </extension>
  </complexContent>
</complexType>
<!-- Authentication Type, for now only Basic Auth is supported -->
<simpleType name="HTTPAuthenticationType">
  <restriction base="string">
    <enumeration value="Basic"/>
  </restriction>
</simpleType>

从模式定义中可以看出,在 WPS/WESB 6.1 中,HTTP Import 绑定只支持基本验证(Basic Authentication)方式。

下面我们开发一个 HTTP Import 实例 OrderClient 来访问之前配置的 HTTP Export。下面是HTTP Import 的清单。

清单 7. HTTP Import 验证配置实例

<?xml version="1.0" encoding="UTF-8"?>
<scdl:import xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 

xmlns:http="http://www.ibm.com/xmlns/prod/websphere/scdl/http/6.1.0" 

xmlns:ns1="http://OrderLib/purchaseOrder" 
xmlns:scdl="http://www.ibm.com/xmlns/prod/websphere/scdl/6.0.0" xmlns:wsdl=
"http://www.ibm.com/xmlns/prod/websphere/scdl/wsdl/6.0.0" 
displayName="PurchaseOrderImport" name="PurchaseOrderImport">
  <interfaces>
    <interface xsi:type="wsdl:WSDLPortType" portType="ns1:purchaseOrder"/>
  </interfaces>
  <esbBinding xsi:type="http:HTTPImportBinding"
   defaultDataBinding="ordlib.data.HTTPStreamDataBindingMap">
    <importInteraction endpointURL=
    "http://localhost:9080/OrderSystemWeb/PurchaseOrderExport" 
    httpMethod="GET"/>
    <methodBinding method="orderProcessing">
      <importInteraction endpointURL=
      "http://localhost:9080/OrderSystemWeb/PurchaseOrderExport?
      TargetFunctionName= orderProcessing" httpMethod="GET">
         <requestAuthentication>
          <credentials>
            <credentialAlias>nlNode01/OrderAuthenticationAlias</credentialAlias>
          </credentials>
          <authenticationType>Basic</authenticationType>
        </requestAuthentication>
      </importInteraction>
    </methodBinding>
  </esbBinding>
</scdl:import>

对应的 WID 属性界面见图 3




另外,我们也需要在 WPS/WESB 控制台中配置相应的别名:nlNode01/OrderAuthenticationAlias,其中,n1Node1 是 WPS/WESB 的 node 名称。下面是配置步骤:

  1. 进入Security -> Secure administration, applications, and infrastructure
  2. 展开右边选项 Java Authentication and Authorization Service -> J2C authentication data
  3. 在新页面中新建一个别名 OrderAuthenticationAlias,配置相应的用户名和密码,并保存设置

注1:此用户名和密码是 HTTP Import 要访问的 URL 的验证用户名和密码,因此,必须保证与 URL 要求的用户名和密码一致。

注2:虽然我们创建的别名是 OrderAuthenticationAlias,但是保存后显示的别名为<节点名>/OrderAuthenticationAlias。在本例的环境中,显示为 n1Node01/OrderAuthenticationAlias。因此,在 Import 的配置文件中,也应该配置为 n1Node01/OrderAuthenticationAlias。

这样,HTTP Import 就能够访问 HTTP Export 对应的URL(http://localhost:9080/OrderSystemWeb/PurchaseOrderExport/orderProcessing)了。

 

当 HTTP Import 要去访问一个 https 的 URL 时,必须在 Import 中配置 SSL。下面是配置了SSL 的 HTTP Import 实例:

清单 8. HTTP Import 的 SSL 配置实例

<?xml version="1.0" encoding="UTF-8"?>
<scdl:import xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:http="http://www.ibm.com/xmlns/prod/websphere/scdl/http/6.1.0"
xmlns:ns1="http://OrderLib/PageHandler" 
xmlns:scdl="http://www.ibm.com/xmlns/prod/websphere/scdl/6.0.0"
xmlns:wsdl="http://www.ibm.com/xmlns/prod/websphere/scdl/wsdl/6.0.0" 
displayName="SSLDemoImport"
name="SSLDemoImport">
  <interfaces>
    <interface xsi:type="wsdl:WSDLPortType" portType="ns1:PageHandler"/>
  </interfaces>
  <esbBinding xsi:type="http:HTTPImportBinding"
  defaultDataBinding=
  "com.ibm.websphere.http.data.bindings.HTTPStreamDataBindingBytes">
    <importInteraction endpointURL="https://www.paypal.com/" httpMethod="GET"/>
    <methodBinding method="getContent">
      <importInteraction endpointURL="https://www.paypal.com/" httpMethod="GET">
        <sslSettings>
          <sslConfigAlias>SSLDemoSettings</sslConfigAlias>
        </sslSettings>
      </importInteraction>
    </methodBinding>
  </esbBinding>
</scdl:import>

另外,在 WPS/WESB 控制台中也要配置相应的 alias。下面,我们介绍一下如何在WPS/WESB 控制台中配置 SSL 的 alias。

1. 进入 Security) -> SSL certificate and key management -> 选择右边的Key stores and certificates:

a) 新建一个密钥库 SSLDemoKeyStore:

路径可以参考 WPS/WESB 已提供的密钥库(NodeDefaultKeyStore)。

设置密码 sdks。

其他保持默认值。

保存设置。

b) 新建一个信任库 SSLDemoTrustStore:

路径可以参考 WPS/WESB 已提供的信任库(NodeDefaultTrustStore)。

设置密码 sdts。

其他保持默认值。

保持设置。

2. 进入 Security -> SSL certificate and key management -> 选择右边的Key stores and certificates,新建一个签署者证书:

  • 点击 SSLDemoTrustStore
  • 在右边的 Additional Properties 栏中点击 Signer certificates,进入配置页面
  • 点击“添加”添加一个签署者证书

注:用户可以通过 Internet Explorer 浏览器导出网站提供的证书。

3. 进入 Security -> SSL certificate and key management -> 选择右边的 SSL configurations,新建一个 SSL 配置 SSLDemoSSLSettings。

  • 信任库名选择 SSLDemoTrustStore
  • 密钥库名选择 SSLDemoKeyStore
  • 点击 Get certificate aliases 并保存

配置完后,HTTP Import 就能够访问相应的 URL了。

来源:IBM

 




发表回复
账号用户名   密码   登录
内容:url email imgsrc image code quote
范例 Example
bold italic underline linethrough   


 [更多...]