We are returning an array of objects from a service (http outbound gateway) in json format and we need it serialized back into an array of objects/POJOS. First we tried simply serializing the POJO without any array lists by setting the XML configuration to
<int:json-to-object-transformer input-channel="testJsonToObjectChannel"
output-channel="testChannel" type="com.that.service.service.test.ApplicationTestDomain" />
and had both the transformer and the http outbound gateway return the same object. However after converting it to an array of "ApplicationTestDomain" POJOs we are getting the error mentioned in the stack trace where it notably mentions
"No converter found capable of converting from type java.util.ArrayList<?> to type com.that.service.service.test.ApplicationTestDomain"
We also tried a simple array of strings and they were succesfully serialized and deserialzed as well, the issue only comes up when we try to serialize and deserialize an array of objects.
Any idea on what needs to be done so that can be resolved
The following is the service which returns the array list
@Service("applicationTestService")
public class ApplicationTestService {
private static Logger logger = Logger.getLogger(ApplicationTestService.class);
public ArrayList<ApplicationTestDomain> getTestThatData(Message<?> inMessage){
ArrayList<ApplicationTestDomain> testData = new ArrayList<ApplicationTestDomain>();
ApplicationTestDomain testDomain = new ApplicationTestDomain();
testDomain.setId(1L);
testDomain.setTotalPrice(100.00D);
testDomain.setTotalTaxes(70.00D);
testDomain.setTotalAll(70D);
testData.add(testDomain);
return testData;
}
}
The following is the service which receives the array list
@MessageEndpoint("applicationDataTransformer")
public class ApplicationTransformer {
public ApplicationResponse transformData(ArrayList<ApplicationTestDomain> response) {
return new ApplicationResponse();
}
}
The following is the xml configuration
<int-http:outbound-gateway request-channel="applicationConfigurationRequest"
reply-channel="testJsonToObjectChannel"
url="http://localhost:8080/testapplication/services/application/testService"
http-method="GET"
expected-response-type="java.lang.String"/>
<int:json-to-object-transformer input-channel="testJsonToObjectChannel"
output-channel="testChannel" type="java.util.ArrayList" />
<int:transformer input-channel="testChannel"
ref="applicationDataTransformer"
method="transformData"
output-channel="applicationConfigurationResponse"/>
The following is the exception stack trace
at org.eclipse.jetty.io.nio.SelectChannelEndPoint$1.run(SelectChannelEndPoint.java:52)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:608)
at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:543)
at java.lang.Thread.run(Unknown Source)
Caused by: org.springframework.messaging.MessageHandlingException: org.springframework.expression.AccessException: Problem invoking method: public com.that.domain.service.hotelavailability.HotelAvailabilityResponse com.that.transformer.service.ApplicationTransformer.transformData(java.util.ArrayList)
at org.springframework.integration.handler.MethodInvokingMessageProcessor.processMessage(MethodInvokingMessageProcessor.java:78)
at org.springframework.integration.transformer.AbstractMessageProcessingTransformer.transform(AbstractMessageProcessingTransformer.java:64)
at org.springframework.integration.transformer.MessageTransformingHandler.handleRequestMessage(MessageTransformingHandler.java:68)
... 83 more
Caused by: org.springframework.expression.AccessException: Problem invoking method: public com.that.domain.service.hotelavailability.HotelAvailabilityResponse com.that.transformer.service.ApplicationTransformer.transformData(java.util.ArrayList)
at org.springframework.expression.spel.support.ReflectiveMethodExecutor.execute(ReflectiveMethodExecutor.java:67)
at org.springframework.expression.spel.ast.MethodReference.getValueInternal(MethodReference.java:122)
at org.springframework.expression.spel.ast.MethodReference.access$000(MethodReference.java:44)
at org.springframework.expression.spel.ast.MethodReference$MethodValueRef.getValue(MethodReference.java:258)
at org.springframework.expression.spel.ast.CompoundExpression.getValueInternal(CompoundExpression.java:84)
at org.springframework.expression.spel.ast.SpelNodeImpl.getTypedValue(SpelNodeImpl.java:114)
at org.springframework.expression.spel.standard.SpelExpression.getValue(SpelExpression.java:111)
at org.springframework.integration.util.AbstractExpressionEvaluator.evaluateExpression(AbstractExpressionEvaluator.java:159)
at org.springframework.integration.util.MessagingMethodInvokerHelper.processInternal(MessagingMethodInvokerHelper.java:268)
at org.springframework.integration.util.MessagingMethodInvokerHelper.process(MessagingMethodInvokerHelper.java:142)
at org.springframework.integration.handler.MethodInvokingMessageProcessor.processMessage(MethodInvokingMessageProcessor.java:75)
... 85 more
Caused by: org.springframework.core.convert.ConversionFailedException: Failed to convert from type java.util.ArrayList<?> to type java.util.ArrayList<com.that.service.service.test.ApplicationTestDomain> for value '[{id=1, totalPrice=100.0, totalTaxes=70.0, totalAll=70.0}]'; nested exception is org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type java.util.ArrayList<?> to type com.that.service.service.test.ApplicationTestDomain
at org.springframework.core.convert.support.ConversionUtils.invokeConverter(ConversionUtils.java:41)
at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:174)
at org.springframework.integration.util.BeanFactoryTypeConverter.convertValue(BeanFactoryTypeConverter.java:123)
at org.springframework.expression.spel.support.ReflectionHelper.convertArguments(ReflectionHelper.java:240)
at org.springframework.expression.spel.support.ReflectiveMethodExecutor.execute(ReflectiveMethodExecutor.java:57)
... 95 more
Caused by: org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type java.util.ArrayList<?> to type com.that.service.service.test.ApplicationTestDomain
at org.springframework.core.convert.support.GenericConversionService.handleConverterNotFound(GenericConversionService.java:291)
at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:177)
at org.springframework.core.convert.support.CollectionToCollectionConverter.convert(CollectionToCollectionConverter.java:85)
at org.springframework.core.convert.support.ConversionUtils.invokeConverter(ConversionUtils.java:35)
... 99 more
Regards, MilindaD
Your issues here that you just use raw
java.util.ArrayList
and you end up just withArrayList<LinkedHashMap<String, Object>>
, rather thanArrayList<LinkedHashMap<String, ApplicationTestDomain>>
.Try this trick:
The general stop here that we can't provide
Class
with generic specification.But with that array trick there should automatic conversion from
Array
toCollection
when Framework appiesMessage
to arguments of your service method.From other side
<int-http:outbound-gateway>
providesexpected-response-type-expression
, which can returnParameterizedTypeReference<?>
.Here is a trick how to let him know about your desired type:
Having this you allow to
RestTemplate
to convert response to the desired value using Jackson, of course. And from here there is no more reason to use<int:json-to-object-transformer>
, because you already have your List of POJOs.