在Spring Integration中将JSON转换为对象数组

Mil*_*daD 2 java xml json arraylist spring-integration

我们从服务(http出站网关)以json格式返回对象数组,我们需要将其序列化回对象/ POJOS数组。首先,我们尝试通过将XML配置设置为来简单地序列化没有任何数组列表的POJO。

<int:json-to-object-transformer input-channel="testJsonToObjectChannel"
            output-channel="testChannel" type="com.that.service.service.test.ApplicationTestDomain" />
Run Code Online (Sandbox Code Playgroud)

并且让转换器和http出站网关都返回相同的对象。但是,在将其转换为“ ApplicationTestDomain” POJO数组之后,我们得到了堆栈跟踪中提到的错误,其中特别提到

"No converter found capable of converting from type java.util.ArrayList<?> to type com.that.service.service.test.ApplicationTestDomain"
Run Code Online (Sandbox Code Playgroud)

我们还尝试了一个简单的字符串数组,并且它们也成功地进行了序列化和反序列化,只有在我们尝试对对象数组进行序列化和反序列化时,才会出现问题。

任何需要做什么的想法都可以解决

以下是返回数组列表的服务

@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;
    }

}
Run Code Online (Sandbox Code Playgroud)

以下是接收数组列表的服务

@MessageEndpoint("applicationDataTransformer")
public class ApplicationTransformer {

    public ApplicationResponse transformData(ArrayList<ApplicationTestDomain> response) {
        return new ApplicationResponse();
    }
}
Run Code Online (Sandbox Code Playgroud)

以下是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"/>         
Run Code Online (Sandbox Code Playgroud)

以下是异常堆栈跟踪

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
Run Code Online (Sandbox Code Playgroud)

此致MilindaD

Art*_*lan 5

您在这里遇到的问题是您仅使用raw ,而java.util.ArrayList最终使用ArrayList<LinkedHashMap<String, Object>>而不是ArrayList<LinkedHashMap<String, ApplicationTestDomain>>

试试这个技巧:

type="com.that.service.service.test.ApplicationTestDomain[]"
Run Code Online (Sandbox Code Playgroud)

我们无法提供Class通用规范的一般停靠点。

但是,有了该数组技巧ArrayCollection当Framework适用Message于服务方法的参数时,应该自动将转换为。

从对方<int-http:outbound-gateway>提供expected-response-type-expression,可以退货ParameterizedTypeReference<?>

这是一个技巧,让他知道您想要的类型:

<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"/>
Run Code Online (Sandbox Code Playgroud)

有了这个,您RestTemplate当然可以使用Jackson将响应转换为所需的值。从这里开始,没有更多的理由可以使用<int:json-to-object-transformer>,因为您已经有了POJO列表。