- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我们在 Camel 中定义了一个路由,并且必须找出处理器中是否抛出异常。当我们只有一个处理器时,Camel 会在 sendBody() 方法中重新抛出异常。如果前面有拆分/聚合,则不会抛出异常。所以下面例子的结果是
before throwing Exception
after sendBody
如果我省略从 .split 到 .completionSize(1) 的所有内容,则输出为
before throwing Exception
Exception thrown
如果在拆分后发生异常,有什么想法可以查明吗?
private static final String DIRECT_START = "direct:start";
public static void main(String[] args) throws Exception {
CamelContext context = new DefaultCamelContext();
context.addRoutes(new RouteBuilder() {
@Override
public void configure() throws Exception {
from(DIRECT_START)
.split(body())
.aggregate(constant(true), new AggregationStrategy() {
public Exchange aggregate(Exchange oldExchange, Exchange newExchange) {
return oldExchange == null ? newExchange : oldExchange;
}
})
.completionSize(1)
.process(new Processor() {
public void process(Exchange exchange) throws Exception {
System.out.println("before throwing Exception");
exchange.setException(new Exception());
throw new Exception("my Exception");
}
});
}});
context.start();
ProducerTemplate producer = context.createProducerTemplate();
try {
producer.sendBody(DIRECT_START, Integer.valueOf(42));
System.out.println("after sendBody");
} catch (Exception e) {
System.out.println("Exception thrown");
}
context.stop();
}
为了事后检查异常,我们找到了解决方案。我们向 onException() 注册了一个 ErrorProcessor,它将状态设置到上下文属性中。
但这不会中断 producer.sendBody(..)。我们有超长时间运行的处理器,我们必须中断它们。
所以问题是,我们可以配置 Camel 以在 sendBody 中抛出 Exception 还是可以在 Exceptionhandler 中执行此操作?
最佳答案
我强烈推荐在 Camel in Action(第 8.3.5 节)中有一个很好的章节介绍 Splitter EIP 和异常处理。该部分解释说:
When using a custom AggregationStrategy with the Splitter, it's important to know that you're responsible for handling exceptions. If you don't propagate the exception back, the Splitter will assume you have handled the exception, and ignore it.
您已经使用了 split()
方法而不指定聚合器。在Camel documentation , 他们指定
The splitter will by default return the original input message
这意味着交换离开 split()
方法没有异常,因此不会将异常传播回您的调用代码。您从处理器抛出的异常在技术上位于拆分器内部。即使您使用了聚合器,它也没有与 split
关联调用,并且您还没有明确结束 split
用end()
.因此,当您的处理器抛出异常时,拆分器会忽略它,因为您没有提供聚合器来处理和传播异常。
我们可以通过将您的聚合策略传递给 split
来对此进行测试像这样调用作为参数:
.split(body(), new AggregationStrategy() {
public Exchange aggregate(Exchange oldExchange, Exchange newExchange) {
System.out.println("Aggregating");
return oldExchange == null ? newExchange : oldExchange;
}
})
.log("test") // inside the split/aggregator EIP
.end() // outside the split/aggregator EIP
.process(new Processor() {
public void process(Exchange exchange) throws Exception {
System.out.println("before throwing Exception");
throw new Exception("my Exception");
}
});
你会得到输出:
test
Aggregating
before throwing Exception
Exception thrown
如果您希望处理器位于拆分/聚合器 EIP 内,如下所示:
.split(body(), new AggregationStrategy() {
public Exchange aggregate(Exchange oldExchange, Exchange newExchange) {
System.out.println("Aggregating");
return oldExchange == null ? newExchange : oldExchange;
}
})
.process(new Processor() { // inside the split/aggregator EIP
public void process(Exchange exchange) throws Exception {
System.out.println("before throwing Exception");
throw new Exception("my Exception");
}
})
.end(); // outside the split/aggregator EIP
你会得到输出:
before throwing Exception
Aggregating
Exception thrown
请注意,在拆分/聚合器 EIP 中,聚合器是如何在抛出异常后运行的?这很重要,因为没有聚合器传递异常,拆分器将忽略它。为了使其工作,您需要在聚合器内正确传播您的异常。例如,在您的代码中,如果 newExchange
是包含一个异常,它会被忽略,因为你没有传播它。您需要更改聚合器以添加:
if (newExchange.getException() != null) {
oldExchange.setException(newExchange.getException());
}
注意:如果您有 onException()
在split EIP内部调用,设置异常处理中,调用getException()
时不再返回.所以如果你想处理你的异常,但仍然通过聚合器传播它们,你可以使用 exchange.getProperty(Exchange.EXCEPTION_CAUGHT);
您还可以使用 .stopOnException()
,像这样:
.split(body()).stopOnException()
.process(new Processor() { // inside the split/aggregator EIP
public void process(Exchange exchange) throws Exception {
System.out.println("before throwing Exception");
throw new Exception("my Exception");
}
});
这会导致拆分在出现异常时停止,并传播它。但是,当您在 stopOnException()
之后放置聚合器时,它不再有效。我不完全确定为什么。我猜这是因为聚合器改变了 exchange
对象。
另请注意,您无需在处理器中为交易所设置异常(exception)。当处理器抛出异常时,Camel 会为你做这件事。所以行 exchange.setException(new Exception());
在处理器中是没有必要的。
tl;dr 所以是的,您可以从拆分内部将异常传播到调用方法。您只需要确保它是通过与拆分关联的聚合器或设置 stopOnException()
完成的。 .这取决于您尝试通过拆分/聚合/处理实现的最佳方法是什么。
关于java - Camel split 后异常不会升级,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35338736/
在 R 中,您可以使用 strsplit在分隔符( split )上分割向量的函数如下: x <- "What is this? It's an onion. What! That's| Well
我的 .split(); 方法有问题。 我称这个函数为: get_content_ajax("html/settings.html", "#ajax", 1, "Settings page have
我是Elixir的新手。我正在尝试对字符串split的基本操作,如下所示 String.split("Awesome",""); 根据elixir document,它应该根据提供的模式split字符
当我使用 =arrayformula(split(input!G2:G, ",")) 时,为什么拆分公式没有扩展到整个列? 我只得到输入的结果!G2 单元格,而不是 G 列中的其余部分。其他公式如 =
我正在尝试制作一个名为 core-splitter 的元素,该元素在 1.0 中已弃用,因为它在我们的项目中起着关键作用。 如果您不知道 core-splitter 的作用,我可以提供一个简短的描述。
我很难尝试使用多个定界符将字符串拆分为列表。我可以像下面这样将它拆分两次: myString.split(':')[1].split('.') 然而,这看起来很不优雅。在我的脑海里,我想做这样的事情:
来自使用惊喜模块的推荐引擎的代码,我在任何地方都找不到答案。 最佳答案 根据您的目标,您可以使用 cross_validation方法,它将自动为您执行拆分。示例:cross_validate(alg
我正在制作一个有丝 split 模拟器,我希望它在细胞足够大并 split 时运行有丝 split 功能。当它分割时,我希望它能够将分割从初始 x 值(前一个单元格的 x)动画化为新的 x 值(右侧的
我有一个用于三个按钮的点击处理程序,在这个处理程序中我想提取所点击按钮的 ID。我有一行这样的代码: $('#switch button').click(function(){ var cla
我需要像这样分割一个字符串 var val = "$cs+55+mod($a)"; 放入数组 arr = val.split( /[+-/*()\s*]/ ); 问题是将分隔符保留为数组元素,如 ar
我在同一个 string 上使用 split() 和 split("") .但为什么 split("") 返回的元素数量少于 split()?我想知道在什么特定的输入情况下会发生这种情况。 最佳答案
我的代码中某处有错误,但看不到我做错了什么。 我拥有的是 facebook 用户 ID 的隐藏输入,它是通过 jQuery UI 自动完成填充的: 然后,我有一个 jQuery 函数,当单击链接将其
我正在寻找一个程序来读取字符串/文件并显示其中的前三个单词。 所以我尝试了: letter= "a,b,c" print(letter.split(',')[0]) 这对获取一个单词有效,但执行 [0
我有一个存储邮件的表 Mails(谁会想到... ;))。 通过 tinyint MailStatus,我决定这是 SentMail、Draft 还是 ReceivedMail。 现在我想知道 Tab
在我的优化探索中,我发现内置的 split() 方法比等效的 re.split() 方法快大约 40%。 虚拟基准(易于复制粘贴): import re, time, random def rando
我对split有一个奇怪的问题,因为默认情况下它不会将split放入默认数组中。 以下是一些玩具代码。 #!/usr/bin/perl $A="A:B:C:D"; split (":",$A); pr
我目前正在学习 JCL,并且正在使用 SORT 程序。作为练习,我想将一些输入记录拆分为属于同一 PDS 的多个成员。这是我的 JCL 代码: //FAILJ JOB //STEP1 EX
在苦苦挣扎了半小时之后,我在使用空格分割字符串时遇到了这种差异,具体取决于您使用的语法。 简单字符串: $line = "1: 2: 3: 4: 5: " 拆分示例1 -从1开始注意带有 token
我有一个像这样的字符串: 'Agendas / Schedules meetings and speakers 4 F 1928-1209 Box 2' 我正在尝试将其
我试图了解 r-tree 的工作原理,发现有两种类型的拆分:二次拆分和线性拆分。 线性和二次实际上有什么区别?在哪种情况下,一个会比另一个更受欢迎? 最佳答案 原始 R-Tree 论文在 3.5.2
我是一名优秀的程序员,十分优秀!