【问题标题】:Strange behavior when returning ObjectNode from IntegrationFlows从 IntegrationFlows 返回 ObjectNode 时的奇怪行为
【发布时间】:2016-02-12 08:27:47
【问题描述】:

当 ObjectNode 从 extractFramesFlow() 传递并到达 httpCallbackFlow() 时,HTTP 请求成功执行,JSON 格式的有效负载被“POST”到指定的“call_back”uri

 @Bean
public IntegrationFlow extractFramesFlow() {
    return IntegrationFlows.from(extractFramesChannel())
            .handle(ObjectNode.class, (payload, headers) -> {
        payload = validateFields(payload);
        String path = payload.get("path").asText();
        try {
            File moviePath = new File(path);
            ArrayNode arrayNode = mapper.createArrayNode();
            String imageType = payload.path("image_type").asText("JPG");
            String prefix = payload.path("prefix").asText();
            Tools.thumbnails(moviePath, payload.get("slice").asInt(), payload.get("scale").asInt(),
                    imageType, prefix, file -> arrayNode.add(file.toString()));
            payload.set("files", arrayNode);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return payload;
    }).enrichHeaders(h-> h.header("errorChannel", "asyncErrorChannel", true))
            .<ObjectNode, Boolean>route(p-> !p.hasNonNull("id"),
            m->m.channelMapping("true","httpCallbackFlow.input")
                    .channelMapping("false","uploadToS3Channel")).get();
}

@Bean
public IntegrationFlow httpCallbackFlow() {
    return f->f.handle(Http.<JsonNode>outboundChannelAdapter(m->m.getPayload().get("call_back").asText()));
}

但是,当一个 ObjectNode 从 handleAsyncErrors() 流链接并到达相同的 httpCallbackFlow() 时,我们会得到一个由

引起的异常

org.springframework.web.client.RestClientException: 无法写入请求:没有为请求类型 [com.fasterxml.jackson.databind.node.ObjectNode] 和内容类型 [application/x-java-serialized- 找到合适的 HttpMessageConverter目的] 在 org.springframework.web.client.RestTemplate$HttpEntityRequestCallback.doWithRequest(RestTemplate.java:811) 在 org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:594) 在 org.springframework.web.client.RestTemplate.execute(RestTemplate.java:572) 在 org.springframework.web.client.RestTemplate.exchange(RestTemplate.java:493) 在 org.springframework.integration.http.outbound.HttpRequestExecutingMessageHandler.handleRequestMessage(HttpRequestExecutingMessageHandler.java:382) ... 24 更多

@Bean
public IntegrationFlow handleAsyncErrors() {
    return IntegrationFlows.from(asyncErrorChannel())
            .<MessagingException>handle((p, h) -> {
                ObjectNode objectNode = mapper.createObjectNode();
                objectNode.put("call_back", "http://some.test.uri");
                return objectNode;
            }).channel("httpCallbackFlow.input").get();
}

尽管如此,我不知道为什么我们会通过相同的 IntegrationFlow 处理此异常。

【问题讨论】:

    标签: spring-integration


    【解决方案1】:

    错误流上的消息没有contentType 标头。

    这是带有MessagingException有效载荷的错误消息;它有2个属性; causefailedMessage

    大概您在主要流消息上有一个内容类型。您可以使用标题丰富器设置内容类型,或添加

    .<MessagingException, Message<?>>transform(p -> p.getFailedMessage())
    

    在您现有的错误处理程序之前,从失败的消息中恢复标头。

    【讨论】:

    • 感谢您的回复,您是对的。正如您所指出的,IntegrationFlow 接受来自 http 客户端的 POST 请求,并且其 contentType 标头值设置为“application/json”。消息被异步处理,结果将被发送回请求有效负载中定义的“call_back”URL,这是一个 JSON。以这种方式重用标头可能不是一个好习惯。
    • 是的;最好使用标头丰富器 (overwrite=true) 显式设置 contentType,而不是依赖某些上游组件设置它(例如从入站请求继承它)。
    猜你喜欢
    • 2012-08-12
    • 1970-01-01
    • 1970-01-01
    • 2019-01-24
    • 2013-12-11
    • 2012-12-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-04
    相关资源
    最近更新 更多