我正在使用接收JMS队列的订单和位置的" Camelhttptransportservlet"公开REST服务。该代码在快乐路径上正常工作,并返回200个响应。我已经编写了处理器来验证输入JSON,并基于输入设置HTTP_Response_code。
问题是 - 对于无效的请求,尽管故障响应代码 - 设置了400个,但流程将继续到下一个路线,并将数据推到队列,而不是将400响应发送给调用应用程序。
。 rest("/ordermanagement")
.post("/order").to("direct:checkInput");
from("direct:checkInput")
.process(new Processor() {
@Override
public void process(final Exchange exchange) throws Exception {
String requestBody = exchange.getIn().getBody(String.class);
if(requestBody == "" || requestBody== null) {
exchange.getIn().setBody("{ "error": Bad Request}");
exchange.getIn().setHeader(Exchange.CONTENT_TYPE, "application/json");
exchange.getIn().setHeader(Exchange.HTTP_RESPONSE_CODE, 400);
}
}
})
.to("direct:sendToQ");
from("direct:sendToQ")
.to("jms:queue:orderReceiver")
.log("Sent to JMS");
有人可以建议这里缺少什么并在可能的情况下提供样本?
尝试实现Onexception方法:
rest("/ordermanagement")
.post("/order").to("direct:checkInput");
onException(CustomException.class).handled(true)
.setHeader(Exchange.HTTP_RESPONSE_CODE, code)
.setBody(jsonObject);
from("direct:checkInput")
.process(new Processor() {
@Override
public void process(final Exchange exchange) throws Exception {
String requestBody = exchange.getIn().getBody(String.class);
if(requestBody == "" || requestBody== null) {
throw CustomException(code, jsonObject)
}
}
})
.to("direct:sendToQ");
from("direct:sendToQ")
.to("jms:queue:orderReceiver")
.log("Sent to JMS");
但是,我无法弄清楚如何传递参数 - 代码,jsonobject从处理器到Onexception块。
对此有任何帮助吗?这是可行的吗?
我会按照以下代码示例的行使用:
onException(CustomException.class)
.handled(true)
.bean(PrepareErrorResponse.class)
.log("Error response processed");
rest("/ordermanagement")
.post("/order")
.to("direct:checkInput");
from("direct:checkInput")
.process((Exchange exchange) -> {
String requestBody = exchange.getIn().getBody(String.class);
if(requestBody == "" || requestBody== null) {
throw new CustomException(code, jsonObject);
}
})
.to("direct:sendToQ");
from("direct:sendToQ")
.to("jms:queue:orderReceiver")
.log("Sent to JMS");
骆驼将存储在Exchange属性中捕获的任何例外,因此应通过Exchange.EXCEPTION_CAUGHT
属性密钥获得。下面的示例说明了这种自定义错误消息bean的外观:
public class PrepareErrorResponse {
@Handler
public void prepareErrorResponse(Exchange exchange) {
Throwable cause = exchange.getProperty(Exchange.EXCEPTION_CAUGHT, Throwable.class);
if (cause instanceof CustomException) {
CustomException validationEx = (CustomException) cause;
// ...
}
Message msg = exchange.getOut();
msg.setHeader(Exchange.CONTENT_TYPE, MediaType.APPLICATION_JSON);
msg.setHeader(Exchange.HTTP_RESPONSE_CODE, 400);
JsonObject errorMessage = new JsonObject();
errorMessage.put("error", "Bad Request");
errorMessage.put("reason", cause.getMessage());
msg.setBody(errorMessage.toString());
// we need to do the fault=false below in order to prevent a
// HTTP 500 error code from being returned
msg.setFault(false);
}
}
骆驼提供了几种处理异常的方法。这里提出的方式只是一个例子。但是,提出的代码允许使用自定义的重新运输策略来用于不同的例外情况以及其他内容。如果错误可以在异常处理程序中解决,则在发生异常(即使用重新交付策略的临时网络问题(进行该路线。如果错误无法在处理程序中固定,则将停止交换。通常,然后有人将当前处理的消息发送到DLQ并记录有关错误的信息。
请注意,此示例将假定CustomException
是未选中的例外,因为处理器被更简单的lambda替换。如果您不能或不想使用这样的例外(或lambda表达式(,则用new Processor() { @Override public void process(Exchange exchange) throws Exception { ... } }
构造替换Lambda Prococessor。
这是一种方法。您可以使用choice
rest("/ordermanagement")
.post("/order").to("direct:checkInput");
from("direct:checkInput")
.process(exchange -> {
String requestBody = exchange.getIn().getBody(String.class);
if(requestBody == null || requestBody.equals("")) {
exchange.getIn().setBody("{ "error": Bad Request}");
exchange.getIn().setHeader(Exchange.CONTENT_TYPE, "application/json");
exchange.getIn().setHeader(Exchange.HTTP_RESPONSE_CODE, 400);
}
})
.choice()
.when(exchange -> {
Object header = exchange.getIn().getHeader(Exchange.HTTP_RESPONSE_CODE);
return header != null && header.equals(400);
})
.stop()
.otherwise()
.to("direct:sendToQ")
.endChoice();
from("direct:sendToQ")
.to("jms:queue:orderReceiver")
.log("Sent to JMS");
设置 route_stop 属性到处理器中的 true 应防止进一步流动并返回您的响应:
...
exchange.getIn().setBody("{ "error": Bad Request}");
exchange.getIn().setHeader(Exchange.CONTENT_TYPE, "application/json");
exchange.getIn().setHeader(Exchange.HTTP_RESPONSE_CODE, 400);
exchange.setProperty(Exchange.ROUTE_STOP, Boolean.TRUE);
...