【发布时间】:2017-01-18 15:47:25
【问题描述】:
我通过 HTTP-POST 向我的 Camel-Spark-REST 组件发送 invalid JSON-body。在我的 Camel 路线上,JSON 主体将通过 Jackson 库从 JSON 转换(编组)为 Java 对象。由于 JSON 正文无效,封送处理失败。使用骆驼 doTry/doCatch 元素,我尝试捕获异常并自己处理它们。这看起来像这样:
rest("/v1/users")
.consumes("application/json")
.produces("application/json")
.post("/insert")
.to("direct:restInput");
from("direct:restInput")
.doTry()
.marshal().json(JsonLibrary.Jackson)
[...]
.process(new Processor() {
public void process(Exchange exchange) throws Exception {
//throw new JsonParseException(null, "");
}
})
[...]
.doCatch(JsonParseException.class)
.process(new Processor() {
public void process(Exchange exchange) throws Exception {
System.out.println("JsonParseException occured");
}
})
.doCatch(Exception.class)
.process(new Processor() {
public void process(Exchange exchange) throws Exception {
System.out.println("Exception occured");
}
})
.end()
.marshal();
如果存在无效的 JSON-body,JsonParseException 将由 Jackson marshaler 抛出。正如您在上面看到的,我尝试捕获 JsonParseException 异常,它应该在我的控制台上输出JsonParseException occured。
但异常未捕获,我在控制台上获得了完整的堆栈跟踪:
Message History
---------------------------------------------------------------------------------------------------------------------------------------
RouteId ProcessorId Processor Elapsed (ms)
[route4 ] [route4 ] [spark-rest://post:v1/users/insert?accept=application%2Fjson ] [ 42]
[route4 ] [restBinding4 ] [ ] [ 39]
Stacktrace
---------------------------------------------------------------------------------------------------------------------------------------
com.fasterxml.jackson.core.JsonParseException: Unexpected character (':' (code 58)): was expecting comma to separate Array entries
at [Source: java.io.ByteArrayInputStream@1aa6eb2; line: 23, column: 17]
at com.fasterxml.jackson.core.JsonParser._constructError(JsonParser.java:1702) ~[jackson-core-2.8.3.jar:2.8.3]
at com.fasterxml.jackson.core.base.ParserMinimalBase._reportError(ParserMinimalBase.java:558) ~[jackson-core-2.8.3.jar:2.8.3]
at com.fasterxml.jackson.core.base.ParserMinimalBase._reportUnexpectedChar(ParserMinimalBase.java:456) ~[jackson-core-2.8.3.jar:2.8.3]
at com.fasterxml.jackson.core.json.UTF8StreamJsonParser.nextToken(UTF8StreamJsonParser.java:761) ~[jackson-core-2.8.3.jar:2.8.3]
at com.fasterxml.jackson.databind.deser.std.UntypedObjectDeserializer$Vanilla.mapArray(UntypedObjectDeserializer.java:594) ~[jackson-databind-2.8.3.jar:2.8.3]
at com.fasterxml.jackson.databind.deser.std.UntypedObjectDeserializer$Vanilla.deserialize(UntypedObjectDeserializer.java:510) ~[jackson-databind-2.8.3.jar:2.8.3]
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:3789) ~[jackson-databind-2.8.3.jar:2.8.3]
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2899) ~[jackson-databind-2.8.3.jar:2.8.3]
at org.apache.camel.component.jackson.JacksonDataFormat.unmarshal(JacksonDataFormat.java:172) ~[camel-jackson-2.18.0.jar:2.18.0]
at org.apache.camel.processor.UnmarshalProcessor.process(UnmarshalProcessor.java:69) ~[camel-core-2.18.0.jar:2.18.0]
at org.apache.camel.component.rest.RestConsumerBindingProcessor.process(RestConsumerBindingProcessor.java:189) ~[camel-core-2.18.0.jar:2.18.0]
at org.apache.camel.management.InstrumentationProcessor.process(InstrumentationProcessor.java:77) ~[camel-core-2.18.0.jar:2.18.0]
at org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:542) [camel-core-2.18.0.jar:2.18.0]
at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:197) [camel-core-2.18.0.jar:2.18.0]
at org.apache.camel.processor.Pipeline.process(Pipeline.java:120) [camel-core-2.18.0.jar:2.18.0]
at org.apache.camel.processor.Pipeline.process(Pipeline.java:83) [camel-core-2.18.0.jar:2.18.0]
at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:197) [camel-core-2.18.0.jar:2.18.0]
at org.apache.camel.processor.DelegateAsyncProcessor.process(DelegateAsyncProcessor.java:97) [camel-core-2.18.0.jar:2.18.0]
at org.apache.camel.component.sparkrest.CamelSparkRoute.handle(CamelSparkRoute.java:46) [camel-spark-rest-2.18.0.jar:2.18.0]
at spark.RouteImpl$1.handle(RouteImpl.java:58) [spark-core-2.3.jar:?]
at spark.webserver.MatcherFilter.doFilter(MatcherFilter.java:162) [spark-core-2.3.jar:?]
at spark.webserver.JettyHandler.doHandle(JettyHandler.java:61) [spark-core-2.3.jar:?]
at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:189) [jetty-server-9.2.19.v20160908.jar:9.2.19.v20160908]
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141) [jetty-server-9.2.19.v20160908.jar:9.2.19.v20160908]
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:97) [jetty-server-9.2.19.v20160908.jar:9.2.19.v20160908]
at org.eclipse.jetty.server.Server.handle(Server.java:499) [jetty-server-9.2.19.v20160908.jar:9.2.19.v20160908]
at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:311) [jetty-server-9.2.19.v20160908.jar:9.2.19.v20160908]
at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:257) [jetty-server-9.2.19.v20160908.jar:9.2.19.v20160908]
at org.eclipse.jetty.io.AbstractConnection$2.run(AbstractConnection.java:544) [jetty-io-9.2.19.v20160908.jar:9.2.19.v20160908]
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:635) [jetty-util-9.2.19.v20160908.jar:9.2.19.v20160908]
at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:555) [jetty-util-9.2.19.v20160908.jar:9.2.19.v20160908]
at java.lang.Thread.run(Thread.java:745) [?:1.8.0_101]
根据我的测试,这发生在.marshal().json(JsonLibrary.Jackson) 部分。如果我发送一个有效的 JSON-body 并在第一个处理器中手动抛出 JsonParseException(参见注释行),那么异常将被捕获。 Exception.class catch 块也永远不会被调用,所以它可以被排除,我试图捕捉“错误”的异常。是否有机会从 Jackson marshaler 中捕获异常,或者是否有一个 Camel 组件来检查 JSON 主体,如果它格式正确,我可以将它放在 marshaler 的前面?
【问题讨论】:
-
您确定在
.marshal().json(JsonLibrary.Jackson)行上引发了异常吗?我不知道 spark-rest 端点,但是当使用带有 REST DSL 的码头端点时,com.fasterxml.jackson.core.JsonParseException会在端点本身中引发。不在随后的编组步骤中。在堆栈跟踪旁边,您还应该在日志中看到消息历史记录。你能把它也发布和/或检查历史实际上包含编组步骤吗? -
你是对的@Ralf,我检查了历史记录,它发生在 restBinding 中。我完全忽略了那部分,对不起。但是不可能将“doTry/doCatch”部分放在 .post("...") 部分之前。所以,我不能使用 doTry/doCatch 或者你是如何解决这个案例的?你改用 onException 了吗?
-
谢谢@Ralf,与 onException(JsonParseException.class).handled(true).to("...");在全球范围内它有效。如果您想将您的评论发布为 anwser,我将接受它作为“最佳答案”。
标签: java json exception jackson apache-camel