Sending Data to External Systems Using TCP with Spring Integration Data can be sent to external systems using various protocols such as HTTP, HTTP/2, and WebSockets. For minimal overhead, TCP communication is a viable alternative.
Before diving into TCP with Spring Integration, let’s first explore basic TCP communication using Netcat.
Setting Up a TCP Listener with Netcat
To create a TCP server that listens for incoming connections, open your terminal and execute the following command:
nc -l 127.0.0.1 8080
This command will start a TCP server on port 8080 of your local machine.
Sending Data to the TCP Server To send data to the server, open a new terminal window and execute the following command:
nc 127.0.0.1 8080
Now, both the server and client are connected via TCP. You can type messages, and they will be visible on both ends.
Using TCP in Spring Integration
Now that we understand the basics of TCP, let’s implement it using Spring Integration.
Create a new Spring project and add the spring-integration-ip package by including the following dependency in your pom.xml:
<!-- Add spring-integration-ip dependency -->
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-ip</artifactId>
<version>6.4.1</version>
</dependency>
Create a TCP Connection Factory Configuration
Create a new file named tcp-connection-factory.xml in the resources/META-INF directory and add the following content:
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/integration"
xmlns:ip="http://www.springframework.org/schema/integration/ip"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/integration/ip https://www.springframework.org/schema/integration/ip/spring-integration-ip.xsd
http://www.springframework.org/schema/integration https://www.springframework.org/schema/integration/spring-integration.xsd">
<!-- Serializer to handle data format -->
<beans:bean id="fastestWireFormatSerializer" class="org.springframework.integration.ip.tcp.serializer.ByteArrayCrLfSerializer"/>
<!-- Define client-side connection factory -->
<ip:tcp-connection-factory id="clientConnFactory"
type="client"
host="localhost"
port="8080"
single-use="false"
serializer="fastestWireFormatSerializer"
deserializer="fastestWireFormatSerializer"
so-timeout="10000"/>
<!-- Caching client connection factory -->
<beans:bean id="cacheTcp" class="org.springframework.integration.ip.tcp.connection.CachingClientConnectionFactory">
<beans:constructor-arg ref="clientConnFactory"/>
<beans:constructor-arg value="10"/>
<beans:property name="connectionWaitTimeout" value="1200"/>
</beans:bean>
<!-- Define inbound and outbound channels -->
<channel id="inbound"/>
<channel id="outbound"/>
<!-- Configure outbound adapter for sending messages -->
<ip:tcp-outbound-channel-adapter id="outAdapter.client"
channel="outbound"
auto-startup="true"
connection-factory="cacheTcp"/>
<!-- Configure inbound adapter for receiving replies -->
<ip:tcp-inbound-channel-adapter id="inAdapter.client"
channel="inbound"
auto-startup="true"
connection-factory="cacheTcp"/>
<!-- Service Activator to handle received messages -->
<service-activator input-channel="inbound" ref="runMethod" method="run"/>
</beans:beans>
Implement the Main Java Class
In your main Java class, you can write the following code to test the TCP communication:
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.integration.channel.DirectChannel;
import org.springframework.messaging.support.GenericMessage;
public class Main {
public static void main(String[] args) throws InterruptedException {
System.out.println("Starting server...");
// Load Spring context configuration
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("/META-INF/spring/integration/tcpClientServerDemo-conversion-context.xml");
// Retrieve the outbound channel bean
DirectChannel dc = context.getBean("outbound", DirectChannel.class);
// Send messages continuously
int i = 0;
while (true) {
dc.send(new GenericMessage<>("Hello World \r\n" + i++));
Thread.sleep(10);
}
}
// Method to handle received replies
public static void run(String resp) {
System.out.println("REPLY RECEIVED --- " + resp);
}
}
This configuration defines the connection factory for both the server and client. The client is configured to connect to localhost on port 8080. Channels: The inbound and outbound channels are used for receiving and sending messages, respectively. Service Activator: The runMethod bean is invoked when a message is received on the inbound channel.