59.3. 以编程方式添加拦截器

59.3.1. 添加拦截器的方法

拦截器可以通过以下方法之一附加到端点中:

  • InterceptorProvider API
  • Java 注解

使用 InterceptorProvider API,开发人员可以将拦截器附加到具有拦截器链的任何运行时组件,但它需要处理底层 Apache CXF 类。Java 注解只能添加到服务接口或服务实施中,但它们允许开发人员保留在 JAX-WS API 或 JAX-RS API 中。

59.3.2. 使用拦截器供应商 API

概述

拦截器可以使用任何实现在 拦截器供应商接口 中显示的 InterceptorProvider 接口的组件注册。

拦截器供应商接口

package org.apache.cxf.interceptor;

import java.util.List;

public interface InterceptorProvider
{
    List<Interceptor<? extends Message>> getInInterceptors();

    List<Interceptor<? extends Message>> getOutInterceptors();

    List<Interceptor<? extends Message>> getInFaultInterceptors();

    List<Interceptor<? extends Message>> getOutFaultInterceptors();
}

通过接口中的四个方法,您可以检索端点的拦截器链作为 Java List 对象。通过使用 Java List 对象提供的方法,开发人员可以在任何链中添加和移除拦截器。

流程

要使用 InterceptorProvider API 将拦截器附加到运行时组件的拦截器链,您必须:

  1. 使用拦截器要附加到的链,访问运行时组件。

    开发人员必须使用 Apache CXF 特定的 API 访问标准 Java 应用代码的运行时组件。通常可以通过将 JAX-WS 或 JAX-RS 工件转换为基础 Apache CXF 对象来访问运行时组件。

  2. 创建拦截器的实例。
  3. 使用正确的 get 方法来检索所需的拦截器链。
  4. 使用 List 对象的 add() 方法将拦截器附加到拦截器链。

    此步骤通常与检索拦截器链合并。

将拦截器附加到消费者

以编程方式将拦截器附加到消费者 显示将拦截器附加到 JAX-WS 消费者的入站拦截器链的代码。

以编程方式将拦截器附加到消费者

package com.fusesource.demo;

import java.io.File;
import java.net.URL;
import javax.xml.namespace.QName;
import javax.xml.ws.Service;

import org.apache.cxf.endpoint.Client;

public class Client
{
  public static void main(String args[])
  {
    QName serviceName = new QName("http://demo.eric.org", "stockQuoteReporter");
    Service s = Service.create(serviceName);

    QName portName = new QName("http://demo.eric.org", "stockQuoteReporterPort");
    s.addPort(portName, "http://schemas.xmlsoap.org/soap/", "http://localhost:9000/EricStockQuote");

    quoteReporter proxy = s.getPort(portName, quoteReporter.class);

    Client cxfClient = (Client) proxy;

    ValidateInterceptor validInterceptor = new ValidateInterceptor();
    cxfClient.getInInterceptor().add(validInterceptor);

    ...
  }
}

以编程方式将拦截器附加到消费者 中的代码执行以下操作:

为消费者创建一个 JAX-WS Service 对象。

在提供消费者的目标地址的 Service 对象中添加端口。

创建用于在服务提供商上调用方法的代理。

将代理转换为 org.apache.cxf.endpoint.Client 类型。

创建拦截器的实例。

将拦截器附加到入站拦截器链。

将拦截器附加到服务供应商

以编程方式将拦截器附加到服务供应商 显示将拦截器附加到服务提供商的出站拦截器链的代码。

以编程方式将拦截器附加到服务供应商

package com.fusesource.demo;
import java.util.*;

import org.apache.cxf.endpoint.Server;
import org.apache.cxf.frontend.ServerFactoryBean;
import org.apache.cxf.frontend.EndpointImpl;

public class stockQuoteReporter implements quoteReporter
{
  ...
  public stockQuoteReporter()
  {
    ServerFactoryBean sfb = new ServerFactoryBean();
    Server server = sfb.create();
    EndpointImpl endpt = server.getEndpoint();

    AuthTokenInterceptor authInterceptor = new AuthTokenInterceptor();

    endpt.getOutInterceptor().add(authInterceptor);
  }
}

以编程方式将拦截器附加到服务供应商 中的代码执行以下操作:

创建一个 ServerFactoryBean 对象,用于提供对底层 Apache CXF 对象的访问权限。

获取 Apache CXF 用来代表端点的服务器对象。

获取服务提供商的 Apache CXF EndpointImpl 对象。

创建拦截器的实例。

将拦截器附加到端点 ; 出站拦截器链。

将拦截器附加到总线

将拦截器附加到总线 显示将拦截器附加到总线入站拦截器链的代码。

将拦截器附加到总线

import org.apache.cxf.BusFactory;
org.apache.cxf.Bus;

...

Bus bus = BusFactory.getDefaultBus();

WatchInterceptor watchInterceptor = new WatchInterceptor();

bus..getInInterceptor().add(watchInterceptor);

...

将拦截器附加到总线 中的代码执行以下操作:

获取运行时实例的默认总线。

创建拦截器的实例。

将拦截器附加到入站拦截器链。

WatchInterceptor 将附加到由运行时实例创建的所有端点的入站拦截器链中。

59.3.3. 使用 Java 注解

概述

Apache CXF 提供四个 Java 注解,允许开发人员指定端点使用的拦截器链。与将拦截器附加到端点的其他方法不同,注解附加到应用程序级别的工件。所用的构件决定了注解的作用范围。

放置注解的位置

注解可以放在以下工件中:

  • 定义端点端点接口(SEI)

    如果注解放置在 SEI 上,则实施该接口的所有服务提供商以及所有使用 SEI 创建代理的用户都会受到影响。

  • 服务实施类

    如果注解放在实施类上,则使用实施类的所有服务提供商都将受到影响。

注解

该注解都位于 org.apache.cxf.interceptor 软件包中,在 表 59.2 “拦截器链注解” 中描述。

表 59.2. 拦截器链注解

注解描述

InInterceptors

指定入站拦截器链的拦截器。

OutInterceptors

指定出站拦截器链的拦截器。

InFaultInterceptors

指定入站故障拦截器链的拦截器。

OutFaultInterceptors

指定出站错误拦截器链的拦截器。

列出拦截器

拦截器列表使用 在链注解中列出拦截器的语法 中显示的语法指定为完全限定类名称列表。

在链注解中列出拦截器的语法

interceptors={"interceptor1", "interceptor2", ..., "interceptorN"}

示例

将拦截器附加到服务实现中 显示将两个拦截器附加到使用 SayHiImpl 所提供的逻辑的入站拦截器链的注解。

将拦截器附加到服务实现中

import org.apache.cxf.interceptor.InInterceptors;

@InInterceptors(interceptors={"com.sayhi.interceptors.FirstLast", "com.sayhi.interceptors.LogName"})
public class SayHiImpl implements SayHi
{
  ...
}