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

无Spring Boot的Apache Camel表单上传路由JsonParseException问题

问题分析与解决方案

错误成因

  1. RestBindingMode.auto的自动绑定冲突:你配置的RestBindingMode.auto会让Camel根据请求头自动选择数据绑定格式,但对于multipart/form-data类型的请求,Camel的自动绑定逻辑会错误地尝试用JSON解析表单内容——尤其是你的实体类标注了@JsonProperty注解,进一步误导了Camel的解析逻辑,导致它把表单字段当成JSON来解析,从而抛出JsonParseException。
  2. 强制绑定实体类触发错误解析:rest端点中配置的.type(IRPageUploadRequestPayload.class)会触发Camel的请求绑定机制,要求将请求体转换为指定的实体类,但multipart/form-data的结构和JSON完全不同,这直接导致了解析失败。

解决方案

1. 关闭自动绑定,避免JSON解析

修改restConfiguration的绑定模式为RestBindingMode.off,阻止Camel自动尝试解析JSON:

restConfiguration()
        .component("servlet")
        .bindingMode(RestBindingMode.off) // 关闭自动绑定
        .dataFormatProperty("prettyPrint", "true");

如果不想全局关闭绑定,也可以针对当前rest端点单独设置:

rest("/pageUpload")
        .post()
        .description("IG API to upload file in ImageRight")
        .id("pageUpload")
        .consumes("multipart/form-data")
        .produces(APPLICATION_JSON)
        .bindingMode(RestBindingMode.off) // 单独关闭该端点的绑定
        .route()
        .to(PAGE_UPLOAD)
        .endRest();

2. 移除实体类绑定配置

删除rest端点中的.type(IRPageUploadRequestPayload.class),因为我们不需要Camel自动将表单数据绑定到实体类,而是要手动处理multipart内容。

3. 手动处理multipart表单数据

unmarshall().mimeMultipart()执行后,Camel会将表单数据解析为MultipartFormData,你可以通过Simple表达式或自定义Processor提取字段,再组装成下游服务需要的请求格式。

示例修改后的路由类:

public class PageUpload extends RouteBuilder {

    @Override
    public void configure() throws Exception {
        String URL = "some link";

        restConfiguration()
                .component("servlet")
                .bindingMode(RestBindingMode.off)
                .dataFormatProperty("prettyPrint", "true");

        rest("/pageUpload")
                .post()
                .description("IG API to upload file in ImageRight")
                .id("pageUpload")
                .consumes("multipart/form-data")
                .produces(APPLICATION_JSON)
                .route()
                .to(PAGE_UPLOAD)
                .endRest();

        from(PAGE_UPLOAD)
                .routeId(this.getClass().getSimpleName())
                .unmarshall().mimeMultipart()
                .process(new TokenProcessor())
                // 手动提取表单字段,组装JSON请求体(根据下游服务要求调整)
                .setBody(simple("{\n" +
                        "  \"DocumentType\": \"${header.CamelMultipartFormData.DocumentType}\",\n" +
                        "  \"FileNumber\": \"${header.CamelMultipartFormData.FileNumber}\",\n" +
                        "  \"PolicyEffectiveDate\": \"${header.CamelMultipartFormData.PolicyEffectiveDate}\",\n" +
                        "  \"Description\": \"${header.CamelMultipartFormData.Description}\",\n" +
                        "  \"UserId\": \"${header.CamelMultipartFormData.UserId}\",\n" +
                        "  \"Username\": \"${header.CamelMultipartFormData.Username}\"\n" +
                        "}"))
                // 若下游需要接收文件,需单独处理Content字段的上传逻辑
                .toD(URL + BRIDGE_ENDPOINT)
                .log("Azure Response Body: ${body}")
                .end();
    }
}

如果下游服务也需要接收multipart/form-data,则无需转换为JSON,直接转发unmarshall后的MultipartFormData即可,确保请求头的Content-Type保持正确。

4. 文件字段处理注意事项

对于Content文件字段,unmarshall().mimeMultipart()执行后,文件内容会以InputStream或byte[]形式存在于MultipartFormData中,可通过${body.getAttachment("Content")}获取,再根据下游服务要求处理文件上传逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 06:23:22