我有一个带有 apache camel 的 springboot 应用程序。在其中我有一个 Camel 语境。 我正在尝试通过带有 key 对值的 curl 发送 json,并通过路由对其进行处理。
发送数据:
curl --header "Content-Type: application/json" -X POST -d '{"msgId=EB2C7265-EF68-4F8F-A709-BEE2C52E842B", "ticket":"ERR001"}' http://lcalhost:8888/api/erroradmin
Camel 上下文.xml:
<?xml version="1.0" encoding="utf-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd">
<camelContext xmlns="http://camel.apache.org/schema/spring" useMDCLogging="true">
<properties>
<property key="CamelLogEipName" value="ThisLogger"/>
</properties>
<dataFormats>
<!-- here we define a Json data format with the id jack and that it should use the TestPojo as the class type when
doing unmarshal. The unmarshalTypeName is optional, if not provided Camel will use a Map as the type -->
<json id="jack" library="Jackson" unmarshalTypeName="java.util.HashMap"/>
</dataFormats>
<restConfiguration component="jetty" port="8888" bindingMode="json">
<dataFormatProperty key="prettyPrint" value="true"/>
</restConfiguration>
<rest path="/api/erroradmin">
<get uri="{id}">
<to uri="direct:processErrorAdminGet"/>
</get>
<post>
<to uri="direct:processErrorAdminPost"/>
</post>
</rest>
<route id="processErrorAdminPost">
<from uri="direct:processErrorAdminPost"/>
<log message="Route(processErrorAdminPost): ${body}"/>
<unmarshal>
<custom ref="jack"/>
</unmarshal>
<log message="Route(processErrorAdminPost): ${body}"/>
</route>
</camelContext>
</beans>
我得到以下 Stacktrace:
org.apache.camel.InvalidPayloadException: No body available of type: java.io.InputStream but has value: {msgId=D507B9EE-176D-4F3C-88E7-9E36CC2B9731, ticket=ERR001} of type: java.util.LinkedHashMap on: HttpMessage@0x28c1a31a. Caused by: No type converter available to convert from type: java.util.LinkedHashMap to the required type: java.io.InputStream with value {msgId=D507B9EE-176D-4F3C-88E7-9E36CC2B9731, ticket=ERR001}. Exchange[09395660-c947-47f1-b00f-d0d3030a39d1]. Caused by: [org.apache.camel.NoTypeConversionAvailableException - No type converter available to convert from type: java.util.LinkedHashMap to the required type: java.io.InputStream with value {msgId=D507B9EE-176D-4F3C-88E7-9E36CC2B9731, ticket=ERR001}]
最佳答案
欢迎使用 Stackoverflow!
我坚信第 13 行提到的 bindingMode="json"
是这次失败的根本原因。
manual说
When using binding you must also configure what POJO type to map to. This is mandatory for incoming messages, and optional for outgoing.
我真的很害怕 XML DSL,但是这里有一个近似等效的 Java 其余 DSL。
@Component
@Slf4j
public class MySpringBootRouter extends RouteBuilder {
@Override
public void configure() {
restConfiguration()
.component("undertow")
.host("127.0.0.1")
.port(9090)
//This works only when a POJO mapping is possible - Ref: https://camel.apache.org/manual/latest/rest-dsl.html
//<quote>When using binding you must also configure what POJO type to map to. This is mandatory for incoming messages, and optional for outgoing.</quote>
//.bindingMode(RestBindingMode.json)
.dataFormatProperty("prettyPrint", "true");
rest("/api")
.post("/erroradmin")
.to("direct:postError")
.get("/erroradmin/{id}").to("direct:getError");
from("direct:getError")
.process(exchange -> {
exchange.getMessage().setBody(("{'messageID':'" + UUID.randomUUID().toString() + "','ticketID':'1234'}"));
});
from("direct:postError")
.unmarshal()
.json(JsonLibrary.Jackson)
.process(exchange -> {
log.info("Type of incoming body:{}", exchange.getIn().getBody().getClass().getName());
log.info("Incoming body:{}", exchange.getIn().getBody());
}).transform().constant("{'httpResponse:200':'OK'}");
}
}
启动后,我使用 cURL 发送有效载荷,如下所示
curl -d '{"msgId":"EB2C7265-EF68-4F8F-A709-BEE2C52E842B", "ticket":"ERR001"}' -H "Content-Type: application/json" -X POST http://localh
ost:9090/api/erroradmin
你会在日志中看到类似下面的内容
2020-02-18 11:44:13.032 INFO 2708 --- [ XNIO-1 task-4] o.a.c.community.so.MySpringBootRouter : Type of incoming body:java.util.LinkedHashMap
2020-02-18 11:44:13.032 INFO 2708 --- [ XNIO-1 task-4] o.a.c.community.so.MySpringBootRouter : Incoming body:{msgId=EB2C7265-EF68-4F8F-A709-BEE2C52E842B, ticket=ERR001}
哦,顺便说一句,您的原始 JSON 负载格式不正确。 整个Java项目是available here , 如果你想玩的话
编辑:额外的标题处理步骤
from("direct:postError")
.unmarshal()
.json(JsonLibrary.Jackson)
.process(exchange -> {
LinkedHashMap map = exchange.getIn().getBody(LinkedHashMap.class);
map.keySet().stream().forEach( item -> exchange.getIn().setHeader(item.toString(),map.get(item)));
})
//This step is just to print the Headers. Doesnt do anything useful
.process( exchange -> {
log.info(String.valueOf(exchange.getIn().getHeaders()));
})
.transform().constant("{'httpResponse:200':'OK'}");
关于json - Apache-camel:如何将 json 对象(由 curl 发送)处理为 header ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60264067/