INT-3556: Payload Conversion Documentation
JIRA: https://jira.spring.io/browse/INT-3556 Clarify when a `GenericConverter` might be needed rather than a simple `Converter`.
This commit is contained in:
committed by
Artem Bilan
parent
96d18d43a7
commit
1018fcf361
@@ -16,13 +16,17 @@
|
||||
|
||||
package org.springframework.integration.channel;
|
||||
|
||||
import static org.hamcrest.Matchers.instanceOf;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertSame;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
@@ -31,13 +35,16 @@ import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.context.support.ConversionServiceFactoryBean;
|
||||
import org.springframework.context.support.GenericApplicationContext;
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.core.convert.converter.GenericConverter;
|
||||
import org.springframework.core.convert.support.DefaultConversionService;
|
||||
import org.springframework.core.convert.support.GenericConversionService;
|
||||
import org.springframework.integration.context.IntegrationContextUtils;
|
||||
import org.springframework.integration.support.converter.DefaultDatatypeChannelMessageConverter;
|
||||
import org.springframework.integration.support.utils.IntegrationUtils;
|
||||
import org.springframework.integration.test.util.TestUtils;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.MessageChannel;
|
||||
import org.springframework.messaging.MessageDeliveryException;
|
||||
import org.springframework.messaging.MessagingException;
|
||||
@@ -199,6 +206,23 @@ public class DatatypeChannelTests {
|
||||
channel.send(new ErrorMessage(new Exception("test")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void genericConverters() {
|
||||
QueueChannel channel = createChannel(Foo.class);
|
||||
DefaultConversionService conversionService = new DefaultConversionService();
|
||||
conversionService.addConverter(new StringToBarConverter());
|
||||
conversionService.addConverter(new IntegerToBazConverter());
|
||||
DefaultDatatypeChannelMessageConverter converter = new DefaultDatatypeChannelMessageConverter();
|
||||
converter.setConversionService(conversionService);
|
||||
channel.setMessageConverter(converter);
|
||||
assertTrue(channel.send(new GenericMessage<String>("foo")));
|
||||
Message<?> out = channel.receive(0);
|
||||
assertThat(out.getPayload(), instanceOf(Bar.class));
|
||||
assertTrue(channel.send(new GenericMessage<Integer>(42)));
|
||||
out = channel.receive(0);
|
||||
assertThat(out.getPayload(), instanceOf(Baz.class));
|
||||
}
|
||||
|
||||
|
||||
private static QueueChannel createChannel(Class<?> ... datatypes) {
|
||||
QueueChannel channel = new QueueChannel();
|
||||
@@ -207,4 +231,50 @@ public class DatatypeChannelTests {
|
||||
return channel;
|
||||
}
|
||||
|
||||
private static class Foo {
|
||||
|
||||
}
|
||||
|
||||
private static class Bar extends Foo {
|
||||
|
||||
}
|
||||
|
||||
private static class Baz extends Foo {
|
||||
|
||||
}
|
||||
|
||||
private static class StringToBarConverter implements GenericConverter {
|
||||
|
||||
@Override
|
||||
public Set<ConvertiblePair> getConvertibleTypes() {
|
||||
Set<ConvertiblePair> pairs = new HashSet<ConvertiblePair>();
|
||||
pairs.add(new ConvertiblePair(String.class, Foo.class));
|
||||
pairs.add(new ConvertiblePair(String.class, Bar.class));
|
||||
return pairs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
|
||||
return new Bar();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class IntegerToBazConverter implements GenericConverter {
|
||||
|
||||
@Override
|
||||
public Set<ConvertiblePair> getConvertibleTypes() {
|
||||
Set<ConvertiblePair> pairs = new HashSet<ConvertiblePair>();
|
||||
pairs.add(new ConvertiblePair(Integer.class, Foo.class));
|
||||
pairs.add(new ConvertiblePair(Integer.class, Baz.class));
|
||||
return pairs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
|
||||
return new Baz();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -593,8 +593,21 @@ any transaction configuration essentially allowing you to enhance the behavior o
|
||||
To register a Converter all you need is to implement
|
||||
<interfacename>org.springframework.core.convert.converter.Converter</interfacename>,
|
||||
<interfacename>org.springframework.core.convert.converter.GenericConverter</interfacename> or
|
||||
<interfacename>org.springframework.core.convert.converter.ConverterFactory</interfacename> and define it via
|
||||
convenient namespace support:
|
||||
<interfacename>org.springframework.core.convert.converter.ConverterFactory</interfacename>.
|
||||
</para>
|
||||
<para>
|
||||
The <classname>Converter</classname> implementation is the simplest and converts
|
||||
from a single type to another. For more sophistication, such as converting to a class hierarchy, you would
|
||||
implement a <classname>GenericConverter</classname> and possibly a <classname>ConditionalConverter</classname>.
|
||||
These give you complete access to the <emphasis>from</emphasis> and <emphasis>to</emphasis> type descriptors
|
||||
enabling complex conversions. For example, if you have an abstract class <classname>Foo</classname> that is
|
||||
the target of your conversion (parameter type, channel data type etc) and you have two concrete implementations
|
||||
<classname>Bar</classname> and <classname>Baz</classname> and you wish to convert to one or the other based
|
||||
on the input type, the <classname>GenericConverter</classname> would be a good fit. Refer to the JavaDocs for
|
||||
these interfaces for more information.
|
||||
</para>
|
||||
<para>
|
||||
When you have implemented your converter, you can register it with convenient namespace support:
|
||||
<programlisting language="xml"><![CDATA[<int:converter ref="sampleConverter"/>
|
||||
|
||||
<bean id="sampleConverter" class="foo.bar.TestConverter"/>]]></programlisting>
|
||||
|
||||
Reference in New Issue
Block a user