简体   繁体   中英

How to marshal to JSON/XML when an exception occurs with Camel rest-dsl

I have a REST-dsl camel route with binding: json_xml with .type() and outType(). It works perfectly when no exception occurs. That is json input gives json output. Xml input gives xml output.

However, when I get an IllegalArgumentException I always return XML. I create a ErrorResponse POJO when the exception occurs. The CONTENT_TYPE is set to "application/json" for json. How do I return a POJO and let camel marhal to JSON/XML when an Exception occurs(given ResBindingMode.json_xml)?

onException(IllegalArgumentException.class)
        .log(LoggingLevel.ERROR, LOGGER, "error")
        .handled(true)
        .setHeader(Exchange.HTTP_RESPONSE_CODE, constant(400))
        .setHeader(Exchange.CONTENT_TYPE, exchangeProperty(Exchange.CONTENT_TYPE))
        .bean(errorResponseTranslator);
restConfiguration().component("restlet").port(port).skipBindingOnErrorCode(true)
        .bindingMode(RestBindingMode.json_xml);
    rest("/whatever/api/v1/request")
        .post().type(RequestDto.class).outType(ResponseDto.class)
            .route()
            .setProperty(Exchange.CONTENT_TYPE, header(Exchange.CONTENT_TYPE))
           ...process

ErrorDto:

@XmlRootElement(name = "errorResponse")
@XmlAccessorType(XmlAccessType.PROPERTY)
public class ErrorResponseDto {
  private String errorCode;
  private String message;

  @XmlElement(name = "message")
  public String getMessage() {
      return message;
  }

  public void setMessage(String message) {
      this.message = message;
  }

  @XmlElement(name = "errorCode")
  public String getErrorCode() {
      return errorCode;
  }

  public void setErrorCode(String errorCode) {
      this.errorCode = errorCode;
  }
}

You need to set the content type explicit to XML then

 .setHeader(Exchange.CONTENT_TYPE, exchangeProperty(Exchange.CONTENT_TYPE))

Should be

 .setHeader(Exchange.CONTENT_TYPE, constant("application/json"))

The error occurs because the outType not dynamic. It seems like its a camel bug. That is: the outType must be an XMLROOT that contains OK and ERROR dto. It is possible to quickfix this if you use a XMLroot that takes an any element with lax=true(here you can add the ErrorDto or okResponseDto). But it does add an unwanted element. For now we have to implement a custom contentNegotiator.

This is when using skipBindingOnError is set to false.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM