Apache Camel REST DSL - Validating Request Payload and return error response

匆匆过客 提交于 2019-12-04 15:16:41

Here is one way to do it. You can use 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");
Roman Vottner

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 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 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.

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.

Setting ROUTE_STOP property to true in the processor should prevent further flow and return your response:

...
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);
...
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!