2013-04-11 46 views
6

我正在实现RESTful服务(使用CXFRS组件),它应该为某些请求返回文件。每个文件都由其ID和扩展名获取,即restfulservice.com/path/file/1/pdf。一旦添加每个文件都不会改变。抓取后不应移动或删除文件,一般应同时访问它们。这里是我的骆驼上下文的一部分:Apache 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 

宇瞻骆驼的版本是2.10.4

任何帮助,将不胜感激

UPD1
Content Enricher页面存在警告,称“pollEnrich无法访问当前Exchange中的任何数据”。
好像pollEnrich不支持URL(link)指定的动态fileName:但是如果我添加fileName=${body}到文件URL

UPD2没有什么变化。路线在目前的时刻:

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
我试图实现自定义的处理器使用PollingConsumer动态文件名:

@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论坛的this文章中有描述。路由使用上面的处理器来使用文件。结果是一样的

回答

9

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

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

现在,它的工作就像一个魅力

+0

您可以显示DSL是什么样子使用自定义的处理器?有没有办法将自定义处理器传递给pollEnrich? – pimlottc 2015-02-03 22:52:11