Apache Camel指南-第十二章:定义REST服务

开发板推荐:天空星STM32F407VET6开发板

超高性价比 STM32主控 | 超高主频 | 一板兼容百芯 | 比赛神器 | 沉金彩色丝印

摘要

Apache Camel支持多种方法来定义REST服务。特别是,Apache Camel提供了REST DSL(特定于域的语言),这是一种简单但功能强大的流畅API,可以在任何REST组件上分层并提供与Swagger的集成。

Camel中的REST概述

概览

Apache Camel提供了许多用于在Camel应用程序中定义REST服务的方法和组件。本节提供了这些不同方法和组件的快速概述,以便您可以确定最适合您要求的实现和API。

什么是REST?

具象状态传输(REST)是一种用于分布式应用的架构,各地的HTTP数据传输中心,只用了四个基本的HTTP动词:GETPOSTPUT,和DELETE

与像SOAP这样的将HTTP视为SOAP消息的单纯传输协议的协议相反,REST体系结构直接利用了HTTP。关键的见解是,HTTP协议本身(通过一些简单的约定进行了扩展)非常适合用作分布式应用程序的框架。

REST调用示例

由于REST体系结构是围绕标准HTTP动词构建的,因此在许多情况下,您可以将常规浏览器用作REST客户端。例如,要调用在主机和端口上运行的简单Hello World REST服务localhost:9091,可以在浏览器中导航至如下所示的URL:

http://localhost:9091/say/hello/Garp

然后,Hello World REST服务可能会返回响应字符串,例如:

Hello Garp

这将显示在浏览器窗口中。仅使用标准浏览器(或curl命令行实用程序)就可以轻松调用REST服务,这是REST协议迅速普及的众多原因之一。

REST包装器层

以下REST包装器层提供了用于定义REST服务的简化语法,并且可以在不同REST实现的基础上分层:

  • REST DSL

    REST DSL(位于camel-core)是外观或包装层,它提供了用于定义REST服务的简化构建器API。REST DSL本身并不提供REST实现:它必须与基础REST实现结合使用。例如,以下Java代码显示了如何使用REST DSL 定义简单的Hello World服务:

    rest("/say")
        .get("/hello/{name}").route().transform().simple("Hello ${header.name}");
    
  • REST 组件

    Rest组件(位于camel-core)是包装层,使您可以使用URI语法定义REST服务。像REST DSL一样,Rest组件本身并不提供REST实现。它必须与基础REST实现结合使用。如果未明确配置HTTP传输组件,则REST DSL通过检查类路径上的可用组件来自动发现要使用的HTTP组件。REST DSL查找任何HTTP组件的默认名称,并使用找到的第一个名称。如果类路径上没有HTTP组件,并且您未明确配置HTTP传输,则默认HTTP组件为camel-http

    注意

    自动发现要使用的HTTP组件的功能是Camel 2.18中的新增功能。在Camel 2.17中不可用。

    以下Java代码显示了如何使用camel-rest组件定义简单的Hello World服务:

    from("rest:get:say:/hello/{name}").transform().simple("Hello ${header.name}");
    

REST实现

Apache Camel通过以下组件提供了几种不同的REST实现:

  • Spark-Rest 组件

    Spark-Rest组件(位于camel-spark-rest)是一个REST实现,使您能够使用URI语法定义REST服务。在Spark框架本身是一个Java API,它是松散的基础上Sinatra框架(一个Python API)。例如,以下Java代码显示了如何使用Spark-Rest组件定义简单的Hello World服务:

    from("spark-rest:get:/say/hello/:name").transform().simple("Hello ${header.name}");
    

    注意,在对比的是休息部件,在URI的变量的语法是:name代替{name}

    注意

    Spark-Rest组件需要Java 8。

  • Restlet 组件

    Restlet组件(位于camel-restlet)是一个REST实现,原则上可以在不同的传输协议之上分层(尽管仅针对HTTP协议对该组件进行了测试)。该组件还提供了与Restlet Framework的集成,Restlet Framework是用于以Java开发REST服务的商业框架。例如,以下Java代码显示了如何使用Restlet组件定义简单的Hello World服务:

    from("restlet:http://0.0.0.0:9091/say/hello/{name}?restletMethod=get")
        .transform().simple("Hello ${header.name}");
    
  • Servlet 组件

    Servlet组件(位于camel-servlet)是将Java Servlet绑定到Camel路由的组件。换句话说,Servlet组件使您可以打包和部署Camel路由,就好像它是标准Java Servlet一样。因此,如果您需要在Servlet容器内部署Camel路由(例如,部署到Apache Tomcat HTTP服务器或JBoss Enterprise Application Platform容器中), Servlet组件特别有用。

    但是,Servlet组件本身并没有提供任何方便的REST API来定义REST服务。因此,使用Servlet组件的最简单方法是将其与REST DSL组合在一起,以便您可以使用用户友好的API定义REST服务。

JAX-RS REST实现

JAX-RS(用于RESTful Web服务的Java API)是用于将REST请求绑定到Java对象的框架,其中Java类必须用JAX-RS批注装饰以定义绑定。JAX-RS框架相对成熟,并提供了用于开发REST服务的复杂框架,但是编程也有些复杂。

与Apache Camel的JAX-RS集成由CXFRS组件实现,该组件位于Apache CXF之上。概括而言,JAX-RS使用以下注释将REST请求绑定到Java类(其中,这只是许多可用注释的不完整示例):

  • @Path

    可以将上下文路径映射到Java类或将子路径映射到特定Java方法的注释。

  • @ GET,@ POST,@ PUT,@ DELETE

    将HTTP方法映射到Java方法的注释。

  • @PathParam

    将URI参数映射到Java方法参数,或将URI参数注入字段的注释。

  • @QueryParam

    将查询参数映射到Java方法参数或将查询参数注入字段的注释。

通常,REST请求或REST响应的主体应采用JAXB(XML)数据格式。但是Apache CXF还支持将JSON格式转换为JAXB格式,因此也可以解析JSON消息。

注意

CXFRS组件与REST DSL集成。

使用REST DSL定义服务

REST DSL是一个外观

REST DSL实际上是一种外观,它提供了用于在Java DSL或XML DSL(特定于域的语言)中定义REST服务的简化语法。REST DSL实际上并不提供REST实现,它只是现有 REST实现(在Apache Camel中有多个)的包装。

REST DSL的优势

REST DSL包装器层具有以下优点:

  • 用于定义REST服务的现代易用语法。
  • 与多个不同的Apache Camel组件兼容。
  • Swagger集成(通过camel-swagger组件)。

与REST DSL集成的组件

由于REST DSL不是实际的REST实现,因此您需要做的第一件事就是选择一个Camel组件来提供基础实现。目前,以下Camel组件已与REST DSL集成:

  • Servlet组件(camel-servlet)。
  • Spark REST组件(camel-spark-rest)。
  • Netty4 HTTP组件(camel-netty4-http)。
  • jetty组件(camel-jetty)。
  • restlet组件(camel-restlet)。

注意

Rest组件(位于camel-core)不是REST实现。像REST DSL一样,Rest组件也是一个外观,它提供了简化的语法以使用URI语法定义REST服务。Rest组件还需要底层的REST实现。

配置REST DSL以使用REST实现

要指定REST实现,请使用restConfiguration()构建器(在Java DSL中)或restConfiguration元素(在XML DSL中)。例如,要将REST DSL配置为使用Spark-Rest组件,您将在Java DSL中使用类似于以下内容的构建器表达式:

restConfiguration().component("spark-rest").port(9091);

并且您将camelContext在XML DSL中使用如下元素(作为的子元素):

<restConfiguration component="spark-rest" port="9091"/>

语法

用于定义REST服务的Java DSL语法如下:

rest("BasePath").Option().
    .Verb("Path").Option().[to() | route().CamelRoute.endRest()]
    .Verb("Path").Option().[to() | route().CamelRoute.endRest()]
    ...
    .Verb("Path").Option().[to() | route().CamelRoute];

其中CamelRoute是可选的嵌入式骆驼路由(使用标准Java DSL语法定义路由)。

REST服务定义以rest()关键字开头,后跟一个或多个处理特定URL路径段的动词子句。的HTTP谓词可以是一个get()head()put()post()delete()patch()verb()。每个动词子句都可以使用以下两种语法之一:

  • to()关键字结尾的动词子句。例如:

    get("...").Option()+.to("...")
    
  • route()关键字结尾的动词子句(用于嵌入骆驼路线)。例如:

    get("...").Option()+.route("...").CamelRoute.endRest()
    

Java REST DSL

在Java中,要使用REST DSL定义服务,请将REST定义放入RouteBuilder.configure()方法的主体中,就像对常规Apache Camel路由所做的一样。例如,要使用带有Spark-Rest组件的REST DSL 定义简单的Hello World服务,请定义以下Java代码:

restConfiguration().component("spark-rest").port(9091);

rest("/say")
    .get("/hello").to("direct:hello")
    .get("/bye").to("direct:bye");

from("direct:hello")
    .transform().constant("Hello World");
from("direct:bye")
    .transform().constant("Bye World");

前面的示例具有三种不同类型的构建器:

  • restConfiguration()

    将REST DSL配置为使用特定的REST实现(Spark-Rest)。

  • rest()

    使用REST DSL定义服务。每个动词子句都由to()关键字终止,该关键字将传入的消息转发到direct端点(direct组件将同一应用程序中的路由拼接在一起)。

  • from()

    定义常规的骆驼路线。

XML REST DSL

在XML中,要使用XML DSL定义服务,请将rest元素定义为元素的子camelContext元素。例如,要使用带有Spark-Rest组件的REST DSL 定义简单的Hello World服务,请定义以下XML代码(在蓝图中):

<camelContext xmlns="http://camel.apache.org/schema/blueprint">
  <restConfiguration component="spark-rest" port="9091"/>

  <rest path="/say">
    <get uri="/hello">
      <to uri="direct:hello"/>
    </get>
    <get uri="/bye">
      <to uri="direct:bye"/>
    </get>
  </rest>

  <route>
    <from uri="direct:hello"/>
    <transform>
      <constant>Hello World</constant>
    </transform>
  </route>
  <route>
    <from uri="direct:bye"/>
    <transform>
      <constant>Bye World</constant>
    </transform>
  </route>
</camelContext>

指定基本路径

rest()关键字(爪哇DSL)或path所述的属性rest元件(XML DSL)允许用户定义一个基本路径,然后将其前缀的路径中的所有动词条文。例如,给出以下Java DSL片段:

rest("/say")
    .get("/hello").to("direct:hello")
    .get("/bye").to("direct:bye");

或给出以下XML DSL片段:

<rest path="/say">
  <get uri="/hello">
    <to uri="direct:hello"/>
  </get>
  <get uri="/bye" consumes="application/json">
    <to uri="direct:bye"/>
  </get>
</rest>

REST DSL构建器为您提供以下URL映射:

/say/hello
/say/bye

基本路径是可选的。如果愿意,可以(不太优雅)在每个动词子句中指定完整路径:

rest()
    .get("/say/hello").to("direct:hello")
    .get("/say/bye").to("direct:bye");

使用动态To

REST DSL支持toD动态 to参数。使用此参数可以指定URI。

例如,在JMS中,可以通过以下方式定义动态端点URI:

public void configure() throws Exception {
   rest("/say")
     .get("/hello/{language}").toD("jms:queue:hello-${header.language}");
}

在XML DSL中,相同的细节如下所示:

<rest uri="/say">
  <get uri="/hello//{language}">
    <toD uri="jms:queue:hello-${header.language}"/>
  </get>
<rest>

URI模板

在动词自变量中,可以指定URI模板,该模板使您可以捕获命名属性中的特定路径段(然后将其映射到Camel消息头)。例如,如果您希望个性化Hello World应用程序,以便它按名称与调用方打招呼,则可以定义REST服务,如下所示:

rest("/say")
    .get("/hello/{name}").to("direct:hello")
    .get("/bye/{name}").to("direct:bye");

from("direct:hello")
    .transform().simple("Hello ${header.name}");
from("direct:bye")
    .transform().simple("Bye ${header.name}");

URI模板捕获{name}路径段的文本,并将捕获的文本复制到name消息头中。如果您通过发送以URL结尾的GET HTTP请求来调用服务/say/hello/Joe,则HTTP响应为Hello Joe

嵌入式路由语法

而不是终止动词从句用的to()关键字(Java的DSL)或to元素(XML DSL),你必须直接嵌入了Apache的骆驼航线进入休息DSL,使用的选项route()关键字(Java的DSL)或route元素(XML DSL )。该route()关键字允许你嵌入的路线变成个动词从句,语法如下:

RESTVerbClause.route("...").CamelRoute.endRest()

endRest()关键字(仅适用于Java的DSL)是一个必要的标点符号,使您能够分开动词条款(如果有不止一个动词在条款rest()建设者)。

例如,您可以重构Hello World示例以使用嵌入式Camel路由,如下Java DSL中所示:

rest("/say")
    .get("/hello").route().transform().constant("Hello World").endRest()
    .get("/bye").route().transform().constant("Bye World");

并在XML DSL中如下所示:

<camelContext xmlns="http://camel.apache.org/schema/blueprint">
  ...
  <rest path="/say">
    <get uri="/hello">
      <route>
        <transform>
          <constant>Hello World</constant>
        </transform>
      </route>
    </get>
    <get uri="/bye">
      <route>
        <transform>
          <constant>Bye World</constant>
        </transform>
      </route>
    </get>
  </rest>
</camelContext>

注意

如果您在current中定义了任何异常子句(使用onException())或拦截器(使用intercept()),则CamelContext这些异常子句和拦截器在嵌入式路由中也处于活动状态。

REST DSL和HTTP传输组件

如果未明确配置HTTP传输组件,则REST DSL通过检查类路径上的可用组件来自动发现要使用的HTTP组件。REST DSL查找任何HTTP组件的默认名称,并使用找到的第一个名称。如果类路径上没有HTTP组件,并且您未明确配置HTTP传输,则默认HTTP组件为camel-http

指定请求和响应的内容类型

您可以使用Java中的和选项或XML中的和属性来过滤HTTP请求和响应的内容类型。例如,以下是一些常见的内容类型(正式称为Internet媒体类型): consumes()``produces()``consumes``produces

  • text/plain
  • text/html
  • text/xml
  • application/json
  • application/xml

内容类型在REST DSL中的动词子句中指定为选项。例如,要限制动词子句仅接受text/plainHTTP请求并仅发送text/htmlHTTP响应,可以使用如下的Java代码:

rest("/email")
    .post("/to/{recipient}").consumes("text/plain").produces("text/html").to("direct:foo");

在XML中,您可以设置consumesproduces属性,如下所示:

<camelContext xmlns="http://camel.apache.org/schema/blueprint">
  ...
  <rest path="/email">
    <post uri="/to/{recipient}" consumes="text/plain" produces="text/html">
      <to "direct:foo"/>
    </get>
  </rest>
</camelContext>

您还可以将参数指定为consumes()produces()作为逗号分隔的列表。例如,consumes("text/plain, application/json")

其他HTTP方法

某些HTTP服务器实现支持附加的HTTP方法,其不通过在REST DSL标准组动词提供,get()head()put()post()delete()patch()。要访问其他HTTP方法,可以verb()在Java DSL中使用通用关键字verb,在XML DSL中使用通用元素。

例如,要在Java中实现TRACE HTTP方法:

rest("/say")
    .verb("TRACE", "/hello").route().transform();

where transform()IN消息的主体复制到OUT消息的主体,从而回显HTTP请求。

要在XML中实现TRACE HTTP方法:

<camelContext xmlns="http://camel.apache.org/schema/blueprint">
  ...
  <rest path="/say">
    <verb uri="/hello" method="TRACE">
      <route>
        <transform/>
      </route>
    </get>
</camelContext>

定义自定义HTTP错误消息

如果您的REST服务需要发送错误消息作为其响应,则可以如下定义自定义HTTP错误消息:

  1. 通过设置指定HTTP错误代码Exchange.HTTP_RESPONSE_CODE标头键错误代码值(例如,400404,等等)。此设置向REST DSL指示您要发送错误消息答复,而不是常规响应。

  2. 用您的自定义错误消息填充消息正文。

  3. 设置Content-Type标题(如果需要)。

  4. 如果将REST服务配置为与Java对象进行封送处理(bindingMode即已启用),则应确保该skipBindingOnErrorCode选项已启用(默认情况下为启用)。这是为了确保REST DSL在发送响应时不会尝试取消封送消息正文。

以下Java示例显示了如何定义自定义错误消息:

/// Java
// Configure the REST DSL, with JSON binding mode
restConfiguration().component("restlet").host("localhost").port(portNum).bindingMode(RestBindingMode.json);

// Define the service with REST DSL
rest("/users/")
    .post("lives").type(UserPojo.class).outType(CountryPojo.class)
        .route()
            .choice()
                .when().simple("${body.id} < 100")
                    .bean(new UserErrorService(), "idTooLowError")
                .otherwise()
                    .bean(new UserService(), "livesWhere");

在此示例中,如果输入的ID小于100,我们将使用UserErrorServiceBean 返回自定义错误消息,该消息的实现方式如下:

// Java
public class UserErrorService {
    public void idTooLowError(Exchange exchange) {
        exchange.getIn().setBody("id value is too low");
        exchange.getIn().setHeader(Exchange.CONTENT_TYPE, "text/plain");
        exchange.getIn().setHeader(Exchange.HTTP_RESPONSE_CODE, 400);
    }
}

UserErrorServiceBean中,我们定义了自定义错误消息,并将HTTP错误代码设置为400

参数默认值

可以为传入的骆驼消息的标题指定默认值。

您可以使用诸如verbose查询参数之类的关键字来指定默认值。例如,在下面的代码中,默认值为false。这意味着如果没有为verbose键的头提供其他任何值,false则将默认插入该值。

rest("/customers/")
    .get("/{id}").to("direct:customerDetail")
    .get("/{id}/orders")
      .param()
	.name("verbose")
	.type(RestParamType.query)
	.defaultValue("false")
	.description("Verbose order details")
      .endParam()
        .to("direct:customerOrders")
    .post("/neworder").to("direct:customerNewOrder");

在自定义HTTP错误消息中包装JsonParserException

您可能想返回自定义错误消息的常见情况是包装JsonParserException异常。例如,您可以方便地利用Camel异常处理机制来创建具有HTTP错误代码400的自定义HTTP错误消息,如下所示:

// Java
onException(JsonParseException.class)
    .handled(true)
    .setHeader(Exchange.HTTP_RESPONSE_CODE, constant(400))
    .setHeader(Exchange.CONTENT_TYPE, constant("text/plain"))
    .setBody().constant("Invalid json data");

REST DSL选项

通常,REST DSL选项可以直接应用于服务定义的基础部分(即紧随其后的部分rest()),如下所示:

rest("/email").consumes("text/plain").produces("text/html")
    .post("/to/{recipient}").to("direct:foo")
    .get("/for/{username}").to("direct:bar");

在这种情况下,指定的选项适用于所有从属动词从句。或者可以将选项应用于每个单独的动词子句,如下所示:

rest("/email")
    .post("/to/{recipient}").consumes("text/plain").produces("text/html").to("direct:foo")
    .get("/for/{username}").consumes("text/plain").produces("text/html").to("direct:bar");

在这种情况下,指定的选项仅适用于相关的动词子句,并覆盖基础部分中的所有设置。

REST DSL选项总结了REST DSL支持的选项。

Java DSLXML DSL描述
bindingMode()@bindingMode指定绑定模式,该模式可用于将传入消息封送到Java对象(以及可选地,将Java对象解封到输出消息)。可以有以下值:off(默认), ,autojson,。 xml``json_xml
consumes()@consumes限制verb子句仅接受HTTP请求中的指定Internet媒体类型(MIME类型)。典型值是:text/plaintext/httptext/xmlapplication/jsonapplication/xml
customId()@customId为JMX管理定义自定义ID。
description()description记录REST服务或动词子句。对于JMX管理和工具很有用。
enableCORS()@enableCORS如果为true,则在HTTP响应中启用CORS(跨域资源共享)标头。默认值为false
id()@id为REST服务定义唯一的ID,这对于定义JMX管理和其他工具很有用。
method()@method指定此动词子句处理的HTTP方法。通常与通用verb()关键字结合使用。
outType()@outType启用对象绑定时(即启用bindingMode选项时),此选项指定表示HTTP响应消息的Java类型。
produces()produces限制verb子句在HTTP响应中仅产生指定的Internet媒体类型(MIME类型)。典型值是:text/plaintext/httptext/xmlapplication/jsonapplication/xml
type()@type启用对象绑定时(即启用bindingMode选项时),此选项指定表示HTTP请求消息的Java类型。
*VerbURIArgument*@uri指定路径段或URI模板作为动词的参数。例如,。 get(*VerbURIArgument*)
*BasePathArgument*@pathrest()关键字(Java DSL)或rest元素(XML DSL)中指定基本路径。

与Java对象之间的编组

序列化Java对象以通过HTTP传输

使用REST协议的最常见方法之一是在消息正文中传输Java Bean的内容。为了使它起作用,您需要一种将Java对象与适当的数据格式进出编组的机制。REST DSL支持以下适用于编码Java对象的数据格式:

  • JSON

    (JavaScript对象表示法)是一种轻量级的数据格式,可以轻松地与Java对象进行映射。JSON语法紧凑,类型轻巧,易于人类读写。由于所有这些原因,JSON已作为REST服务的消息格式变得流行。

    例如,下面的JSON代码可以表示User豆具有两个属性字段,idname

    {
        "id" : 1234,
        "name" : "Jane Doe"
    }
    
  • JAXB

    (用于XML绑定的Java体系结构)是一种基于XML的数据格式,可以轻松地与Java对象进行映射。为了将XML编组为Java对象,还必须注释要使用的Java类。

    例如,下面的代码JAXB可以代表一个User豆具有两个属性字段,idname

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <User>
      <Id>1234</Id>
      <Name>Jane Doe</Name>
    </User>
    

    注意

    从Camel 2.17.0开始,JAXB数据格式和类型转换器支持使用XML到POJO的类的转换,这些类使用ObjectFactory代替XmlRootElement。此外,Camel上下文应包含CamelJaxbObjectFactory值为true 的属性。但是,由于优化,默认值为false。

JSON和JAXB与REST DSL的集成

当然,您可以编写所需的代码来亲自将消息主体与Java对象之间来回转换。但是REST DSL提供了自动执行此转换的便利。尤其是,JSON和JAXB与REST DSL的集成具有以下优点:

  • 自动进行Java对象之间的序列化(给定适当的配置)。
  • REST DSL可以自动检测数据格式(JSON或JAXB)并执行适当的转换。
  • REST DSL提供了一个抽象层,因此您编写的代码并不特定于特定的JSON或JAXB实现。因此,您可以稍后再打开实施,对应用程序代码的影响最小。

支持的数据格式组件

Apache Camel提供了JSON和JAXB数据格式的许多不同实现。REST DSL当前支持以下数据格式:

  • JSON
    • Jackson数据格式(camel-jackson(默认)
    • GSon数据格式(camel-gson
    • XStream数据格式(camel-xstream
  • JAXB
    • JAXB数据格式(camel-jaxb

如何启用对象序列化

要在REST DSL中启用对象序列化,请注意以下几点:

  1. 通过设置bindingMode选项来启用绑定模式。

  2. 在带有type选项(必填)的传入消息上和带有outType选项(可选)的传出消息上,指定要转换为(或从)转换的Java类型。

  3. 如果要在Java对象和JAXB数据格式之间进行转换,则必须记住用适当的JAXB注释对Java类进行注释。

  4. 使用jsonDataFormat和/或xmlDataFormat选项(可以在restConfiguration构建器上指定)指定基础数据格式实现。

  5. 如果您的路由以JAXB格式提供返回值,则通常应将交换正文的Out消息设置为带有JAXB批注(一个JAXB元素)的类的实例。但是,如果您希望直接以XML格式提供JAXB返回值,则将其dataFormatProperty与键设置xml.out.mustBeJAXBElementfalse(可以在restConfiguration构建器上指定)。例如,在XML DSL语法中:

    <restConfiguration ...>
      <dataFormatProperty key="xml.out.mustBeJAXBElement"
                          value="false"/>
      ...
    </restConfiguration>
    
  6. 将所需的依赖项添加到您的项目构建文件中。例如,如果您使用的是Maven构建系统,并且使用的是Jackson数据格式,则可以将以下依赖项添加到您的Maven POM文件中:

    <?xml version="1.0" encoding="UTF-8"?>
    <project ...>
      ...
      <dependencies>
        ...
        <!-- use for json binding --> <dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-jackson</artifactId> </dependency>
        ...
      </dependencies>
    </project>
    
  7. 将应用程序部署到OSGi容器时,请记住为所选的数据格式安装必需的功能。例如,如果使用的是Jackson数据格式(默认),则可以camel-jackson通过输入以下Karaf控制台命令来安装功能部件:

    JBossFuse:karaf@root> features:install camel-jackson
    

    或者,如果要部署到Fabric环境中,则可以将该功能添加到Fabric配置文件中。例如,如果您使用概要文件,MyRestProfile那么可以通过输入以下控制台命令来添加功能部件:

    JBossFuse:karaf@root> fabric:profile-edit --features camel-jackson MyRestProfile
    

配置绑定方式

bindingMode选项是off默认选项,因此必须启用它才能显式配置Java对象。TABLE显示了受支持的绑定模式的列表。

注意

从Camel 2.16.3开始,仅当content-type标头包含json或**xml时,**才会发生从POJO到JSon / JAXB的绑定。如果不应使用绑定将消息正文封送,这使您可以指定自定义内容类型。例如,如果消息正文是自定义二进制有效负载,则这很有用。

表4.2. REST DSL绑定模式

装订模式描述
off绑定已关闭**(默认)**。
auto已为JSON和/或XML启用绑定。在此模式下,Camel根据传入消息的格式自动选择JSON或XML(JAXB)。你是不是需要启用这两种数据格式,但是:无论是JSON实现,XML实现,或两者都可以提供在类路径中。
json绑定仅对JSON启用。必须在类路径上提供JSON实现(默认情况下,Camel尝试启用该camel-jackson实现)。
xml绑定仅对XML启用。必须在类路径上提供XML实现(默认情况下,Camel尝试启用该camel-jaxb实现)。
json_xmlJSON和XML均启用了绑定。在此模式下,Camel根据传入消息的格式自动选择JSON或XML(JAXB)。您需要在类路径上提供两种数据格式。

在Java中,这些绑定模式值表示为以下enum类型的实例:

org.apache.camel.model.rest.RestBindingMode

您可以在几个不同的级别上设置bindingMode,如下所示:

  • REST DSL配置

    您可以bindingModerestConfiguration构建器设置选项,如下所示:

    restConfiguration().component("servlet").port(8181).bindingMode(RestBindingMode.json);
    
  • 服务定义基础部分

    您可以bindingModerest()关键字之后(在动词子句之前)立即设置选项,如下所示:

    rest("/user").bindingMode(RestBindingMode.json).get("/{id}").VerbClause
    
  • 动词从句

    您可以bindingMode在动词子句中设置选项,如下所示:

    rest("/user")
        .get("/{id}").bindingMode(RestBindingMode.json).to("...");
    

示例

对于完整的代码示例,该示例演示如何使用Servlet组件作为REST实现来使用REST DSL,请看一下Apache Camel camel-example-servlet-rest-blueprint示例。您可以通过安装独立的Apache Camel发行版(apache-camel-2.21.0.fuse-750033-redhat-00001.zip位于extras/Fuse安装的子目录中)找到此示例。

安装独立的Apache Camel发行版后,您可以在以下目录下找到示例代码:

ApacheCamelInstallDir/examples/camel-example-servlet-rest-blueprint

将Servlet组件配置为REST实现

在该camel-example-servlet-rest-blueprint示例中,REST DSL的基础实现由Servlet组件提供。

示例为REST DSL配置Servlet组件

<?xml version="1.0" encoding="UTF-8"?>
<blueprint ...>

  <!-- to setup camel servlet with OSGi HttpService -->
  <reference id="httpService" interface="org.osgi.service.http.HttpService"/>

  <bean class="org.apache.camel.component.servlet.osgi.OsgiServletRegisterer"
        init-method="register"
        destroy-method="unregister">
    <property name="alias" value="/camel-example-servlet-rest-blueprint/rest"/>
    <property name="httpService" ref="httpService"/>
    <property name="servlet" ref="camelServlet"/>
  </bean>

  <bean id="camelServlet" class="org.apache.camel.component.servlet.CamelHttpTransportServlet"/>
  ...
  <camelContext xmlns="http://camel.apache.org/schema/blueprint">

    <restConfiguration component="servlet"
                       bindingMode="json"
                       contextPath="/camel-example-servlet-rest-blueprint/rest"
                       port="8181">
      <dataFormatProperty key="prettyPrint" value="true"/>
    </restConfiguration>
    ...
  </camelContext>

要使用REST DSL配置Servlet组件,您需要配置一个由以下三层组成的堆栈:

  • REST DSL层

    REST DSL层由restConfiguration元素配置,该元素通过将component属性设置为值与Servlet组件集成servlet

  • Servlet组件层

    Servlet组件层实现为类的实例CamelHttpTransportServlet,其中示例实例的bean ID为camelServlet

  • HTTP容器层

    Servlet组件必须部署到HTTP容器中。Karaf容器通常配置有默认的HTTP容器(Jetty HTTP容器),该容器在端口8181上侦听HTTP请求。要将Servlet组件部署到默认的Jetty容器,您需要执行以下操作:

    a. 获取对org.osgi.service.http.HttpServiceOSGi服务的OSGi参考,其中该服务是标准化的OSGi接口,可提供对OSGi中默认HTTP服务器的访问。

    b. 创建实用程序类的实例OsgiServletRegisterer,以将Servlet组件注册到HTTP容器中。该OsgiServletRegisterer班是简化了管理Servlet组件的生命周期的工具。创建此类的实例时,它将自动registerServletHttpServiceOSGi服务上调用该方法;实例销毁后,它将自动调用该unregister方法。

所需的依赖项

此示例具有两个依赖关系,这些依赖关系对REST DSL至关重要,如下所示:

  • Servlet组件

    提供REST DSL的基础实现。这在Maven POM文件中指定,如下所示:

    <dependency>
      <groupId>org.apache.camel</groupId>
      <artifactId>camel-servlet</artifactId>
      <version>${camel-version}</version>
    </dependency>
    

    并且,在将应用程序捆绑包部署到OSGi容器之前,必须安装Servlet组件功能,如下所示:

    JBossFuse:karaf@root> features:install camel-servlet
    
  • Jackson 数据格式

    提供JSON数据格式实现。这在Maven POM文件中指定,如下所示:

    <dependency>
      <groupId>org.apache.camel</groupId>
      <artifactId>camel-jackson</artifactId>
      <version>${camel-version}</version>
    </dependency>
    

    并且在将应用程序捆绑包部署到OSGi容器之前,必须安装Jackson数据格式功能,如下所示:

    JBossFuse:karaf@root> features:install camel-jackson
    

响应的Java类型

示例应用程序User在HTTP请求和响应消息中来回传递类型对象。该UserJava类被定义为示于

示例 JSON响应的用户类

// Java
package org.apache.camel.example.rest;

public class User {

    private int id;
    private String name;

    public User() {
    }

    public User(int id, String name) {
        this.id = id;
        this.name = 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;
    }
}

所述User类在JSON格式数据相对简单的表示。例如,以JSON格式表示的此类的典型实例为:

{
    "id" : 1234,
    "name" : "Jane Doe"
}

带有JSON绑定REST DSL路由的示例

带有JSON绑定的REST DSL路由中显示了此示例的REST DSL配置和REST服务定义。

<?xml version="1.0" encoding="UTF-8"?>
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           ...>
  ...
  <!-- a bean for user services -->
  <bean id="userService" class="org.apache.camel.example.rest.UserService"/>

  <camelContext xmlns="http://camel.apache.org/schema/blueprint">

    <restConfiguration component="servlet"
                       bindingMode="json"
                       contextPath="/camel-example-servlet-rest-blueprint/rest"
                       port="8181">
      <dataFormatProperty key="prettyPrint" value="true"/>
    </restConfiguration>

    <!-- defines the REST services using the  base path, /user -->
    <rest path="/user" consumes="application/json" produces="application/json">
      <description>User rest service</description>

      <!-- this is a rest GET to view a user with the given id -->
      <get uri="/{id}" outType="org.apache.camel.example.rest.User">
        <description>Find user by id</description>
        <to uri="bean:userService?method=getUser(${header.id})"/>
      </get>

      <!-- this is a rest PUT to create/update a user -->
      <put type="org.apache.camel.example.rest.User">
        <description>Updates or create a user</description>
        <to uri="bean:userService?method=updateUser"/>
      </put>

      <!-- this is a rest GET to find all users -->
      <get uri="/findAll" outType="org.apache.camel.example.rest.User[]">
        <description>Find all users</description>
        <to uri="bean:userService?method=listUsers"/>
      </get>

    </rest>

  </camelContext>

</blueprint>

REST操作

示例中 的REST服务定义了以下REST操作:

  • GET /camel-example-servlet-rest-blueprint/rest/user/{id}

    获取由标识的用户的详细信息{id},其中HTTP响应以JSON格式返回。

  • PUT /camel-example-servlet-rest-blueprint/rest/user

    创建一个新用户,该用户的详细信息包含在PUT消息的主体中,并以JSON格式编码(以匹配User对象类型)。

  • GET /camel-example-servlet-rest-blueprint/rest/user/findAll

    获取所有用户的详细信息,其中,HTTP响应作为用户数组以JSON格式返回。

调用REST服务的URL

通过检查示例的REST DSL定义,可以将调用每个REST操作所需的URL拼凑在一起。例如,要调用第一个REST操作(该操作返回具有给定ID的用户的详细信息),则URL的构建如下:

  • http://localhost:8181

    在中restConfiguration,协议默认为http,端口明确设置为8181

  • /camel-example-servlet-rest-blueprint/rest

    由元素的contextPath属性指定restConfiguration

  • /user

    由元素的path属性指定rest

  • /{id}

    由动词元素的uri属性指定get

因此,可以curl通过在命令行中输入以下命令来使用实用程序调用此REST操作:

curl -X GET -H "Accept: application/json" http://localhost:8181/camel-example-servlet-rest-blueprint/rest/user/123

同样,curl通过输入以下示例命令,可以使用调用其余的REST操作:

curl -X GET -H "Accept: application/json" http://localhost:8181/camel-example-servlet-rest-blueprint/rest/user/findAll

curl -X PUT -d "{ \"id\": 666, \"name\": \"The devil\"}" -H "Accept: application/json" http://localhost:8181/camel-example-servlet-rest-blueprint/rest/user

配置REST DSL

使用Java配置

在Java中,您可以使用restConfiguration()构建器API 配置REST DSL 。例如,将REST DSL配置为使用Servlet组件作为基础实现:

restConfiguration().component("servlet").bindingMode("json").port("8181")
    .contextPath("/camel-example-servlet-rest-blueprint/rest");

使用XML进行配置

在XML中,您可以使用restConfiguration元素配置REST DSL 。例如,将REST DSL配置为使用Servlet组件作为基础实现:

<?xml version="1.0" encoding="UTF-8"?>
<blueprint ...>
  ...
  <camelContext xmlns="http://camel.apache.org/schema/blueprint">
    ...
    <restConfiguration component="servlet"
                       bindingMode="json"
                       contextPath="/camel-example-servlet-rest-blueprint/rest"
                       port="8181">
      <dataFormatProperty key="prettyPrint" value="true"/>
    </restConfiguration>
    ...
  </camelContext>

</blueprint>

配置选项

Java DSLXML DSL描述
component()@component指定骆驼分量作为传输REST(例如,使用servletrestletspark-rest,等等)。该值可以是标准组件名称,也可以是自定义实例的bean ID。如果未指定此选项,则Camel RestConsumerFactory在类路径或bean注册表中查找的实例。
scheme()@scheme用于公开REST服务的协议。依赖于底层REST实现,但httphttps通常的支持。默认值为http
host()@host用于公开REST服务的主机名。
port()@port用于公开REST服务的端口号。注意:此设置被Servlet组件忽略,该组件使用容器的标准HTTP端口。对于Apache Karaf OSGi容器,标准的HTTP端口通常为8181。尽管如此,为实现JMX和工具,设置端口值仍然是一个好习惯。
contextPath()@contextPath为REST服务设置领先的上下文路径。可以与诸如Servlet之类的组件一起使用,其中使用context-path设置来部署已部署的Web应用程序。
hostNameResolver()@hostNameResolver如果未明确设置主机名,则此解析器将确定REST服务的主机。可能的值是RestHostNameResolver.localHostName(Java DSL)或localHostName(XML DSL),它们解析为主机名格式。和RestHostNameResolver.localIp(Java的DSL)或localIp(XML DSL),它解析为点分十进制IP地址格式。从骆驼2.17 RestHostNameResolver.allLocalIp可用于解析为所有本地IP地址。默认值为localHostNameCamel 2.16。在Camel 2.17中,默认值为allLocalIp
bindingMode()@bindingMode启用JSON或XML格式消息的绑定模式。可能的值有:offautojsonxml,或json_xml。默认值为off
skipBindingOnErrorCode()@skipBindingOnErrorCode指定是否存在自定义HTTP错误代码标头,是否跳过输出绑定。这使您可以构建不绑定到JSON或XML的自定义错误消息,否则成功消息就会这样做。默认值为true
enableCORS()@enableCORS如果为true,则在HTTP响应中启用CORS(跨域资源共享)标头。默认值为false
jsonDataFormat()@jsonDataFormat指定Camel用于实现JSON数据格式的组件。可能的值有:json-jacksonjson-gsonjson-xstream。默认值为json-jackson
xmlDataFormat()@xmlDataFormat指定Camel用于实现XML数据格式的组件。可能的值为:jaxb。默认值为jaxb
componentProperty()componentProperty使您可以在基础REST实现上设置任意组件级别的属性。
endpointProperty()endpointProperty使您可以在基础REST实现上设置任意端点级别的属性。
consumerProperty()consumerProperty使您可以在基础REST实现上设置任意的使用者终结点属性。
dataFormatProperty()dataFormatProperty使您可以在基础数据格式组件(例如,Jackson或JAXB)上设置任意属性。从Camel 2.14.1开始,您可以将以下前缀附加到属性键:json.in``json.out``xml.in``xml.out将属性设置限制为特定的格式类型(JSON或XML)和特定的消息方向(INOUT)。
corsHeaderProperty()corsHeaders使您可以将自定义CORS标头指定为键/值对。

默认的CORS标头

如果启用了CORS(跨域资源共享),则默认设置以下标头。您可以选择通过调用corsHeaderPropertyDSL命令来覆盖默认设置。

默认的CORS标头

标题键标头值
Access-Control-Allow-Origin\*
Access-Control-Allow-MethodsGETHEADPOSTPUTDELETETRACEOPTIONSCONNECTPATCH
Access-Control-Allow-HeadersOriginAcceptX-Requested-WithContent-TypeAccess-Control-Request-MethodAccess-Control-Request-Headers
Access-Control-Max-Age3600

启用或禁用Jackson JSON功能

您可以通过在dataFormatProperty选项中配置以下键来启用或禁用特定的Jackson JSON功能:

  • json.in.disableFeatures
  • json.in.enableFeatures

例如,禁用杰克逊的FAIL_ON_UNKNOWN_PROPERTIES功能(如果JSON输入具有无法映射到Java对象的属性,这将导致杰克逊失败):

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

以下示例显示了如何在Java DSL中禁用和启用Jackson JSON功能:

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

以下示例显示了如何在XML DSL中禁用和启用Jackson JSON功能:

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

可以禁用或启用的Jackson功能对应于enum以下Jackson类的ID

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

Swagger整合

概览

您可以使用Swagger服务为CamelContext文件中的任何REST定义的路由和端点创建API文档。为此,请将Camel REST DSL与camel-swagger-java纯基于Java 的模块一起使用。该camel-swagger-java模块创建一个与CamelContext集成的servlet,该servlet从每个REST端点提取信息以生成JSON或YAML格式的API文档。

如果使用Maven,则编辑pom.xml文件以添加对camel-swagger-java组件的依赖关系:

<dependency>
   <groupId>org.apache.camel</groupId>
   <artifactId>camel-swagger-java</artifactId>
   <version>x.x.x</version>
   <!-- Specify the version of your camel-core module. -->
</dependency>

配置CamelContext以启用Swagger

要在Camel REST DSL中启用Swagger API,请调用apiContextPath()设置Swagger生成的API文档的上下文路径。例如:

public class UserRouteBuilder extends RouteBuilder {
    @Override
    public void configure() throws Exception {
        // Configure the Camel REST DSL to use the netty4-http component:
        restConfiguration().component("netty4-http").bindingMode(RestBindingMode.json)
            // Generate pretty print output:
            .dataFormatProperty("prettyPrint", "true")
            // Set the context path and port number that netty will use:
            .contextPath("/").port(8080)
            // Add the context path for the Swagger-generated API documentation:
            .apiContextPath("/api-doc")
                .apiProperty("api.title", "User API").apiProperty("api.version", "1.2.3")
                // Enable CORS:
                .apiProperty("cors", "true");

        // This user REST service handles only JSON files:
        rest("/user").description("User rest service")
            .consumes("application/json").produces("application/json")
            .get("/{id}").description("Find user by id").outType(User.class)
                .param().name("id").type(path).description("The id of the user to get").dataType("int").endParam()
                .to("bean:userService?method=getUser(${header.id})")
            .put().description("Updates or create a user").type(User.class)
                .param().name("body").type(body).description("The user to update or create").endParam()
                .to("bean:userService?method=updateUser")
            .get("/findAll").description("Find all users").outTypeList(User.class)
                .to("bean:userService?method=listUsers");
    }
}

Swagger模块配置选项

下表中描述的选项使您可以配置Swagger模块。设置一个选项,如下所示:

  • 如果将camel-swagger-java模块用作servlet,请通过更新web.xml文件并init-param为要设置的每个配置选项指定一个元素来设置选项。
  • 如果使用的是camel-swagger-java从骆驼REST部件模块,通过调用适当的设定的选项RestConfigurationDefinition的方法,例如enableCORS()host(),或contextPath()api.xxx使用RestConfigurationDefinition.apiProperty()方法设置选项。
选项类型描述
api.contact.email字符串用于API相关通信的电子邮件地址。
api.contact.name字符串要联系的人员或组织的名称。
api.contact.url字符串网站的URL,以获取更多联系信息。
apiContextIdListing布尔型如果您的应用程序使用多个CamelContext对象,则默认行为是仅在current中列出REST端点CamelContext。如果要CamelContext在运行REST服务的JVM中运行的每个REST端点的列表,请将此选项设置为true。如果apiContextIdListing为true,则Swagger会将CamelContext根路径中的ID(例如)输出为/api-docsJSON格式的名称列表。要访问Swagger生成的文档,请将REST上下文路径附加到CamelContextID,例如api-docs/myCamel。您可以使用该apiContextIdPattern选项来过滤此输出列表中的名称。
apiContextIdPattern字符串用于过滤哪些CamelContext ID出现在上下文列表中的模式。您可以指定正则表达式并将*用作通配符。这与骆驼拦截功能使用的模式匹配工具相同。
api.license.name字符串用于API的许可证名称。
api.license.url字符串用于API的许可证的URL。
api.path字符串设置可用于生成文档的REST API的路径,例如/api-docs。指定相对路径。例如,请勿指定httphttps。该camel-swagger-java模块在运行时以以下格式计算绝对路径:protocol://host:port/context-path/api-path
api.termsOfService字符串API服务条款的网址。
api.title字符串应用程序的标题。
api.version字符串API版本。默认值为0.0.0。
base.path字符串需要。设置REST服务可用的路径。指定相对路径。也就是说,请勿指定httphttps。该camel-swagger-java模件计算在运行时以这种格式的绝对路径:protocol://host:port/context-path/base.path
cors布尔型是否启用HTTP访问控制(CORS)。这使CORS仅用于查看REST API文档,而不用于访问REST服务。默认值为false。建议改用此CorsFilter选项,如下表所述。
host字符串设置运行Swagger服务的主机的名称。默认为基于计算主机名localhost
schemes字符串使用的协议方案。例如,用逗号分隔多个值,"http,https".默认值为http
swagger.version字符串Swagger规范版本。默认值为2.0。

使用CORS筛选器启用CORS支持

如果使用Swagger用户界面查看REST API文档,则可能需要启用对HTTP访问控制(CORS)的支持。当托管Swagger用户界面并在与运行REST API的主机名/端口不同的主机名/端口上运行Swagger用户界面时,需要此支持。

要启用对CORS的支持,请将添加RestSwaggerCorsFilter到您的web.xml文件中。CORS过滤器添加了启用CORS的HTTP标头。例如:

<!-- Enable CORS filter to allow use of Swagger UI for browsing and testing APIs. -->
<filter>
     <filter-name>RestSwaggerCorsFilter</filter-name>
     <filter-class>org.apache.camel.swagger.rest.RestSwaggerCorsFilter</filter-class>
</filter>
<filter-mapping>
     <filter-name>RestSwaggerCorsFilter</filter-name>
     <url-pattern>/api-docs/*</url-pattern>
     <url-pattern>/rest/*</url-pattern>
</filter-mapping>

RestSwaggerCorsFilter规定对所有请求以下标题:

  • Access-Control-Allow-Origin= *
  • Access-Control-Allow-Methods = GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS, CONNECT, PATCH
  • Access-Control-Max-Age = 3600’
  • Access-Control-Allow-Headers = Origin, Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers

RestSwaggerCorsFilter是一个简单的过滤器。如果需要阻止某些客户端或为给定客户端设置不同的标头值,则可能需要更复杂的过滤器。

获取JSON或YAML输出

从Camel 2.17开始,该camel-swagger-java模块支持JSON和YAML格式的输出。要指定所需的输出,请在/swagger.json/swagger.yamlURL上添加。如果请求URL未指定格式,则camel-swagger-java模块将检查HTTP Accept标头以检测是否可以接受JSON或YAML。如果两个都被接受,或者没有一个被设置为接受,那么JSON是默认的返回格式。

例子

在Apache Camel发行,camel-example-swagger-cdicamel-example-swagger-java演示该camel-swagger-java模块的使用。

增强Swagger生成的文档

从Camel 2.16开始,您可以通过定义参数详细信息(例如名称,描述,数据类型,参数类型等)来增强Swagger生成的文档。如果使用XML,请指定param元素以添加此信息。以下示例显示如何提供有关ID路径参数的信息:

<!-- This is a REST GET request to view information for the user with the given ID: -->
<get uri="/{id}" outType="org.apache.camel.example.rest.User">
     <description>Find user by ID.</description>
     <param name="id" type="path" description="The ID of the user to get information about." dataType="int"/>
     <to uri="bean:userService?method=getUser(${header.id})"/>
</get>

以下是Java DSL中的相同示例:

.get("/{id}").description("Find user by ID.").outType(User.class)
   .param().name("id").type(path).description("The ID of the user to get information about.").dataType("int").endParam()
   .to("bean:userService?method=getUser(${header.id})")

如果定义名称为的参数,body则还必须指定body该参数的类型。例如:

<!-- This is a REST PUT request to create/update information about a user. -->
<put type="org.apache.camel.example.rest.User">
     <description>Updates or creates a user.</description>
     <param name="body" type="body" description="The user to update or create."/>
     <to uri="bean:userService?method=updateUser"/>
</put>

以下是Java DSL中的相同示例:

.put().description("Updates or create a user").type(User.class)
     .param().name("body").type(body).description("The user to update or create.").endParam()
     .to("bean:userService?method=updateUser")

开发板推荐:天空星STM32F407VET6开发板

超高性价比 STM32主控 | 超高主频 | 一板兼容百芯 | 比赛神器 | 沉金彩色丝印

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

沙子可可

你的鼓励是我创造的动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值