无Spring Boot的Apache Camel表单上传路由JsonParseException问题
问题分析与解决方案
错误成因
- RestBindingMode.auto的自动绑定冲突:你配置的
RestBindingMode.auto会让Camel根据请求头自动选择数据绑定格式,但对于multipart/form-data类型的请求,Camel的自动绑定逻辑会错误地尝试用JSON解析表单内容——尤其是你的实体类标注了@JsonProperty注解,进一步误导了Camel的解析逻辑,导致它把表单字段当成JSON来解析,从而抛出JsonParseException。 - 强制绑定实体类触发错误解析: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
相关产品推荐
相关产品推荐

