我编写了一个简单的测试应用程序,该应用程序从数据库中读取记录并将结果放入csv文件中。到目前为止,它工作正常,但列名(即标题)未放入 csv 文件中。根据文档,它应该放在那里。我也尝试过没有/有流媒体和拆分,但情况是一样的。
在第 182 行的骆驼单元测试中,标头明确地放在那里:https://github.com/apache/camel/blob/master/components/camel-csv/src/test/java/org/apache/camel/dataformat/csv/CsvDataFormatTest.java
如何在不需要迭代标头的情况下解决这个非常简单的问题?我也尝试了不同的设置,但都是一样的。例如,分隔符被认为是我设置的,但标题不是。也提前感谢您的回复。
我是这样使用 Camel 2.16.1 的:
final CsvDataFormat csvDataFormat = new CsvDataFormat();
csvDataFormat.setHeaderDisabled(false);
[...]
from("direct:TEST").routeId("TEST")
.setBody(constant("SELECT * FROM MYTABLE"))
.to("jdbc:myDataSource?readSize=100") // max 100 records
// .split(simple("${body}")) // split the list
// .streaming() // not to keep all messages in memory
.marshal(csvDataFormat)
.to("file:extract?fileName=TEST.csv");
[...]
编辑 1
我还尝试从 exchange.in 中添加标题。它们在HashSet中具有名称“CamelJdbcColumnNames”。我像这样将它添加到csvDataFormat中:
final CsvDataFormat csvDataFormat = new CsvDataFormat();
csvDataFormat.setHeaderDisabled(false);
[...]
from("direct:TEST").routeId("TEST")
.setBody(constant("SELECT * FROM MYTABLE"))
.to("jdbc:myDataSource?readSize=100") // max 100 records
.process(new Processor() {
public void process(Exchange exchange) throws Exception {
headerNames = (HashSet)exchange.getIn().getHeader("CamelJdbcColumnNames");
System.out.println("#### Process headernames = " + new ArrayList<String>(headerNames).toString());
csvDataFormat.setHeader(new ArrayList<String>(headerNames));
}
})
.marshal(csvDataFormat)//.tracing()
.to("file:extract?fileName=TEST.csv");
println() 打印列名,但生成的 cvs 文件不会。
EDIT2 我按照注释 1 中的建议将标题名称添加到正文中,如下所示:
.process(new Processor() {
public void process(Exchange exchange) throws Exception {
Set<String> headerNames = (HashSet)exchange.getIn().getHeader("CamelJdbcColumnNames");
Map<String, String> nameMap = new LinkedHashMap<String, String>();
for (String name: headerNames){
nameMap.put(name, name);
}
List<Map> listWithHeaders = new ArrayList<Map>();
listWithHeaders.add(nameMap);
List<Map> records = exchange.getIn().getBody(List.class);
listWithHeaders.addAll(records);
exchange.getIn().setBody(listWithHeaders, List.class);
System.out.println("#### Process headernames = " + new ArrayList<String>(headerNames).toString());
csvDataFormat.setHeader(new ArrayList<String>(headerNames));
}
})
该提案解决了这个问题,并感谢您,但这意味着 CsvDataFormat 并不真正可用。JDBC 查询之后的交换体包含一个来自 HashMap 的 ArrayList,其中包含表的一条记录。HashMap 的键是列的名称,值是值。因此,在 CsvDataFormat 中设置标头输出的配置值应该足以生成标头。您知道更简单的解决方案还是我在配置中遗漏了某些内容?
我使用 spring xml 的解决方案(但我希望有一个选项来提取顶部的标题:
使用Spring xml
<multicast stopOnException="true">
<pipeline>
<log message="saving table ${headers.tablename} header to ${headers.CamelFileName}..."/>
<setBody>
<groovy>request.headers.get('CamelJdbcColumnNames').join(";") + "\n"</groovy>
</setBody>
<to uri="file:output"/>
</pipeline>
<pipeline>
<log message="saving table ${headers.tablename} rows to ${headers.CamelFileName}..."/>
<marshal>
<csv delimiter=";" headerDisabled="false" useMaps="true"/>
</marshal>
<to uri="file:output?fileExist=Append"/>
</pipeline>
</multicast>
http://www.redaelli.org/matteo-blog/2019/05/24/exporting-database-tables-to-csv-files-with-apache-camel/
我通过覆盖 BindyCsvDataFormat 和 BindyCsvFactory 来做到这一点
public class BindySplittedCsvDataFormat extends BindyCsvDataFormat {
private boolean marshallingfirslLot = false;
public BindySplittedCsvDataFormat() {
super();
}
public BindySplittedCsvDataFormat(Class<?> type) {
super(type);
}
@Override
public void marshal(Exchange exchange, Object body, OutputStream outputStream) throws Exception {
marshallingfirslLot = new Integer(0).equals(exchange.getProperty("CamelSplitIndex"));
super.marshal(exchange, body, outputStream);
}
@Override
protected BindyAbstractFactory createModelFactory(FormatFactory formatFactory) throws Exception {
BindySplittedCsvFactory bindyCsvFactory = new BindySplittedCsvFactory(getClassType(), this);
bindyCsvFactory.setFormatFactory(formatFactory);
return bindyCsvFactory;
}
protected boolean isMarshallingFirslLot() {
return marshallingfirslLot;
}
}
public class BindySplittedCsvFactory extends BindyCsvFactory {
private BindySplittedCsvDataFormat bindySplittedCsvDataFormat;
public BindySplittedCsvFactory(Class<?> type, BindySplittedCsvDataFormat bindySplittedCsvDataFormat) throws Exception {
super(type);
this.bindySplittedCsvDataFormat = bindySplittedCsvDataFormat;
}
@Override
public boolean getGenerateHeaderColumnNames() {
return super.getGenerateHeaderColumnNames() && bindySplittedCsvDataFormat.isMarshallingFirslLot();
}
}
您使用 JDBC 从数据库中获取数据,因此您需要先将标头添加到消息正文中,以便它是第一行。来自 jdbc 的结果集只是数据,不包括标头。
问题内容: 我有一个简单的PHP脚本,正在尝试跨域CORS请求: 但是我仍然得到错误: 请求标头字段不允许 我有什么想念的吗? 问题答案: 不允许作为可接受的值,请参阅此处的Mozilla文档。 您应该发送可接受的标头(而不是如星号所示)而不是星号。
问题内容: 我尝试构建一个python脚本,该脚本发送带有用于提取结果的参数的POST。通过提琴手,我提取了我要返回的帖子请求。该网站仅使用https。 现在我的python脚本: 但是当我运行脚本时,出现以下错误: 问题答案: 非常感谢您链接到请求模块。太完美了。下面解决我的问题。
问题内容: 我正在尝试发送带有标头的XMLHttpRequest并添加FormData。有没有一种(优雅的)方式我可以做这样的事情: 问题答案: 您无法在发送时指定标题,因为该标题会被浏览器自动设置为。您也可以设置其他标题,请尝试以下操作:
问题内容: 我正在尝试发送跨域域并添加自定义的“授权”标头。请参见下面的代码。 错误: XMLHttpRequest无法加载{url}。请求标头字段Access-Control-Allow-Headers不允许授权。 我也尝试过: 在ajax请求中。 可能是jquery-ajax框架阻止了跨域身份验证?我怎样才能解决这个问题? 更新: 顺便说一句:是否有一种更安全的方法将auth.key存储在客户
以及一些我熟悉的头,如accept、accept-encoding等。 我正在使用.NET4.0来发出HTTP/HTTPS请求。当尝试添加这些以冒号开头的标头时,第一个项目会引发错误: 错误消息: 这是否意味着我需要升级到较新的.NET版本? 提前道谢。
您好,我想使用截取标题和正文参数向服务器发送删除请求。但我无法成功发送请求 我试过的 这是我的截击请求课 当我尝试此代码时,我收到400响应代码错误。如果有人可以帮助我,请告诉我。。这就是我做错的地方。谢谢 这里是我测试的deleteapi的屏幕截图,它工作正常。
我们什么时候应该在HttpRequest estMessage对象中使用标头而不是HttpClient中的标头?? 我们需要添加授权(总是在变化)和一些自定义标头(总是在变化) 问题 > 首选哪种方法 我是否应该向HttpClient添加公共头(所有请求都相同),并向HttpRequestMessage对象添加基于请求的头??
请问下, Notion这里的图标,带有箭头的和不带箭头的区别是什么呢?