当前位置: 首页 > 知识库问答 >
问题:

Apache Camel根据请求使用文件内容丰富消息

景理
2023-03-14

我正在实现RESTful服务(使用CXFRS组件),它应该为某些请求返回文件。每个文件都是通过其id和扩展名获取的,即restfulservice.com/path/file/1/pdf。每个文件一旦添加就不会更改。文件在获取后不应移动或删除,通常它们应该可以同时访问。这是我的Camel上下文的一部分:

from("direct:fetchFile")
    .process(fetchFileProcessor) // set file.id & file.extension
    .bean(fileService, "fetchFile(${header.file.id}, ${header.file.extension})") // set body to filename
    .setHeader("CamelFileName", simple("${body}"))
    .choice()
        .when(header("file.extension").isEqualTo("xml"))
            .pollEnrich("file:///{{application.fileStorage.basePath}}/xml?noop=true", 500)
        .when(header("file.extension").isEqualTo("pdf"))
            .pollEnrich("file:///{{application.fileStorage.basePath}}/pdf?noop=true", 500)
    .end()
    .convertBodyTo(File.class)
    .bean(responseProvider, "getResponse(${body}, 200)");

此配置的问题是,响应只有第二个非空主体(为什么?)请求,无超时设置服务在第二个请求时进入永恒循环,并显示调试消息

DEBUG o.a.c.c.f.FileConsumer - Took 0.000 seconds to poll <base path>\xml

Apace Camel版本为2.10.4

任何帮助都将不胜感激

UPD1:
Content Enrich页面上有警告,称“pollEnrich无法访问当前Exchange中的任何数据”。但如果我将文件名=${body}添加到文件URL,则不会发生任何更改

UPD2:
看起来polenrich不支持URL(链接)中指定的动态fileName。当前时刻的路由:

from("direct:fetchFile")
    .process(fetchFileProcessor) // set file.id & file.extension
    .bean(fileService, "fetchFile(${header.file.id}, ${header.file.extension})") // set body to filename
    .choice()
        .when(header("file.extension").isEqualTo("xml"))
            .pollEnrich("file:///{{application.fileStorage.basePath}}/xml?fileName=${body}&noop=true", 500)
            .setHeader("asset.type", simple(MediaType.APPLICATION_XML))
        .when(header("file.extension").isEqualTo("pdf"))
            .pollEnrich("file:///{{application.fileStorage.basePath}}/pdf?fileName=${body}&noop=true", 500)
            .setHeader("asset.type", simple("application/pdf"))
    .end()
    .convertBodyTo(File.class)
    .process(multipartProcessor) // add file ass attachment to multipart body and set it as body
    .bean(responseProvider, "getResponse(${body}, 200)");

UPD3
我正在尝试实现自定义处理器以使用具有动态文件名的Polling消费者:

@Override
public void process(Exchange exchange) throws Exception {
    Long timeout = exchange.getIn().getHeader("file.timeout", Long.class);
    if (enrichUri == null) {
        throw new FileNotFoundException("'file.url' header not set");
    }

    CamelContext context = exchange.getContext();
    Endpoint endpoint = context.getEndpoint(enrichUri);
    PollingConsumer consumer = endpoint.createPollingConsumer();
    consumer.start();

    Exchange consumedExchange;
    try {
        if (timeout == null || timeout < 0) {
            consumedExchange = consumer.receive();
        } else if (timeout == 0) {
            consumedExchange = consumer.receiveNoWait();
        } else {
            consumedExchange = consumer.receive(timeout);
        }
    } catch (Exception e) {
        throw new AssetNotFoundException(e);
    } finally {
        consumer.stop();
    }
    exchange.getIn().setBody(consumedExchange.getIn().getBody());
}

现在,它在第一次响应时返回文件内容,但在每次后续请求中,我都会得到上面日志消息的永久循环:

DEBUG o.a.c.c.f.FileConsumer - Took 0.000 seconds to poll <base path>\xml

UPD4实现了动态路由,在处理之前添加,在处理之后删除。Apache Camel论坛的这篇文章描述了这种方法。路由使用上述处理器使用文件。结果是一样的

共有1个答案

柳浩大
2023-03-14

简单的方法往往是最好的方法。在这种情况下,我拒绝处理Apache Camel文件组件,并实现了以下处理器:

public class FileLoadingProcessor implements Processor {

@Override
public void process(Exchange exchange) throws Exception {
    String filename = exchange.getIn().getBody(String.class); // message body contains filename
    String filePath = exchange.getIn().getHeader("fileprocessor.filepath", String.class);

    if (filePath == null || filename == null) {
        // throw some custom exception
    }

    URI uri = new URI(filePath.concat(filename));
    File file = new File(uri);

    if (!file.exists()) {
        throw new FileNotFoundException(String.format("File %s not found on %s", filename, filePath));
    }

    exchange.getIn().setBody(file);
}

现在它就像一个魔咒

 类似资料:
  • 我有一个RESTful Webservice,我想在骆驼路上用它来丰富内容。参见类似的代码: 如果我运行这个,我会得到以下错误: < code >没有类型转换器可用于从type: de.my.Class转换为所需的type: java.io.InputStream,值为de.my.Class@620ee765。 在我看来,他试图将 Exchange 的主体发送到 http-Endpoint,尽管我

  • 有什么方法可以指定在编组时对此实例使用不同的命名空间吗?

  • 要表现色彩里的浓烈、富足感可藉由组合一个有力的色彩和它暗下来的补色。例如,深白兰地酒红色就是在红色中加了黑色,就像产自法国葡萄园里陈年纯美的葡萄酒,象征财富。白兰地酒红色和深森林绿如果和金色一起使用可表现富裕。这些深色、华丽的色彩用在各式各样的织料上,如皮革和波纹皱丝等等,可创造出戏剧性、难以忘怀的效果。这些色彩会给人一种财富和地位的感觉。 补色色彩组合 原色色彩组合 单色色彩组合 49 3 49

  • 在Spring Integration中,我有如下消息: 我需要使用一些Rest服务来丰富/转换这个消息,这将为我提供属性值。 例如会回答我 最后一个对象应如下所示: 如何实现这一点? 应该是这样吗?https://www.youtube.com/watch?time_continue=273 入站适配器-

  • 使用vertx http代理(https://github.com/eclipse-vertx/vertx-http-proxy),添加/插入自定义身份验证机制(例如基于客户端证书的LDAP身份验证和为后端目标填充授权基本标头)的最佳方式是什么?

  • 数据丰富是指用于增强,改进和改进原始数据的一系列过程。 它指的是有用的数据转换(原始数据到有用信息)。 数据丰富过程的重点是使数据成为现代企业或企业的宝贵数据资产。 最常见的数据丰富过程包括通过使用特定的决策算法来纠正数据库中的拼写错误或印刷错误。 数据丰富工具为简单数据表添加有用信息。 考虑以下代码进行单词拼写纠正 - import re from collections import Coun