【问题标题】:How to marshal to JSON/XML when an exception occurs with Camel rest-dslCamel rest-dsl 发生异常时如何编组为 JSON/XML
【发布时间】:2017-06-29 13:07:57
【问题描述】:

我有一个带有绑定的 REST-dsl 骆驼路由:json_xml 使用 .type() 和 outType()。当没有异常发生时,它工作得很好。即 json 输入给出 json 输出。 xml 输入给出 xml 输出。

但是,当我收到 IllegalArgumentException 时,我总是返回 XML。发生异常时,我创建了一个 ErrorResponse POJO。对于 json,CONTENT_TYPE 设置为“application/json”。发生异常时如何返回 POJO 并让骆驼编组到 JSON/XML(给定 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;
  }
}

【问题讨论】:

    标签: json rest apache-camel marshalling


    【解决方案1】:

    然后您需要将内容类型显式设置为 XML

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

    应该是

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

    【讨论】:

    • 我试过了,还是给xml Content-type: application/json; charset=UTF-8 使用 .setHeader(Exchange.CONTENT_TYPE, constant("application/json"))。骆驼虫?
    • .. 响应为 XML 格式,响应头为 Content-type: application/json; charset=UTF-8
    • 您需要设置skipBindingOnErrorCode=false,详情见camel.apache.org/rest-dsl
    • 我尝试设置skipBindingOnErrorCode=false 只能产生自定义JSON errorResponse。当我应该生成 XML 错误响应时,我收到以下错误: InvalidPayloadException:没有可用的类型:javax.xml.bind.JAXBElement 但具有值:no.name.dto.response.ErrorResponseDto@3c3a808 即使它有@XmlRootElement。似乎是因为 skipBindingOnErrorCode=false 选项在 ResponseDto 上设置了 jaxbContext 类。我该如何解决这个问题?
    • 我还尝试将 ErrorResponse POJO 包装在 JaxbElement(用于 XML)中,但出现以下错误:java.io.IOException: javax.xml.bind.MarshalException ......原因:javax.xml.bind.JAXBException:no.name.dto.response.ErrorResponseDto 在此上下文中未知
    【解决方案2】:

    发生错误是因为 outType 不是动态的。它似乎是一只骆驼虫。即:outType 必须是包含 OK 和 ERROR dto 的 XMLROOT。如果您使用带有 lax=true 的任何元素的 XMLroot(在这里您可以添加 ErrorDto 或 okResponseDto),则可以快速修复此问题。但它确实添加了一个不需要的元素。现在我们必须实现一个自定义的 contentNegotiator。

    这是当使用 skipBindingOnError 设置为 false 时。

    【讨论】:

      猜你喜欢
      • 2015-03-02
      • 1970-01-01
      • 1970-01-01
      • 2017-06-03
      • 1970-01-01
      • 1970-01-01
      • 2018-04-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多