如何在Spring Integration中使用int-http:outbound-gateway将object / json传递给post方法

时间:2016-12-06 08:35:48

标签: spring spring-integration

我们如何将对象或json从Activator传递到int-http:outbound-gateway。

以下是我的配置

<int:channel id="preparedData"/>
    <int:service-activator input-channel="preparedData" ref="writer" method="writeData" output-channel="CallbackChannel">       
    </int:service-activator>

    <int:channel id="CallbackChannel" />
    <int-http:outbound-gateway 
        request-channel="CallbackChannel" 
        http-method="POST" url="{url}" 
        extract-request-payload="true">     
        <int-http:uri-variable name="url" expression="headers['url']" />        
    </int-http:outbound-gateway>

我的激活器正在@RequestBody

中的一个控制器中的POST API中返回一个对象。

以上配置低于错误。

13:58:41.202 [task-scheduler-1] ERROR org.springframework.integration.handler.LoggingHandler - org.springframework.messaging.MessageHandlingException: HTTP request execution failed for URI [http://**myUrl**]; nested exception is org.springframework.web.client.HttpClientErrorException: 400 Bad Request

请建议。

EDIT1

如果我在Activator中以JSON格式转换我返回的MyObject,那么我将收到以下错误。

nested exception is java.lang.ClassCastException: java.lang.String cannot be cast to java.util.Map

修改2

当我将我的Activator的返回类型更改为使用键值对之一映射为&#39;输入&#39;和对象然后它抱怨如下。

HTTP request execution failed for URI [http://MYURL]; nested exception is java.lang.ClassCastException: com.******.MyObject cannot be cast to java.lang.String

2 个答案:

答案 0 :(得分:1)

<int-http:outbound-gateway>将所有辛勤工作委托给RestTemplate,默认情况下会附带HttpMessageConverter这一组:

    this.messageConverters.add(new ByteArrayHttpMessageConverter());
    this.messageConverters.add(new StringHttpMessageConverter());
    this.messageConverters.add(new ResourceHttpMessageConverter());
    this.messageConverters.add(new SourceHttpMessageConverter<>());
    this.messageConverters.add(new AllEncompassingFormHttpMessageConverter());

    if (romePresent) {
        this.messageConverters.add(new AtomFeedHttpMessageConverter());
        this.messageConverters.add(new RssChannelHttpMessageConverter());
    }

    if (jackson2XmlPresent) {
        this.messageConverters.add(new MappingJackson2XmlHttpMessageConverter());
    }
    else if (jaxb2Present) {
        this.messageConverters.add(new Jaxb2RootElementHttpMessageConverter());
    }

    if (jackson2Present) {
        this.messageConverters.add(new MappingJackson2HttpMessageConverter());
    }
    else if (gsonPresent) {
        this.messageConverters.add(new GsonHttpMessageConverter());
    }

    if (jackson2SmilePresent) {
        this.messageConverters.add(new MappingJackson2SmileHttpMessageConverter());
    }
    if (jackson2CborPresent) {
        this.messageConverters.add(new MappingJackson2CborHttpMessageConverter());
    }

我认为您的Object以某种方式转换为有线字节,您应该确保使用正确且适当的转换。这实际上取决于服务器(@RequestBody)的要求。

答案 1 :(得分:0)

以下是我的解决方案。

 <int:channel id="preparedData"/>
    <int:service-activator input-channel="preparedData" ref="writer" method="writeData" output-channel="CallbackChannel"/>

         <int:channel id="CallbackChannel"/>      
         <int:transformer input-channel="CallbackChannel"
                     output-channel="registrationQueue"
                     ref="transformer" method="doTransform"/>  

        <int:channel id="registrationQueue" />  
        <int:header-enricher input-channel="registrationQueue" output-channel="enricherOutput">
            <int:header name="contentType" value="application/json"/>
        </int:header-enricher>

        <int:channel id="enricherOutput" />
        <int-http:outbound-gateway 
                request-channel="enricherOutput" 
                http-method="POST" url="{url}" 
                extract-request-payload="true" 
                reply-channel="replyChannel" 
                message-converters="converter"
            <int-http:uri-variable name="url" expression="headers['url']" />
        </int-http:outbound-gateway>

        <util:list id="converter">
            <bean id="test" class="com.xx.rr.ttt.MyMessageConvertor" />
        </util:list>

 <int:channel id="replyChannel" />    
    <int:service-activator input-channel="replyChannel" ref="lastActivator"/>

必须使用以下代码添加转换器。

public class MyMessageConvertor extends AbstractHttpMessageConverter<MyMessageConvertor> {

    public static final Charset DEFAULT_CHARSET = Charset.forName("ISO-8859-1");


    public MyMessageConvertor() {
        this(DEFAULT_CHARSET);
    }

    public MyMessageConvertor(Charset defaultCharset) {
        super(defaultCharset, new MediaType("application", "json"), MediaType.ALL);     

    }   

    @Override
    protected boolean supports(Class<?> clazz) {    
        return true;
    }

    @Override
    protected MyResponse readInternal(Class<? extends MyResponse > clazz,
            HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException {

        return null;        
    }

    @Override
    protected void writeInternal(MyResponse t, HttpOutputMessage outputMessage)
            throws IOException, HttpMessageNotWritableException {

         ObjectMapper mapperObj = new ObjectMapper();
            String jsonStr = null;
            try {
                jsonStr = mapperObj.writeValueAsString(t);
            } catch (IOException e) {
                e.printStackTrace();
            }

        Charset charset = getContentTypeCharset(outputMessage.getHeaders().getContentType());
        StreamUtils.copy(jsonStr, charset, outputMessage.getBody());
        //System.out.println("outputMessage.getBody()" + outputMessage.getBody());      
    }

    private Charset getContentTypeCharset(MediaType contentType) {
        if (contentType != null && contentType.getCharset() != null) {
            return contentType.getCharset();
        }
        else {
            return getDefaultCharset();
        }
    }
}

我没有实现readInternal,因为我正在点击的网址没有返回reply-channelhttp:outbound-gateway以外的任何内容,这是强制属性,因为我必须添加一个并添加一个激活器正在完成这一流程。