Integration

Spring Integration Custom Transformer Example

1. Introduction

Spring Integration provides a transformer mechanism to convert message payloads from one form to another between two channels. In this article, we will see how to implement a simple custom transformer.

2. Application

The application is a Spring Boot application in which a Map is sent to a message channel. A Spring Integration Transformer listens to the message channel, transforms the Map to a Ticket object and sends it to an output channel. Finally, the message is printed to stdout.

3. Environment

I have used the following technologies for this application:

  • Java 1.8
  • Spring Boot 1.5.10
  • Maven 3.3.9
  • Ubuntu 16.04 LTS

4. Source Code

This is a Maven-based project, so all the required libraries are declared in pom.xml

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.javacodegeeks.springintegration.transformer</groupId>
    <artifactId>simpletransformer</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>simpletransformer</name>
    <description>Demo project for Spring Boot</description>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.10.RELEASE</version>
        <relativePath /> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-integration</artifactId>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

Below is the domain object of the application. It has two fields ticketId and description, both of type String.

Ticket.java

package org.javacodegeeks.springintegration.transformer.simpletransformer.domain;

import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;

@Getter @Setter @NoArgsConstructor @ToString
public class Ticket {
	
	private String ticketId;
	
	private String description;

}

Also, the lombok annotations @Getter, @Setter, @NoArgsConstructor and @ToString are used to generate the getters and setters, the default constructor and the toString method.

In the below file, two channels “input” and “output” are configured, which get the DefaultChannel type.

transformer-context.xml

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
    xmlns:int="http://www.springframework.org/schema/integration"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
    http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd">

    <context:component-scan
        base-package="org.javacodegeeks.springintegration.transformer.simpletransformer" />

    <int:transformer input-channel="input" output-channel="output"
        ref="mapToObject" />

    <int:channel id="input" />
    <int:channel id="output">
            <int:queue />
    </int:channel>
</beans>

We also configure a Spring Integration transformer which listens to input channel and writes to the output channel using the MapToObject class to transform the input to output.

The below class is the custom transformer that we use in the application.

MapToObject.java

package org.javacodegeeks.springintegration.transformer.simpletransformer.util;

import java.util.Map;

import org.javacodegeeks.springintegration.transformer.simpletransformer.domain.Ticket;
import org.springframework.stereotype.Component;

@Component
public class MapToObject {

	public Ticket map(Map message) {
		Ticket ticket = new Ticket();
		ticket.setTicketId(message.get("ticketId"));
		ticket.setDescription(message.get("description"));

		return ticket;
	}
}

This class is annotated with @Component so that it is available for the Spring run time during classpath scanning to create beans . The map method takes a Java Map object as input parameter. It constructs a Ticket object and sets the values of its properties to the values from the input map. The method returns the Ticket object.

Below, is the main class of the application.

SimpleTransformerApplication.java

package org.javacodegeeks.springintegration.transformer.simpletransformer;

import java.util.HashMap;
import java.util.Map;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.integration.support.MessageBuilder;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.PollableChannel;

@SpringBootApplication
public class SimpletransformerApplication {

	public static void main(String[] args) {
		SpringApplication.run(SimpletransformerApplication.class, args);
		ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("transformer-context.xml");
		MessageChannel input = context.getBean("input", MessageChannel.class);
		PollableChannel output = context.getBean("output", PollableChannel.class);

		Map ticketMap = new HashMap();
		ticketMap.put("ticketId", "1001");
		ticketMap.put("description", "First ticket");
		System.out.println("Sent: " + ticketMap);
		
		input.send(MessageBuilder.withPayload(ticketMap).build());
		System.out.println("received " + output.receive().getPayload());
		
		context.close();
	}
}

From the configuration, it gets two beans: input of type MessageChannel and output of type PollableChannel. It then creates a Java HashMap object called ticketMap and sets the value for two keys, ticketId and description. The ticketMap is sent to the input channel. Behind the scene, the transformer object converts it to a Ticket object and writes it to the output channel. The method then invokes receive on the output channel, gets the object and writes it to stdout.

5. How To Run

At the command prompt, just run

$ mvn spring-boot:run.

You will see the following output:

Sent: {description=First ticket, ticketId=1001}
received Ticket(ticketId=1001, description=First ticket)

6. Conclusion

In this article, we have seen a simple custom transformer functionality that takes in a Java Map object and outputs a custom domain object. Spring Integration provides several built-in transformers for transformation: object-to-string, object-to-map-transformer, map-to-object transformer, json-to-object-transformer, object-to-json-transformer and so on. In the map method, we could transform the input object to any other form, say csv or pdf.

7. Download the Source Code

Download
You can download the full source code of this example here: simpletransformer.zip

Mahboob Hussain

Mahboob Hussain graduated in Engineering from NIT Nagpur, India and has an MBA from Webster University, USA. He has executed roles in various aspects of software development and technical governance. He started with FORTRAN and has programmed in a variety of languages in his career, the mainstay of which has been Java. He is an associate editor in our team and has his personal homepage at http://bit.ly/mahboob
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Back to top button