问题描述
我们正在从服务(http出站网关)以json格式返回对象数组,我们需要将其序列化回对象/POJOS数组.首先,我们尝试通过将XML配置设置为
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" />
,并且转换器和http出站网关都返回相同的对象.但是,将其转换为"ApplicationTestDomain" POJO数组之后,我们在堆栈跟踪中发现了其中特别提到的错误
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();
}
}
以下是xml配置
<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"/>
以下是异常堆栈跟踪
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
关于,MilindaD
Regards,MilindaD
推荐答案
您在这里遇到的问题是,您仅使用原始的java.util.ArrayList
,最终仅使用ArrayList<LinkedHashMap<String, Object>>
而不是ArrayList<LinkedHashMap<String, ApplicationTestDomain>>
.
Your issues here that you just use raw java.util.ArrayList
and you end up just with ArrayList<LinkedHashMap<String, Object>>
, rather than ArrayList<LinkedHashMap<String, ApplicationTestDomain>>
.
尝试这个技巧:
type="com.that.service.service.test.ApplicationTestDomain[]"
此处的一般要点是我们无法为Class
提供通用规范.
The general stop here that we can't provide Class
with generic specification.
但是使用该数组技巧,当Framework将Message
应用于服务方法的参数时,应该自动将Array
转换为Collection
.
But with that array trick there should automatic conversion from Array
to Collection
when Framework appies Message
to arguments of your service method.
从另一面<int-http:outbound-gateway>
提供expected-response-type-expression
,它可以返回ParameterizedTypeReference<?>
.
From other side <int-http:outbound-gateway>
provides expected-response-type-expression
, which can return ParameterizedTypeReference<?>
.
这是一个技巧,如何让他知道您想要的类型:
Here is a trick how to let him know about your desired type:
<int:header-enricher>
<int:header name="expectedResponseType">
<int-groovy:script>
<![CDATA[
new org.springframework.core.ParameterizedTypeReference<List<com.that.service.service.test.ApplicationTestDomain>>() {}
]]>
</int-groovy:script>
</int:header>
</int:header-enricher>
<int-http:outbound-gateway request-channel="applicationConfigurationRequest"
reply-channel="testJsonToObjectChannel"
url="http://localhost:8080/testapplication/services/application/testService"
http-method="GET"
expected-response-type-expression="headers.expectedResponseType"/>
具有此功能,您当然可以允许RestTemplate
使用Jackson将响应转换为所需值.从这里开始,没有更多的理由使用<int:json-to-object-transformer>
,因为您已经有了POJO列表.
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.
这篇关于在Spring Integration中将JSON转换为对象数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!