搜索

61.7. Entity Writer Interceptor

download PDF

概述

本节介绍如何在客户端或服务器端 写入消息正文时截获实体拦截器。这通常可用于请求正文的通用转换,如加密和解密、压缩和解压缩。

WriterInterceptor 接口

javax.ws.rs.ext.WriterInterceptor 接口定义如下:

// Java
...
package javax.ws.rs.ext;

public interface WriterInterceptor {
    void aroundWriteTo(WriterInterceptorContext context)
            throws java.io.IOException, javax.ws.rs.WebApplicationException;
}

通过实施 WriterInterceptor 接口,您可以截获消息正文(实体 对象),因为它在服务器端或客户端上写入。您可以在以下任何一个上下文中使用实体拦截器:

  • 服务器端- 如果作为服务器端拦截器绑定,实体写器将截获响应消息正文,紧接在响应消息正文后再发送回客户端。
  • client side- 如果作为客户端侧拦截器绑定,实体写入器会截获请求消息正文,紧接在请求消息正文被封锁并发送到服务器。

WriterInterceptorContext 接口

WriterInterceptoraroundWriteTo 方法收到类型为 javax.ws.rs.ext.WriterInterceptorContext 的参数,可用于访问消息正文(实体 对象)和消息元数据。

WriterInterceptorContext 接口定义如下:

// Java
...
package javax.ws.rs.ext;

import java.io.IOException;
import java.io.OutputStream;

import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MultivaluedMap;

public interface WriterInterceptorContext extends InterceptorContext {

    void proceed() throws IOException, WebApplicationException;

    Object getEntity();

    void setEntity(Object entity);

    OutputStream getOutputStream();

    public void setOutputStream(OutputStream os);

    MultivaluedMap<String, Object> getHeaders();
}

InterceptorContext 接口

WriterInterceptorContext 接口也支持从基础 InterceptorContext 接口继承的方法。有关 InterceptorContext 的定义,请参阅 “InterceptorContext 接口”一节

客户端上的实现示例

要为客户端实施实体拦截器,请定义一个实现 WriterInterceptor 接口的类。

例如,以下代码显示了客户端侧的实体写器(优先级为 10)的示例,它将额外文本行附加到传出请求的消息正文中:

// Java
package org.jboss.fuse.example;

import java.io.IOException;
import java.io.OutputStream;

import javax.ws.rs.WebApplicationException;
import javax.ws.rs.ext.WriterInterceptor;
import javax.ws.rs.ext.WriterInterceptorContext;
import javax.annotation.Priority;

@Priority(value = 10)
public class SampleClientWriterInterceptor implements WriterInterceptor {

  @Override
  public void aroundWriteTo(WriterInterceptorContext interceptorContext)
          throws IOException, WebApplicationException {
    OutputStream outputStream = interceptorContext.getOutputStream();
    String appendedContent = "\nInterceptors always get the last word in.";
    outputStream.write(appendedContent.getBytes());
    interceptorContext.setOutputStream(outputStream);

    interceptorContext.proceed();
  }
}

服务器端的实现示例

要为服务器端实施实体拦截器,请定义一个实施 WriterInterceptor 接口的类,并使用 @Provider 注释给它添加注解。

例如,以下代码显示了服务器端的实体写器示例(优先级为 10),这会将额外的文本行附加到传出请求的消息正文中:

// Java
package org.jboss.fuse.example;

import java.io.IOException;
import java.io.OutputStream;

import javax.ws.rs.WebApplicationException;
import javax.ws.rs.ext.Provider;
import javax.ws.rs.ext.WriterInterceptor;
import javax.ws.rs.ext.WriterInterceptorContext;
import javax.annotation.Priority;

@Priority(value = 10)
@Provider
public class SampleServerWriterInterceptor implements WriterInterceptor {

  @Override
  public void aroundWriteTo(WriterInterceptorContext interceptorContext)
          throws IOException, WebApplicationException {
    OutputStream outputStream = interceptorContext.getOutputStream();
    String appendedContent = "\nInterceptors always get the last word in.";
    outputStream.write(appendedContent.getBytes());
    interceptorContext.setOutputStream(outputStream);

    interceptorContext.proceed();
  }
}

在客户端绑定 writer 拦截器

使用 JAX-RS 2.0 客户端 API,您可以在 javax.ws.rs. client.Client 对象或 javax.ws.rs.client.WebTarget 对象上直接注册实体拦截器。实际上,这意味着 writer interceptor 可以选择性地应用到不同的范围,以便只有特定的 URI 路径会受到拦截器的影响。

例如,以下代码演示了如何注册 SampleClientReaderInterceptor 拦截器,使其适用于使用 client 对象进行的所有调用:

// Java
...
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Invocation;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.Response;
...
Client client = ClientBuilder.newClient();
client.register(SampleClientReaderInterceptor.class);

有关使用 JAX-RS 2.0 客户端注册拦截器的详情,请参考 第 49.5 节 “配置客户端端点”

在服务器端绑定写器

要在服务器端 绑定 拦截器(即要将它安装到 Apache CXF 运行时中),请执行以下步骤:

  1. @Provider 注释添加到 writer interceptor 类,如以下代码片段所示:

    // Java
    package org.jboss.fuse.example;
    ...
    import javax.ws.rs.WebApplicationException;
    import javax.ws.rs.ext.Provider;
    import javax.ws.rs.ext.WriterInterceptor;
    import javax.ws.rs.ext.WriterInterceptorContext;
    import javax.annotation.Priority;
    
    @Priority(value = 10)
    @Provider
    public class SampleServerWriterInterceptor implements WriterInterceptor {
      ...
    }

    当写器实施加载到 Apache CXF 运行时中时,REST 实施会自动扫描加载的类,以搜索标有 @Provider 注解( 扫描阶段)。

  2. 在 XML 中定义 JAX-RS 服务器端点(例如,请参阅 第 18.1 节 “配置 JAX-RS 服务器端点”)时,将 writer interceptor 添加到 jaxrs:providers 元素中的供应商列表中。

    <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:jaxrs="http://cxf.apache.org/blueprint/jaxrs"
        xmlns:cxf="http://cxf.apache.org/blueprint/core"
        ...
    >
        ...
        <jaxrs:server id="customerService" address="/customers">
          ...
          <jaxrs:providers>
            <ref bean="interceptorProvider" />
          </jaxrs:providers>
          <bean id="interceptorProvider" class="org.jboss.fuse.example.SampleServerWriterInterceptor"/>
    
        </jaxrs:server>
    
    </blueprint>
    注意

    此步骤是 Apache CXF 的非标准要求。根据 JAX-RS 标准,严格说,@Provider 注释应全部是绑定拦截器所必需的。但是在实践中,标准方法有些不灵活,当许多库包含在大型项目中时,可能会导致禁止提供程序。

Red Hat logoGithubRedditYoutubeTwitter

学习

尝试、购买和销售

社区

关于红帽文档

通过我们的产品和服务,以及可以信赖的内容,帮助红帽用户创新并实现他们的目标。

让开源更具包容性

红帽致力于替换我们的代码、文档和 Web 属性中存在问题的语言。欲了解更多详情,请参阅红帽博客.

關於紅帽

我们提供强化的解决方案,使企业能够更轻松地跨平台和环境(从核心数据中心到网络边缘)工作。

© 2024 Red Hat, Inc.