用户可以采用白名单或黑名单来列示 POJO 服务中的一组方法。要设置白名单和黑名单,请使用 POJO 元素中的 methods 元素的 filter 特性。filter 的值可以是 whitelisting 和 blacklisting。如果未指定 filter,那么将列示所有方法。如以下示例所示,可以通过指定 POJO 服务以白名单方式列示 AddressLookup 类的 getAddress 方法。
此示例演示使用 RPC 适配器只能访问 AddressLookup 类的 getAddress。也可以采用黑名单方式来列示同一个方法,如以下示例所示。
这个示例演示可使用 RPC 适配器来访问 AddressLookup 类中除 getAddress 以外的所有方法。如果未指定 POJO 服务的 methods 元素或者未对 methods 元素指定 filter 特性,那么在缺省情况下,将采用白名单方式列示所有方法。
在许多情况下,您可能需要在正从 JavaScriptTM 中调用的方法中访问 HttpServletRequest 对象。这可以通过将 HttpServletRequest 用作方法调用中的第一个参数在 RPC 适配器中实现此目标。返回的简单方法描述 (SMD) 未将 HttpServletRequest 对象用作参数,在 JavaScript 中,可以在不传递此参数的情况下调用方法。例如,对于 putNameInSession(HttpServletRequest req, String name) 方法,将显示以下相应的 XML。
验证器是在 RPC 适配器配置文件中使用 validators 元素定义的。您可以为各个 POJO 服务指定一组验证器。在调用一个方法之前,将使用该方法的参数来调用所指定验证器的 validate 方法。您可以对每个方法参数指定不同的验证器。所有验证器都扩展抽象类 com.ibm.websphere.rpcadapter.Validator。另外,您还可以使用正则表达式来执行验证。可以使用 validation-regex 元素来指定与参数值相匹配的正则表达式。如果参数值与该正则表达式不匹配,那么将发生验证错误。
发生验证错误将导致以 JSON 格式返回一个 Error 对象。此信息可用于错误处理。下面是对各个字段的描述。
RPC 适配器现在支持为它所呈示的对象指定作用域。RPC 适配器支持三个不同的作用域,即 Request、Session 和 Application,您可以指定这些作用域以便在请求、会话或应用程序中存储所呈示的对象。将作用域设置为 Application 或 Session 时,还有一个好处就是,不用每次都重新创建对象,而只需在 Session 或 Application 作用域中查询该对象。使用的键的格式为“com.ibm.websphere.rpcadapter:ServiceName”,其中 ServiceName 是所呈示的对象的名称。为了指定此键,为每个对象都提供了 scope 标记,此标记可以包含下列值:Session、Request 和 Application。请参阅以下示例。
现在,RPC 适配器支持将返回值添加到会话。为了添加此值,需要按如下方式添加 <add-to-session> 标记。
RPC 适配器现在支持复杂对象,例如可以包含其他对象的对象。支持将复杂对象用作返回类型以及方法参数。RPC 适配器现在可以将任何类型的复杂对象序列化。不支持将 Map 和 Collection 用作方法调用的参数。这是因为,无法仅仅根据 Map 或 Collection 的内容来确定它所包含的对象的类。此支持将需要类提示或参数化类型,因此目前尚未受支持。并且,尽管支持复杂返回类型,但是不能通过 HTTP-RPC 来调用具有复杂参数的方法。
这是复杂对象支持的特例。例如,A -> B -> A;或者 A 包含 B,而 B 又包含 A。产品 RPC 适配器组件通过将重复出现的对象替换为 $jref(JSON 序列化)或 $xref(XML 序列化)占位符来处理这种情况。这些占位符包含可以用来查询原始对象的信息,即 XPath 表达式(对于 XML)或 JavaScript 表达式(对于 JSON)。您可以通过将 <recursive-object-support> 标记的值设置为 true 来启用递归对象处理支持。以下示例说明了这种情况。
通常,需要呈示的对象包含应用程序开发者不想通过 JSON 或 XML Web Service 来呈示的特定字段。RPC 适配器能够让这些字段不在返回的对象中出现。您可以通过 <serialized-params> 标记来启用此项字段抑制功能。下面提供了用于阻止呈示 com.ibm.Address 类的 postalCode 字段的配置。此配置将导致 com.ibm.Address 类的 postalCode 字段永远不会被序列化。
用户可以对类指定别名。在进行 XML 序列化期间,别名将用作节点名。以下示例说明如何配置地址的别名。
用户可以对 JSON/XML 指定转换器。如果对某个类指定了转换器,那么可以将该转换器用于该类的 JSON/XML
序列化。所有转换器类都需要实现 com.ibm.websphere.rpcadapter.converters.IConverter
接口。缺省情况下,RPC 适配器附带提供了下列转换器。
转换器 | 用法 |
com.ibm.websphere.rpcadapter.converters.sql.Date
|
将 java.sql.Date 转换为日期和时间字符串。 |
com.ibm.websphere.rpcadapter.converters.sql.Time
|
将 java.sql.Time 转换为日期和时间字符串。 |
com.ibm.websphere.rpcadapter.converters.sql.TimeStamp
|
将 java.sql.TimeStamp 转换为日期和时间字符串。 |
com.ibm.websphere.rpcadapter.converters.util.Date
|
将 java.util.Date 转换为日期和时间字符串。 |
您可以在 RpcAdapterConfig.xml 中指定类似于以下示例的转换器。通过将 <subclass-support> 标记之间的值设置为 true,可以使用此标记来指定,转换器类应该转换所指定 Bean 类的子类。缺省情况下,此值设置为 false。
为了确保安全,使用 RPC 适配器将方法作为 JSON Web Service 呈示时,可以将 RPC 适配器配置为发出已将 JSON 注释过滤掉的输出(例如,括在“/*”和“*/”中的 JSON 数据)。Dojo 能够在客户机端处理这种已将注释过滤掉的 JSON。缺省情况下,此功能在 RPCAdapter 中处于禁用状态。您可以通过在 RPCAdapterConfig.xml 文件中将 filtered 标记设置为 true 来启用此功能,如以下示例所示。
RPC 适配器中的安全性支持是使用 Java EE Web 安全性实现的。所有已配置为要向客户机呈示的服务都将具有唯一的 URL。对这些 URL 进行的访问受 Java EE Web 安全性所限制。这涉及在应用程序服务器中创建一个安全域,然后在部署描述符文件 web.xml 中定义对不同 URL 的基于角色的访问权,然后使用特定于服务器的配置将这些角色映射至安全域中的用户或组。对于批处理调用,不能单独使用此功能。
除 Java EE Web 安全性以外,还可以配置 RPCAdapter 以便为呈示的服务执行授权检查,从而只允许访问 web.xml 或 geronimo-web.xml 中定义的特定角色。要使用此功能,应该通过 web.xml 来保护 URL 模式“/RPCAdapter/*”。下一步涉及使用 <role> 标记来指定是否只允许特定角色的用户访问相应的服务。您应该注意,当 RPCAdapter 执行服务授权时,应用程序仍负责在调用受保护服务之前认证用户。如果未在调用受保护服务之前执行认证,那么 RPCAdapter 将不允许访问相应的服务。这仅适用于服务中已列入白名单的方法。您可以按如下方式来控制对服务进行的访问。
用户可以使用 BatchService API 对一组调用进行批处理。可以创建、初始化并接着提交新的批处理服务工厂,如下所示。
通过在 RpcAdapterConfig.xml 文件中对重载的给定方法指定唯一的名称以及相应的参数类型,可以呈示重载的方法。
可以对方法指定与 Java 实现中使用的实际名称不同的名称。您可以通过以类似于方法重载的方式使用 <alias> 和 <name> 标记来完成此任务。唯一的例外是,如果未重载方法,那么不必指定参数类型。
要通过 RPCAdapter 来访问企业 Bean,请在 RPCAdapterConfig.xml 中指定 EJB 模块的必需信息。EJB 模块中的方法将被呈示,并且,您可以直接从 JavaScript 中调用方法。
要通过 RPCAdapter 来访问会话 Bean,请指定远程接口和本地接口、用于查找 EJB 模块的
JNDI 名称以及所实现的方法。对于 EJB 3.0 而言,远程接口和本地接口将被通常称为业务接口的单一接口替换。因此,请使用
<business-interface> 标记来指定业务接口。<ejb-name>
标记用于使逻辑名与 EJB 模块相关联。<jndi-name> 用于查找
EJB 模块。用户在 RPCAdapterConfig.xml 文件中指定的 JNDI 名称必须与 web.xml 文件中指定的
JNDI 名称匹配。对于 EJB 3.0,如果使用的应用程序服务器是 WebSphere® Application Server Community Edition,请对
JNDI 名称添加前缀“java:comp/env/”。对于 WebSphere Application Server,如果正在使用
EJB3.0,那么必须对 <jndi-name> 标记中的 JNDI 名称添加“ejblocal:”关键字作为前缀。您必须使用
<session-type> 标记来提供会话 Bean 的类型,即 stateless 或 stateful。
以下示例展示 RPCAdapterConfig.xml 文件中无状态会话 Bean 的示例条目。
在有状态会话 Bean 中,Home 接口可以包含多个 create 函数。在这种情况下,请指定所要调用的 create 函数。请在 RPCAdapterConfig.xml 文件中使用 <create> 标记来声明 create 函数。EJB 2.1 的有状态会话 Bean 的代码片段如下所示。
注释支持允许您直接从代码中呈示服务,以代替在 RPCAdapterConfig.xml 文件中配置服务。为了启用此功能,本发行版提供了 RPCAdapter-annotation.jar 文件。请将这个 JAR 文件放入使用此功能的 Web 应用程序的 WEB-INF/lib 目录。您应该使用 @Pojo 对包含所要呈示的方法的类进行注释,并使用 @Method 和 @Params 注释对相应的方法进行注释。所注释的类将通过 web.xml 文件对 RPCAdapter 可视。请对 RPCAdapter 指定所注释的类的规范名称作为“init-param”值。将相应的“init-param”名称指定为 classn,其中 n 是任意数字。以下是样本代码片段。
在 RPC 适配器中,输出格式为 JSON 或 XML。
下面列示不同情况下生成的各种 XML 输出。
如果返回类型为 void,那么生成的 XML 输出将是空结果标记,如下所示。
如果 JavaBeans 中的方法为 public int getSalary()
,那么输出将与以下示例类似:
public String getMessage()
,那么输出将与以下示例类似。public Boolean isLeapYear(int year)
,那么输出将与以下示例类似。
如果返回类型为集合,那么输出是一组元素,并且每个元素都表示集合中的一个条目。如果该集合包含已被抑制的对象类型的任何实例,那么该条目将被忽略。
public Collection getEmployees()
,并且返回的集合包含 Employee 实例,那么样本输出将与以下示例类似。如果返回类型为数组,那么输出是一组元素,并且每个元素都表示该数组中的一个条目。
public Employee[] getEmployees()
,并且返回的数组包含 Employee 实例,那么样本输出将与以下示例类似。
如果返回类型为映射,那么输出是一组元素,并且每个元素都表示该映射中的一个键值对。节点名为键。
如果 JavaBeans 中的方法为 public Map getDepartments()
,并且返回的映射是部门详细信息的部门代码的键值对,那么样本输出将与以下示例类似。
如果返回类型为 JavaBeans,那么将对所有 read 方法以及没有 read 方法的公用字段进行 XML 序列化。JavaBeans
由元素表示。此元素的节点名将是它所表示的 JavaBeans 的类型。如果对该 Bean 指定了任何别名,那么此别名将用作节点名。
如果 JavaBeans 中的方法为 public Employee getEmployee()
,那么样本输出将与以下示例类似。
下面说明各种情况下生成的各种 JSON 输出。
如果返回类型为 void,那么生成的 JSON 输出将为 JSON 结果对象。
public int getSalary()
,那么输出将与以下示例类似。public String getMessage()
,那么输出将与以下示例类似。public Boolean isLeapYear(int year)
,那么输出将与以下示例类似。如果返回类型为集合,那么输出是一组元素,并且每个元素都表示集合中的一个条目。如果该集合包含已被抑制的对象类型的任何实例,那么该条目将被忽略。
public Collection getEmployees()
,并且返回的集合包含 Employee 实例,那么样本输出将与以下示例类似。如果返回类型为数组,那么输出是一组元素,并且每个元素都表示该数组中的一个条目。
public Employee[] getEmployees()
,并且返回的数组包含 Employee 实例,那么样本输出将与以下示例类似。
如果返回类型为映射,那么输出将是一组键值对。
如果 JavaBeans 中的方法为 public Map getDepartments()
,并且返回的映射是部门详细信息的部门代码的键值对,那么样本输出将与以下示例类似。
JavaBeans 表示成键值对,其中,键是字段的名称,值是字段的值。将只对公用字段以及带有 getter 方法的字段进行序列化。
如果 JavaBeans 中的方法为 public Employee getEmployee()
,那么样本输出将与以下示例类似。
可以将 RPC 适配器配置为:(1) 对于每个请求,将 JavaBeans 实例化;(2) 对于每个用户,复用实例。(例如,可以将购物车对象配置为后一种情况。)缺省行为是,对于每个请求都实例化新的 JavaBeans。复用功能是通过 Bean 描述符信息来配置的。有关详细信息,请参阅 SampleBeanInfo API 文档。
在开发某些命令时,并没有期望将它们直接作为服务来呈示。在此类情况下,可以开发一个 JavaBeans 的访问器来包含隐含的逻辑。例如,PlantsByWebSphere 样本中的 ShoppingCart EJB 就包含 addItem(StoreItem item) 方法。StoreItem 对象包含商品价格,因此,此设计假定只有可信源才会调用该方法,例如 ShoppingServlet Servlet 中的以下示例。