Rest DSL 错误处理与验证
Rest DSL - 错误处理与验证
原样定义自定义错误消息
如果你想定义自定义错误消息,并连同 HTTP 错误码(例如 400、404 等)一起返回给客户端,那么你需要将键为 Exchange.HTTP_RESPONSE_CODE 的消息头设置为该错误码(必须是 300 以上,例如 404)。然后在消息正文中填入回复消息内容,并可选择性地设置 content-type 消息头。下面给出一个简单的示例:
- Java
- XML
- YAML
restConfiguration().component("netty-http").host("localhost").port(9091).bindingMode(RestBindingMode.json);
// use the rest DSL to define the rest services
rest("/users/")
.post("lives").type(UserPojo.class).outType(CountryPojo.class)
.to("direct:users-lives");
from("direct:users-lives")
.choice()
.when().simple("${body.id} < 100")
.bean("userErrorService", "idToLowError")
.otherwise()
.bean("userService", "livesWhere");<restConfiguration component="netty-http" host="localhost" port="9091" bindingMode="json"/>
<rest path="/users/">
<post path="lives" type="com.foo.UserPojo" outType="com.foo.CountryPojo">
<to uri="direct:users-lives"/>
</post>
</rest>
<route>
<from uri="direct:users-lives"/>
<choice>
<when>
<simple>${body.id} < 100</simple>
<bean ref="userErrorService" method="idToLowError"/>
</when>
<otherwise>
<bean ref="userService" method="livesWhere"/>
</otherwise>
</choice>
</route>- restConfiguration:
component: "netty-http"
host: "localhost"
port: "9091"
bindingMode: "json"
- rest:
path: "/users"
post:
- path: "/lives"
to: "direct:users-lives"
type: "com.foo.UserPojo"
outType: "com.foo.CountryPojo"
- route:
from:
uri: direct:users-lives
steps:
- choice:
when:
- expression:
simple:
expression: "${body.id} < 100"
steps:
- bean:
ref: userErrorService
method: idToLowError
otherwise:
steps:
- bean:
ref: userService
method: livesWhere在本示例中,如果输入的 id 是一个小于 100 的数字,我们希望使用 UserErrorService bean 返回一条自定义错误消息,该 bean 的实现如下:
public class UserErrorService {
public void idToLowError(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);
}
}在 UserErrorService bean 中,我们构建自定义错误消息,并将 HTTP 错误码设置为 400。这一点很重要,因为它告诉 rest-dsl 这是一条自定义错误消息,该消息不应使用输出 POJO 绑定(否则会绑定到 CountryPojo)。
捕获 JsonParserException 并返回自定义错误消息
你可以原样返回自定义消息(参见上一节)。因此,我们可以结合 Camel 错误处理器来捕获 JsonParserException,处理该异常并构建自定义响应消息。例如,要返回 HTTP 错误码 400 和一条硬编码的消息,可以按如下方式操作:
- Java
- XML
- YAML
onException(JsonParseException.class)
.handled(true)
.setHeader(Exchange.HTTP_RESPONSE_CODE, constant(400))
.setHeader(Exchange.CONTENT_TYPE, constant("text/plain"))
.setBody().constant("Invalid json data");<onException>
<exception>com.fasterxml.jackson.core.JsonParseException</exception>
<handled>
<constant>true</constant>
</handled>
<setHeader name="CamelHttpResponseCode">
<constant>400</constant>
</setHeader>
<setHeader name="Content-Type">
<constant>text/plain</constant>
</setHeader>
<setBody>
<constant>Invalid json data</constant>
</setBody>
</onException>- onException:
exception:
- com.fasterxml.jackson.core.JsonParseException
handled:
constant:
expression: "true"
steps:
- setHeader:
name: CamelHttpResponseCode
expression:
constant:
expression: 400
- setHeader:
name: Content-Type
expression:
constant:
expression: text/plain
- setBody:
expression:
constant:
expression: Invalid json data查询/请求头参数的默认值
你可以在 rest-dsl 中为参数指定默认值,例如下面的 verbose 参数:
- Java
- XML
- YAML
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");<rest path="/customers/">
<get path="/{id}">
<to uri="direct:customerDetail"/>
</get>
<get path="/{id}/orders">
<param description="Verbose order details" name="verbose" type="query" defaultValue="false"/>
<to uri="direct:customerOrders"/>
</get>
<post path="/neworder">
<to uri="direct:customerNewOrder"/>
</post>
</rest>- rest:
path: "/customers/"
get:
- path: "/{id}"
to: "direct:customerDetail"
- path: "/{id}/orders"
to: "direct:customerOrders"
param:
- name: "verbose"
type: "query"
defaultValue: "false"
description: "Verbose order details"
post:
- path: "/neworder"
to: "direct:customerNewOrder"默认值会被自动设置为传入 Camel Message 的头部。因此,如果调用 /customers/id/orders 时没有包含键为 verbose 的查询参数,Camel 就会因为该参数声明了默认值,而添加一个键为 verbose、值为 false 的头部。此功能仅适用于查询参数。请求头也可以用同样的方式设置默认值。
- Java
- XML
- YAML
rest("/customers/")
.get("/{id}").to("direct:customerDetail")
.get("/{id}/orders")
.param().name("indicator").type(RestParamType.header).defaultValue("disabled").description("Feature Enabled Indicator").endParam()
.to("direct:customerOrders")
.post("/neworder").to("direct:customerNewOrder");<rest path="/customers/">
<get path="/{id}">
<param name="id" type="path"/>
<to uri="direct:customerDetail"/>
</get>
<get path="/{id}/orders">
<param description="Feature Enabled Indicator" name="indicator" type="header" defaultValue="disabled"/>
<to uri="direct:customerOrders"/>
</get>
<post path="/neworder">
<to uri="direct:customerNewOrder"/>
</post>
</rest>- rest:
path: "/customers/"
get:
- path: "/{id}"
to: "direct:customerDetail"
- path: "/{id}/orders"
to: "direct:customerOrders"
param:
- name: "indicator"
type: "header"
defaultValue: "disabled"
description: "Feature Enabled Indicator"
post:
- path: "/neworder"
to: "direct:customerNewOrder"客户端请求与响应校验
可以启用对客户端传入请求的校验。该校验会检查以下内容:
- Content-Type 请求头是否与 Rest DSL 所消费的类型匹配。(返回 HTTP 状态码 415)
- Accept 请求头是否与 Rest DSL 所产生的类型匹配。(返回 HTTP 状态码 406)
- 是否缺少必需的数据(查询参数、HTTP 请求头、消息体)。(返回 HTTP 状态码 400)
- 检查查询参数或 HTTP 请求头是否包含不被允许的取值。(返回 HTTP 状态码 400)
- 消息体解析错误(需要启用 JSON、XML 或自动绑定模式)。(返回 HTTP 状态码 400)
如果校验失败,Rest DSL 将返回一个带有 HTTP 错误码的响应。
该校验默认是关闭的(以保持向后兼容)。可以通过 clientRequestValidation 开启,示例如下:
- Java
- XML
- YAML
restConfiguration().component("jetty").host("localhost")
.clientRequestValidation(true);<restConfiguration component="jetty" host="localhost" clientRequestValidation="true"/>- restConfiguration:
component: "jetty"
host: "localhost"
clientRequestValidation: "true"验证器是可插拔的,Camel 开箱即用地提供了默认实现。
不过,camel-openapi-validator 在客户端请求校验方面使用的是第三方库 Atlassian Swagger Request Validator。该库比 camel-core 中的默认验证器功能更强大,例如它可以校验负载是否按照 OpenAPI 规范的结构组织。
在 Camel 4.13 中,我们还新增了响应验证器,它更像是一种开发辅助工具,可以在构建 Camel 集成时启用,用于帮助确保 Camel 返回给 HTTP 客户端的内容是有效的。响应验证器会检查以下内容:
- 状态码和 Content-Type 是否与 Rest DSL 的响应消息匹配。
- 根据 Rest DSL 响应消息头,检查是否包含了预期的响应头。
- 如果响应体是 JSON,则检查其是否为有效的 JSON。
一旦检测到任何错误,将返回 HTTP 状态码 500。
此外,可以将 camel-openapi-validator 加入 classpath,以获得更强大的响应验证器,用它来校验响应负载是否按照 OpenAPI 规范的结构组织。
评论
登录后参与评论
KnowForge