You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Camel REST应用浏览器二次请求返回304/500异常排查求助

问题分析与解决方案

你的问题核心在于Camel路由没有正确处理Facebook接口返回的304 Not Modified响应,导致后续的Jackson反序列化步骤抛出异常,最终返回500错误。

为什么会出现这个问题?

当浏览器第一次请求后,收到了Camel返回的ETag头,第二次请求时会自动携带If-None-Match头。你的路由中removeHeaders("CamelHttp*")并没有移除客户端发送的If-None-Match(因为它不是以CamelHttp开头的请求头),所以这个头会被直接转发给Facebook的API。

Facebook API识别到If-None-Match后,会返回304状态码且没有响应体。但你的路由后续依然执行了.unmarshal("model-jackson-dataformat")步骤——Jackson试图解析空的响应体,自然会抛出异常,最终导致Camel返回500错误。而Postman默认不会自动发送If-None-Match头,所以不会触发这个问题。

解决方案

这里提供两种可行的解决思路,你可以根据需求选择:


方案1:拦截并处理304响应

在路由中检查Facebook接口返回的状态码,如果是304,则直接将该状态码返回给客户端,跳过反序列化步骤。修改你的路由代码如下:

rest("/facebook")
    .get("/name")
    .description("Gets the name of the Facebook application")
    .route().id("get-app-name-route")
        .removeHeaders("CamelHttp*")
        .setHeader(HTTP_METHOD, constant(GET))
        .to("{{facebook.api.base.url}}/{{facebook.appID}}?fields=name&access_token={{facebook.permanentToken}}")
        // 添加分支处理304响应
        .choice()
            .when(header(Exchange.HTTP_RESPONSE_CODE).isEqualTo(304))
                // 直接返回304状态码,不执行反序列化
                .setHeader(Exchange.HTTP_RESPONSE_CODE, constant(304))
                .setBody(constant(null))
            .otherwise()
                .unmarshal("model-jackson-dataformat")
        .endChoice()
    .end()
    .endRest();

方案2:禁止转发客户端的缓存请求头

如果你希望每次都从Facebook获取最新数据(忽略浏览器的缓存请求),可以直接移除客户端发送的If-None-Match和If-Modified-Since头,这样Facebook API每次都会返回200和完整响应体,Camel就能正常处理:

rest("/facebook")
    .get("/name")
    .description("Gets the name of the Facebook application")
    .route().id("get-app-name-route")
        .removeHeaders("CamelHttp*")
        // 移除浏览器发送的缓存相关请求头,不转发给Facebook
        .removeHeader("If-None-Match")
        .removeHeader("If-Modified-Since")
        .setHeader(HTTP_METHOD, constant(GET))
        .to("{{facebook.api.base.url}}/{{facebook.appID}}?fields=name&access_token={{facebook.permanentToken}}")
        .unmarshal("model-jackson-dataformat")
    .end()
    .endRest();

额外优化建议

如果希望Camel自己处理缓存逻辑(比如管理ETag和304响应),可以考虑:

  • 使用Camel的cache组件,缓存Facebook返回的结果和ETag
  • 当客户端发送If-None-Match时,先对比本地缓存的ETag,如果匹配直接返回304,不调用Facebook API

这样可以减少对Facebook API的请求次数,同时避免转发缓存头带来的问题。

内容的提问来源于stack exchange,提问作者Spock

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:36:28