高级技巧

本节介绍在某些情况下可能会有帮助的高级技术。

策略接口

在许多情况下,前面描述的配置足以启用通过 TCP/IP 的安全通信。但是,Spring 集成提供了一些策略接口来允许自定义和修改套接字工厂和套接字

  • TcpSSLContextSupport

  • TcpSocketFactorySupport

  • TcpSocketSupport

  • TcpNetConnectionSupport

  • TcpNioConnectionSupport

TcpSSLContextSupport 策略接口

以下清单显示了 TcpSSLContextSupport 策略接口

public interface TcpSSLContextSupport {

    SSLContext getSSLContext() throws Exception;

}

TcpSSLContextSupport 接口的实现负责创建 SSLContext 对象。框架提供的实现是 DefaultTcpSSLContextSupport前面已描述。如果您需要不同的行为,请实现此接口并为连接工厂提供对您类的实现的 Bean 的引用。

TcpSocketFactorySupport 策略接口

以下清单显示了 TcpSocketFactorySupport 策略接口的定义

public interface TcpSocketFactorySupport {

    ServerSocketFactory getServerSocketFactory();

    SocketFactory getSocketFactory();

}

此接口的实现负责获取对 ServerSocketFactorySocketFactory 的引用。提供了两个实现。第一个是用于非 SSL 套接字(未定义 ssl-context-support 属性时)的 DefaultTcpNetSocketFactorySupport。它使用 JDK 的默认工厂。第二个实现是 DefaultTcpNetSSLSocketFactorySupport。默认情况下,当定义了 ssl-context-support 属性时使用它。它使用该 Bean 创建的 SSLContext 来创建套接字工厂。

仅当 using-niofalse 时,此接口才适用。NIO 不使用套接字工厂。

TcpSocketSupport 策略接口

以下清单显示了 TcpSocketSupport 策略接口的定义

public interface TcpSocketSupport {

    void postProcessServerSocket(ServerSocket serverSocket);

    void postProcessSocket(Socket socket);

}

此接口的实现可以在创建套接字并应用所有配置的属性后但在使用套接字之前修改套接字。无论您是否使用 NIO,这都适用。例如,您可以使用此接口的实现来修改 SSL 套接字上支持的密码套件,或者您可以添加一个在 SSL 握手完成后收到通知的侦听器。框架提供的唯一实现是 DefaultTcpSocketSupport,它不会以任何方式修改套接字。

要提供您自己的 TcpSocketFactorySupportTcpSocketSupport 实现,请分别通过设置 socket-factory-supportsocket-support 属性为连接工厂提供对自定义类型 Bean 的引用。

TcpNetConnectionSupport 策略接口

以下清单显示了 TcpNetConnectionSupport 策略接口的定义

public interface TcpNetConnectionSupport {

    TcpNetConnection createNewConnection(Socket socket,
            boolean server, boolean lookupHost,
            ApplicationEventPublisher applicationEventPublisher,
            String connectionFactoryName) throws Exception;

}

调用此接口以创建类型为 TcpNetConnection(或其子类)的对象。框架提供了一个实现(DefaultTcpNetConnectionSupport),该实现默认情况下创建简单的 TcpNetConnection 对象。它有两个属性:pushbackCapablepushbackBufferSize。启用回推时,实现将返回一个子类,该子类将连接的 InputStream 包装在 PushbackInputStream 中。与 PushbackInputStream 默认值一致,缓冲区大小默认为 1。这允许反序列化程序将字节“取消读取”(回推)到流中。以下简单示例显示了它如何在委托反序列化程序中使用,该反序列化程序“窥视”第一个字节以确定要调用的哪个反序列化程序

public class CompositeDeserializer implements Deserializer<byte[]> {

    private final ByteArrayStxEtxSerializer stxEtx = new ByteArrayStxEtxSerializer();

    private final ByteArrayCrLfSerializer crlf = new ByteArrayCrLfSerializer();

    @Override
    public byte[] deserialize(InputStream inputStream) throws IOException {
        PushbackInputStream pbis = (PushbackInputStream) inputStream;
        int first = pbis.read();
        if (first < 0) {
            throw new SoftEndOfStreamException();
        }
        pbis.unread(first);
        if (first == ByteArrayStxEtxSerializer.STX) {
            this.receivedStxEtx = true;
            return this.stxEtx.deserialize(pbis);
        }
        else {
            this.receivedCrLf = true;
            return this.crlf.deserialize(pbis);
        }
    }

}

TcpNioConnectionSupport 策略接口

以下清单显示了 TcpNioConnectionSupport 策略接口的定义

public interface TcpNioConnectionSupport {

    TcpNioConnection createNewConnection(SocketChannel socketChannel,
            boolean server, boolean lookupHost,
            ApplicationEventPublisher applicationEventPublisher,
            String connectionFactoryName) throws Exception;

}

调用此接口以创建 TcpNioConnection 对象(或来自子类的对象)。Spring 集成提供了两个实现:DefaultTcpNioSSLConnectionSupportDefaultTcpNioConnectionSupport。使用哪一个取决于是否正在使用 SSL。一个常见的用例是子类化 DefaultTcpNioSSLConnectionSupport 并覆盖 postProcessSSLEngine。请参阅SSL 客户端身份验证示例。与 DefaultTcpNetConnectionSupport 一样,这些实现也支持回推。

示例:启用 SSL 客户端身份验证

要启用使用 SSL 时客户端证书身份验证,则技术取决于您是否使用 NIO。当您不使用 NIO 时,请提供自定义的 TcpSocketSupport 实现来后处理服务器套接字

serverFactory.setTcpSocketSupport(new DefaultTcpSocketSupport() {

    @Override
    public void postProcessServerSocket(ServerSocket serverSocket) {
        ((SSLServerSocket) serverSocket).setNeedClientAuth(true);
    }

});

(当您使用 XML 配置时,请通过设置 socket-support 属性来提供对您的 Bean 的引用)。

当您使用 NIO 时,请提供自定义的 TcpNioSslConnectionSupport 实现来后处理 SSLEngine,如下例所示

@Bean
public DefaultTcpNioSSLConnectionSupport tcpNioConnectionSupport() {
    return new DefaultTcpNioSSLConnectionSupport(serverSslContextSupport) {

            @Override
            protected void postProcessSSLEngine(SSLEngine sslEngine) {
                sslEngine.setNeedClientAuth(true);
            }

    }
}

@Bean
public TcpNioServerConnectionFactory server() {
    ...
    serverFactory.setTcpNioConnectionSupport(tcpNioConnectionSupport());
    ...
}

(当您使用 XML 配置时,从 4.3.7 版开始,请通过设置 nio-connection-support 属性来提供对您的 Bean 的引用)。