使用 REST 和 Rest DSL

Rest DSL 绑定与配置

师成师成· 更新于 2026-09-28· 阅读 37 分钟· 0 次阅读

登录后可跨设备保存划线和私人笔记登录

Rest DSL - 绑定与配置

返回 Rest DSL

使用 POJO 进行绑定

Rest DSL 支持使用数据格式将 json/xml 内容自动绑定到 POJO 或从 POJO 反绑定。默认情况下,绑定模式是关闭的,也就是说,对于传入和传出的消息都不会进行自动绑定。

如果你开发的 POJO 与 REST 服务的请求和响应类型相对应,那么你可能希望使用绑定功能。这样,作为开发者,你就可以在 Java 代码中直接操作这些 POJO。

绑定模式有:

绑定模式说明
off关闭绑定。这是默认选项。
auto启用绑定,Caml 采用宽松模式,只要类路径中包含所需的数据格式,就支持 JSON、XML 或两者。请注意,例如若类路径中没有 camel-jaxb,则不会启用 XML 绑定。另外,对于 XML,默认使用 jaxb,若想改用 jackson XML,必须显式设置 xmlDataFormat=jacksonXml。
json启用与 JSON 之间的绑定,需要类路径中具备支持 JSON 的数据格式。默认情况下,Camel 会使用 jackson 作为数据格式。
xm启用与 XML 之间的绑定,需要类路径中有 camel-jaxb 或 camel-jacksonxml。
json_xml启用与 JSON 和 XML 之间的绑定,需要两种数据格式都在类路径中。
在 auto 绑定模式下,当传入请求没有 Content-Type 头(或该头未指明 JSON 或 XML)时,consumes 选项用作格式检测的回退依据。它不会拒绝 Content-Type 与 consumes 不匹配的请求。例如,配置为 .consumes("application/json").bindingMode(auto) 的端点,当客户端发送 Content-Type: application/xml 且 classpath 中存在支持 XML 的数据格式(例如 camel-jaxb)时,仍然会接受并反序列化 XML 请求。如果你需要强制要求 Content-Type 与 consumes 声明相匹配,可使用 clientRequestValidation(true) 启用客户端请求与响应校验,对于内容类型不匹配的请求将返回 HTTP 415。或者,使用显式的绑定模式(json 或 xml)来限制可用的数据格式。

使用 camel-jaxb 进行 XML 绑定时,你可以通过 mustBeJAXBElement 选项放宽输出消息体必须是带 JAXB 注解的类这一要求。当消息体本身已经是 XML 格式,并且你希望直接将消息体原样作为输出类型时,可以使用该选项。如果是这种情况,请将 dataFormatProperty 选项 mustBeJAXBElement 设置为 false。

从 POJO 到 JSON/JAXB 的绑定仅在 content-type 头分别包含 json 或 xml 字样时才会发生。这样,当你不希望消息体尝试通过绑定进行编组时,可以指定自定义的 content-type。例如,当消息体是自定义二进制负载等情况时。

当从 POJO 自动绑定到 JSON/JAXB 时,默认情况下现有的 content-type 请求头会被替换为 application/json 或 application/xml。若要禁用该默认行为,以便在生成 JSON/JAXB 响应时使用自定义的 content-type 请求头(例如 application/user.v2+json),可按如下方式配置:

  • Java
  • XML
  • YAML
restConfiguration().dataFormatProperty("contentTypeHeader", "false");
<restConfiguration>
   <dataFormatProperty key="contentTypeHeader" value="false"/>
</restConfiguration>

dataFormatProperty 中的 value 必须定义为字符串值,因此我们使用带引号的字符串 "false"。

- restConfiguration:
    dataFormatProperty:
      - key: "contentTypeHeader"
        value: "false"

要使用绑定功能,你必须在 classpath 中包含所需的数据格式依赖,例如 camel-jaxb / camel-jacksonxml 和/或 camel-jackson,然后启用绑定模式。你可以在 rest 配置上全局配置绑定模式,也可以针对每个 rest 服务单独覆盖。

若要使用 Jackson XML 进行 XML 绑定,则必须配置 xmlDataformat=jacksonXml,并在 classpath 中包含 camel-jacksonxml。

要启用绑定,可在 Java DSL 中按如下方式进行配置:

  • Java
  • XML
  • YAML
restConfiguration().component("netty-http").host("localhost").port(portNum).bindingMode(RestBindingMode.auto);
<restConfiguration bindingMode="auto" component="netty-http" port="8080"/>
- restConfiguration:
    bindingMode: "auto"
    component: "netty-http"
    port: "8080"

启用绑定后,Camel 会根据消息的内容类型自动绑定传入和传出的消息。如果消息是 JSON,则执行 JSON 绑定;如果消息是 XML,则执行 XML 绑定。绑定同时适用于传入消息和回复消息。下表总结了传入消息和回复消息所发生的绑定情况。

消息体方向绑定模式消息体
XML传入auto,xml,json_xmlPOJO
POJO传出auto,xml, json_xmlXML
JSON传入auto,json,json_xmlPOJO
POJO传出auto,json,json_xmlJSON

使用绑定时,还必须配置要映射到的 POJO 类型。对于传入消息这是必填项,对于传出消息则是可选的。

当使用绑定模式 json、xml 或 json_xml 时,如果尚未显式配置,Camel 会根据模式自动在 rest 端点上设置 consumers 和 produces。例如,绑定模式为 json 且 outType 设置为 UserPojo,Camel 会将此 rest 端点定义为产出 application/json。

例如,要将 xml/json 映射到 POJO 类 UserPojo,可以按照如下方式进行:

  • Java
  • XML
  • YAML
// configure to use netty-http on localhost with the given port
// and enable auto binding mode
restConfiguration().component("netty-http").host("localhost").port(portNum).bindingMode(RestBindingMode.auto);

// use the rest DSL to define the rest services
rest("/users/")
    .post().type(UserPojo.class)
        .to("direct:newUser");
<restConfiguration component="netty-http" host="localhost" port="{{portNum}}" bindingMode="auto"/>

<rest>
  <post path="/users" type="com.foo.UserPojo">
    <to uri="direct:newUser"/>
  </post>
</rest>
- restConfiguration:
    component: "netty-http"
    host: "localhost"
    port: "{{portNum}}"
    bindingMode: "auto"
- rest:
    post:
      - path: "/users"
        to: "direct:newUser"
        type: "com.foo.UserPojo"

注意,我们使用 type 来定义传入的类型。我们还可以选择性地定义传出的类型(这可能是个好主意,这样既能从 DSL 中明确该类型,也能让工具和 JMX API 了解 REST 服务的传入与传出类型)。要定义传出类型,我们使用 outType,如下所示:

  • Java
  • XML
  • YAML
// configure to use netty-http on localhost with the given port
// and enable auto binding mode
restConfiguration().component("netty-http").host("localhost").port(portNum).bindingMode(RestBindingMode.auto);

// use the rest DSL to define the rest services
rest("/users/")
    .post().type(UserPojo.class).outType(CountryPojo.class)
        .to("direct:newUser");
<restConfiguration component="netty-http" host="localhost" port="{{portNum}}" bindingMode="auto"/>

<rest>
  <post path="/users" type="com.foo.UserPojo" outType="com.foo.CountryPojo">
    <to uri="direct:newUser"/>
  </post>
</rest>
- restConfiguration:
    component: "netty-http"
    host: "localhost"
    port: "{{portNum}}"
    bindingMode: "auto"
- rest:
    post:
      - path: "/users"
        to: "direct:newUser"
        type: "com.foo.UserPojo"
        outType: "com.foo.CountryPojo"

要使用数组来指定输入和/或输出,请在规范类名的末尾添加 [],如下所示:

  • Java
  • XML
  • YAML

注意我们在 Java 中是如何将其声明为数组类的。

// configure to use netty-http on localhost with the given port
// and enable auto binding mode
restConfiguration().component("netty-http").host("localhost").port(portNum).bindingMode(RestBindingMode.auto);

// use the rest DSL to define the rest services
rest("/users/")
    .post().type(UserPojo[].class).outType(CountryPojo[].class)
        .to("direct:newUser");
<restConfiguration component="netty-http" host="localhost" port="{{portNum}}" bindingMode="auto"/>

<rest>
  <post path="/users" type="com.foo.UserPojo[]" outType="com.foo.CountryPojo[]">
    <to uri="direct:newUser"/>
  </post>
</rest>
- restConfiguration:
    component: "netty-http"
    host: "localhost"
    port: "{{portNum}}"
    bindingMode: "auto"
- rest:
    post:
      - path: "/users"
        to: "direct:newUser"
        type: "com.foo.UserPojo[]"
        outType: "com.foo.CountryPojo[]"

UserPojo 只是一个普通的 POJO,带有 getter/setter,如下所示:

public class UserPojo {
    private int id;
    private String name;
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}

UserPojo 只支持 JSON,因为 XML 需要使用 JAXB 注解,所以如果想同时支持 XML,可以添加这些注解。

@XmlRootElement(name = "user")
@XmlAccessorType(XmlAccessType.FIELD)
public class UserPojo {
    @XmlAttribute
    private int id;
    @XmlAttribute
    private String name;
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}

通过 JAXB 注解,该 POJO 同时支持 JSON 和 XML 绑定。

Camel Rest-DSL 配置

Rest DSL 支持以下选项:

名称默认值类型描述
apiComponentString设置用作 REST API 的 Camel 组件名称(例如 swagger 或 openapi)
apiContextPathString设置 REST API 服务将要使用的前置 API 上下文路径。当使用诸如 camel-servlet 之类以上下文路径方式部署的 Web 应用程序的组件时,可以使用此选项。
apiHostString为 API 文档(例如 swagger 或 openapi)指定特定的主机名。可用于用该配置的主机名覆盖自动生成的主机名。
apiPropertiesMap设置 API 级别的附加选项
apiVendorExtensionfalseboolean是否在 Rest API 中启用厂商扩展。如果启用,Camel 会将额外信息作为厂商扩展(例如,以 x- 开头的键)包含进来,如路由 ID、类名等。并非所有第三方 API 网关和工具在导入你的 API 文档时都支持厂商扩展。
bindingModeoffRestBindingMode设置 REST 消费者要使用的绑定模式
clientRequestValidationfalseboolean是否启用客户端请求校验,检查:1) Content-Type 请求头是否与 Rest DSL 所消费的类型匹配;校验失败时返回 HTTP 状态码 415。2) Accept 请求头是否与 Rest DSL 所产生的类型匹配;校验失败时返回 HTTP 状态码 406。3) 是否缺少必需的数据(查询参数、HTTP 请求头、消息体);校验失败时返回 HTTP 状态码 400。4) 消息体解析错误(必须启用 JSON、XML 或自动绑定模式);校验失败时返回 HTTP 状态码 400。
clientResponseValidationfalseboolean是否检查 Camel 返回给客户端的响应:1) 状态码和 Content-Type 是否与 Rest DSL 的响应消息匹配。2) 检查是否包含 Rest DSL 响应消息头中预期的请求头。3) 如果响应体是 JSON,则检查其是否为有效的 JSON。检测到校验错误时返回 500。
componentString设置用作 REST 消费者的 Camel 组件名称
componentPropertiesMap设置组件级别的附加选项
consumerPropertiesMap设置消费者级别的附加选项
contextPathString设置 REST 服务将要使用的前置上下文路径。当使用诸如 camel-servlet 之类以上下文路径方式部署的 Web 应用程序的组件时,可以使用此选项;也可用于包含 HTTP 服务器的组件,如 camel-jetty 或 camel-netty-http。
corsHeadersMap设置在启用 CORS 时要使用的 CORS 请求头。
dataFormatPropertiesMap设置数据格式级别的附加选项
enableCORSfalseboolean指定是否启用 CORS,即 Camel 会自动在响应的 HTTP 请求头中加入 CORS 信息。此选项默认为 false。
enableNoContentResponsefalseboolean指定当响应包含空的 JSON 对象或 XML 根对象时,是否返回响应体为空的 HTTP 204。
endpointPropertiesMap设置端点级别的附加选项
hostString设置 REST 消费者要使用的主机名
hostNameResolverallLocalIpRestHostNameResolver设置用于解析主机名的解析器
inlineRoutestrueboolean内联 rest-dsl 中通过 direct 端点连接的路由。如果禁用,则 Rest DSL 中的每个服务都是独立的路由,意味着每个服务至少要有两条路由(rest-dsl,以及从 rest-dsl 连接的路由)。默认情况下,这使得 Camel 能够将其优化并内联为单条路由。不过,这要求使用 direct 端点,且每个服务的 direct 端点必须唯一。
jsonDataFormatString设置要使用的自定义 JSON 数据格式。注意:此选项仅用于设置数据格式的自定义名称,而不是引用已有的数据格式实例。
portint设置 REST 消费者要使用的端口
producerApiDocString设置 REST 生产者将使用的 API 文档(swagger API)的位置,用于校验 REST URI 和查询参数是否符合该 API 文档……​
producerComponentString设置用作 REST 生产者的 Camel 组件名称
schemeString设置 REST 消费者要使用的协议
skipBindingOnErrorCodetrueboolean当存在自定义 HTTP 错误码时,是否跳过输出绑定,而直接使用响应体。此选项默认为 true。
useXForwardHeaderstrueboolean是否使用 X-Forward 请求头为 Swagger 设置主机等信息。此选项默认为 true。
xmlDataFormatString设置要使用的自定义 XML 数据格式。注意:此选项仅用于设置数据格式的自定义名称,而不是引用已有的数据格式实例。

例如,要在端口 9091 上为 jetty 组件配置请求缓冲区,可以按如下方式进行:

  • Java
  • XML
  • YAML
restConfiguration().component("jetty").port(9091).componentProperty("requestBufferSize", "50000");
<restConfiguration component="jetty" port="9091">
  <componentProperty key="requestBufferSize" value="50000"/>
</restConfiguration>
- restConfiguration:
    component: "jetty"
    port: "9091"
    componentProperty:
      - key: "requestBufferSize"
        value: "50000"

如果尚未显式配置任何组件,Camel 将查找是否存在与 Rest DSL 集成的 Camel 组件,或者注册表中是否注册了 org.apache.camel.spi.RestConsumerFactory。若找到其中之一,便会使用它。

你可以在以下层级配置属性。

  • component(组件)—— 用于设置 Component 类上的任意选项。你也可以直接在组件上配置这些选项。
  • endpoint(端点)—— 用于设置端点层级的任意选项。许多 Camel 组件在端点层级提供了大量可供设置的选项。
  • consumer(消费者)—— 用于设置消费者层级的任意选项。
  • data format(数据格式)—— 用于设置数据格式的任意选项。例如,启用 JSON 数据格式的美化打印。
  • cors headers(CORS 头)—— 若启用了 CORS,可以设置自定义的 CORS 头。当前使用的默认值见下文。如果设置了自定义头,则该值优先于默认值。

同一层级可以设置多个选项,例如你可以配置两个组件选项、三个端点选项,等等。

OAuth Bearer 令牌校验

对于支持 OAuth Bearer 令牌校验的 HTTP 消费者组件,如 platform-http、servlet、jetty、netty-http 和 undertow,请通过 endpointProperty 设置 oauthProfile 端点选项:

  • Java
  • XML
  • YAML
restConfiguration()
    .component("netty-http")
    .endpointProperty("oauthProfile", "myprofile");
<restConfiguration component="netty-http">
  <endpointProperty key="oauthProfile" value="myprofile"/>
</restConfiguration>
- restConfiguration:
    component: netty-http
    endpointProperty:
      - key: oauthProfile
        value: myprofile

使用默认验证器实现时,请将 camel-oauth 组件添加到应用类路径中,并通过 camel.oauth.<profile>.* 属性来配置指定的 profile。OAuth 校验会在路由处理器之前执行。根据所选 HTTP 消费者的不同,传输层可能已经接收、解码或绑定了入站请求的部分内容。

对于有效的令牌,路由代码可以从交换属性中读取验证结果:

OAuthTokenValidationResult result = exchange.getProperty(
    "CamelOAuthTokenValidationResult",
    OAuthTokenValidationResult.class);

启用或禁用 Jackson JSON 功能

使用 JSON 绑定时,你可能希望开启或关闭特定的 Jackson 功能。例如,要禁用“遇到未知属性即失败”的行为(例如 JSON 输入中包含一个无法映射到 POJO 的属性),则可按如下方式通过 dataFormatProperty 进行配置:

  • Java
  • XML
  • YAML
restConfiguration().component("jetty").host("localhost").port(getPort()).bindingMode(RestBindingMode.json)
   .dataFormatProperty("json.in.disableFeatures", "FAIL_ON_UNKNOWN_PROPERTIES");

可以通过用逗号分隔各值来禁用更多功能,例如:

.dataFormatProperty("json.in.disableFeatures", "FAIL_ON_UNKNOWN_PROPERTIES,ADJUST_DATES_TO_CONTEXT_TIME_ZONE");

同样,你可以使用 enableFeatures 来启用相关功能,例如:

restConfiguration().component("jetty").host("localhost").port(getPort()).bindingMode(RestBindingMode.json)
   .dataFormatProperty("json.in.disableFeatures", "FAIL_ON_UNKNOWN_PROPERTIES,ADJUST_DATES_TO_CONTEXT_TIME_ZONE")
   .dataFormatProperty("json.in.enableFeatures", "FAIL_ON_NUMBERS_FOR_ENUMS,USE_BIG_DECIMAL_FOR_FLOATS");
<restConfiguration component="jetty" host="localhost" port="9090" bindingMode="json">
  <dataFormatProperty key="json.in.disableFeatures" value="FAIL_ON_UNKNOWN_PROPERTIES,ADJUST_DATES_TO_CONTEXT_TIME_ZONE"/>
  <dataFormatProperty key="json.in.enableFeatures" value="FAIL_ON_NUMBERS_FOR_ENUMS,USE_BIG_DECIMAL_FOR_FLOATS"/>
</restConfiguration>
- restConfiguration:
    component: "jetty"
    host: "localhost"
    port: "9090"
    bindingMode: "json"
    dataFormatProperty:
      - key: "json.in.disableFeatures"
        value: "FAIL_ON_UNKNOWN_PROPERTIES,ADJUST_DATES_TO_CONTEXT_TIME_ZONE"
      - key: json.in.enableFeatures
        value: "FAIL_ON_NUMBERS_FOR_ENUMS,USE_BIG_DECIMAL_FOR_FLOATS"

可用于在 Jackson 上启用和禁用功能的值,是以下三个 Jackson 2.x 类中枚举的名称

  • com.fasterxml.jackson.databind.SerializationFeature
  • com.fasterxml.jackson.databind.DeserializationFeature
  • com.fasterxml.jackson.databind.MapperFeature

默认 CORS 头

如果启用了 CORS,默认会使用「以下头」。你可以配置自定义 CORS 头,其优先级高于默认值。

键值
Access-Control-Allow-Origin*
Access-Control-Allow-MethodsGET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS, CONNECT, PATCH
Access-Control-Allow-HeadersOrigin, Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers
Access-Control-Max-Age3600

评论

登录后参与评论

正在加载评论…