有一条具有多个可能的Rest-respons的Rest-route(它们的类型不同,但让我们假设它只是MyResponse.class)。
rest().post("/{{camel.rest.version}}/myjson")
.consumes("application/json").produces("application/json")
.type(SampleRequest.class)
.responseMessage().code("200").responseModel(MyResponse.class).endResponseMessage()
.responseMessage().code("400").responseModel(MyResponse.class).endResponseMessage()
.responseMessage().code("500").responseModel(MyResponse.class).endResponseMessage()
.route().routeId("rest_myroute")
.log(LoggingLevel.INFO, "API_REQ Recieved http request ${body}")
.process(sampleProcessor).id("sample_transform")
.log(LoggingLevel.INFO, "API_RESP Response ${body}")
.endRest();
处理器执行一些验证/业务逻辑。大致看起来像:
@Override
public void process(Exchange exchange) throws Exception {
SampleRequest inReq = exchange.getIn().getBody(SampleRequest.class);
if (inReq.getMsgMode().equals("500"))
exchange.getOut().setHeader(Exchange.HTTP_RESPONSE_CODE, HttpStatus.SC_INTERNAL_SERVER_ERROR);
if (inReq.getMsgMode().equals("400"))
exchange.getOut().setHeader(Exchange.HTTP_RESPONSE_CODE, HttpStatus.SC_BAD_REQUEST);
MyResponse myClass = new MyResponse();
myClass.setRecId("123456");
exchange.getOut().setBody(myClass);
}
肯定案例的执行结果:
代码详细信息 200 反应体 { “ recId”:“ 123456” }
500或400箱 代码详细信息 400错误:请求错误 响应头 连接:保持活动状态
(没有身体)
如果我将路线更改为手动编组:
rest().post("/{{camel.rest.version}}/myjson")
.consumes("application/json").produces("application/json")
.type(SampleRequest.class)
.route().routeId("rest_myroute")
.log(LoggingLevel.INFO, LoggingConst.API_REQ+" Recieved http request ${body}")
.process(sampleProcessor).id("sample_transform")
.marshal().json(JsonLibrary.Jackson)
.log(LoggingLevel.INFO, LoggingConst.API_RESP+" Response ${body}")
.endRest();
结果相同。
好的。万一使用getOut()不好,请尝试使用getIn()。 使用getIn()的处理器
@Override
public void process(Exchange exchange) throws Exception {
SampleRequest inReq = exchange.getIn().getBody(SampleRequest.class);
if (inReq.getMsgMode().equals("500"))
exchange.getIn().setHeader(Exchange.HTTP_RESPONSE_CODE, HttpStatus.SC_INTERNAL_SERVER_ERROR);
if (inReq.getMsgMode().equals("400"))
exchange.getIn().setHeader(Exchange.HTTP_RESPONSE_CODE, HttpStatus.SC_BAD_REQUEST);
MyResponse myClass = new MyResponse();
myClass.setRecId("123456");
exchange.getIn().setBody(myClass);
}
结果:
正例:
代码详细信息 200 反应体 “ eyJyZWNJZCI6IjEyMzQ1NiJ9”
(已完成双重编组)
否定情况:
400错误:错误的请求 反应体 { “ recId”:“ 123456” }
让我们彻底删除编组!
rest().post("/{{camel.rest.version}}/myjson")
.consumes("application/json").produces("application/json")
.type(SampleRequest.class)
.route().routeId("rest_myroute")
.log(LoggingLevel.INFO, LoggingConst.API_REQ+" Recieved http request ${body}")
.process(sampleProcessor).id("sample_transform")/*.streamCaching()*/
.log(LoggingLevel.INFO, LoggingConst.API_RESP+" Response ${body}")
.endRest();
肯定的结果:
代码详细信息 200 反应体 { “ recId”:“ 123456” }
阴性结果:
代码详细信息 400错误:请求错误 反应体 无法解析JSON。原始结果:
MyResponse类{ recId:123456 }
(收到的原始数据)
在所有情况下,我的API日志在骆驼准备休息响应之前都显示相同的结果:
{"timestamp":"2018-08-21T16:04:37.284+00:00","level":"INFO","logger_name":"rest_myroute","message":"ApiRq Recieved http request SampleRequest(msgMode=400)","traceId":"-4589659693669010018","spanId":"-3263510332551481190","camel.exchangeId":"ID-VRN26-1534867331800-0-3","camel.contextId":"IndividualClientService","camel.messageId":"ID-VRN26-1534867331800-0-4","camel.breadcrumbId":"ID-VRN26-1534867331800-0-3","camel.routeId":"rest_myroute","parentId":"-4589659693669010018"}
{"timestamp":"2018-08-21T16:04:37.288+00:00","level":"INFO","logger_name":"rest_myroute","message":"ApiRsp Response {\"recId\":\"123456\"}","traceId":"-4589659693669010018","spanId":"-3263510332551481190","camel.exchangeId":"ID-VRN26-1534867331800-0-3","camel.contextId":"IndividualClientService","camel.messageId":"ID-VRN26-1534867331800-0-4","camel.breadcrumbId":"ID-VRN26-1534867331800-0-3","camel.routeId":"rest_myroute","parentId":"-4589659693669010018"}
骆驼版本:2.21.0.000033-fuse-000001-redhat-1
这是骆驼虫吗?如果是这样,它固定了吗? 有解决方法吗?
答案 0 :(得分:3)
找到了解决方案。看起来像骆驼默认路由配置,如果发生错误,可以防止编组机构。即使您手动声明需要在.responseModel(MyClass.class)中编组
设置skipBindingOnErrorCode(false)
@Bean
RouteBuilder restConfiguration(){
RouteBuilder restConfiguration = new RouteBuilder() {
@Override
public void configure() throws Exception{
restConfiguration().component("servlet")
.bindingMode(RestBindingMode.json)
.skipBindingOnErrorCode(false) //!!!!!!!!! add this
.contextPath(apiContextPath);
}
};
return restConfiguration;
}