Apache Camel REST DSL - 验证请求有效负载并返回错误响应 [英] Apache Camel REST DSL - Validating Request Payload and return error response

查看:38
本文介绍了Apache Camel REST DSL - 验证请求有效负载并返回错误响应的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用CamelHttpTransportServlet"公开一个休息服务,该服务接收订单并放置在 jms 队列中.该代码在快乐路径上运行良好并返回 200 响应.我编写了 Processor 来验证输入 JSON,并根据输入设置 http_response_code.

I am exposing a rest service using "CamelHttpTransportServlet" that receive orders and place in jms queue. The code works fine on happy path and returns 200 response. I have written Processor to validate the input JSON, and set http_response_code based on the input.

问题是 - 对于失败响应代码的无效请求 - 设置了 400,流继续到下一个路由并将数据推送到队列,而不是将 400 响应发送回调用应用程序.

The issue is - for invalid requests though failure response code - 400 is set, the flow continues to the next route and pushes the data to the queue instead of sending the 400 response back to the calling app.

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

有人可以告知这里缺少什么并在可能的情况下提供样本吗?

Can someone advise what is missing here and provide a sample if possible?

尝试实现 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");

但是我不知道如何将参数 - code,jsonObject 从处理器传递到 onException 块.

However I could not figure out how to pass the parameters - code,jsonObject from processor to onException block.

对此有帮助吗?这可行吗?

Any help on this? Is this feasible?

推荐答案

我会使用类似于以下代码示例的内容:

I'd use something along the lines of the code example below:

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

Camel 将存储在交易所的属性中捕获的任何异常,因此应该可以通过 Exchange.EXCEPTION_CAUGHT 属性键获得.下面的示例说明了此类自定义错误消息 bean 的外观:

Camel will store any exception caught in the exchange's property and should be therefore obtainable via the Exchange.EXCEPTION_CAUGHT property key. The sample below illustrates how such a custom error message bean can look like:

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

Camel 提供了几种实际处理异常的方法.这里介绍的方式只是一个例子.然而,提议的代码允许对不同的捕获异常以及其他内容使用自定义重新传递策略.如果错误可以在异常处理程序中得到解决,则路由将在异常发生时继续执行(即应用重新传递策略的临时网络问题).如果错误无法在处理程序中得到修复,则交换将停止.通常,人们会将当前处理的消息发送到 DLQ 并记录有关错误的信息.

Camel provides a couple of ways actually to deal with exceptions. The presented way here is just one example. The proposed code however allows to use custom redelivery strategies for different caught exceptions as well as additional stuff. If the error could get resolved within the exception handler, the route is proceeded at the point the exception occurred (i.e. temporary network issue with a redelivery strategy applied). If the error could not get fixed within the handler, the exchange will be stopped. Usually one would then send the currently processed message to a DLQ and log something about the error.

请注意,此示例将假定 CustomException未经检查的异常,因为处理器被更简单的 lambda 取代.如果您不能或不想使用这样的异常(或 lambda 表达式),请将 lambda 处理器替换为 new Processor() { @Override public void process(Exchange exchange) throws Exception { ... }} 构造.

Note that this example will assume that CustomException is an unchecked exception as the processor is replaced with a simpler lambda. If you can't or don't want to use such an exception (or lambda expressions) replace the lambda-processor with new Processor() { @Override public void process(Exchange exchange) throws Exception { ... } } construct.

这篇关于Apache Camel REST DSL - 验证请求有效负载并返回错误响应的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆