Camel HTTP4上传JSON触发InvalidPayloadException问题求助
你在CSV上传时用multipart/form-data格式正常,但切换到JSON上传时遇到了类型转换异常,这其实是因为JSON接口通常不需要用multipart格式,大部分场景下直接发送JSON字符串作为请求体即可。我来帮你一步步梳理问题和解决方案:
问题根源
你当前的代码给JSON上传也套用了CSV的MultipartEntityBuilder构建请求体,而Camel HTTP4组件在处理这个请求时,期望的是java.io.InputStream类型的请求体,但没有对应的转换器能把MultipartFormEntity转成InputStream,所以抛出了InvalidPayloadException。
而且从你的路由配置看,已经通过jsonMapper处理过消息体了,说明body应该已经是JSON格式的数据,完全不需要再包装成multipart表单。
解决方案
你需要针对CSV和JSON的上传场景做区分处理,调整请求体格式和请求头:
1. 区分上传逻辑,修改uploadProcessor代码
在uploadProcessor里判断当前处理的是CSV还是JSON文件,然后分别设置对应的请求体和请求头:
LOG.info("Uploading File for CustKey: " + custKey + " and Tenant: " + tenant); StringBuilder authHeader = new StringBuilder("Bearer "); authHeader.append(token); LOG.info("Authorization: " + authHeader.toString()); // 通用配置 exchange.setProperty("CamelCharsetName", "UTF-8"); exchange.getIn().setHeader("CamelHttpCharacterEncoding", "UTF-8"); exchange.getIn().setHeader("CamelHttpUri", uploadUrl); exchange.getIn().setHeader("CamelHttpMethod", "POST"); exchange.getIn().setHeader("Tenant", tenant); exchange.getIn().setHeader("Authorization", authHeader.toString()); // 通过文件名判断是否为JSON上传(你也可以用其他标识,比如路由参数) String fileName = (String) exchange.getIn().getHeader(Exchange.FILE_NAME); boolean isJsonUpload = fileName.endsWith(".json"); if (isJsonUpload) { // JSON上传逻辑:直接用jsonMapper处理后的JSON作为请求体 exchange.getIn().setHeader("CamelAcceptContentType", "application/json"); exchange.getIn().setHeader(Exchange.CONTENT_TYPE, "application/json"); // 移除CSV专属的请求头 exchange.getIn().removeHeader("x-ge-csvformat"); // 注意:这里不需要构建MultipartEntity,jsonMapper已经把body转为JSON格式了 } else { // CSV上传逻辑:保留原有的multipart方式 exchange.getIn().setHeader("CamelAcceptContentType", "multipart/form-data"); exchange.getIn().setHeader("x-ge-csvformat", "ODB"); File file = exchange.getIn().getBody(File.class); MultipartEntityBuilder entity = MultipartEntityBuilder.create(); entity.addBinaryBody("file", file); entity.addTextBody("name", fileName); exchange.getIn().setBody(entity.build()); }
2. 确认JSON接口的协议要求
如果调整后仍有问题,需要先明确JSON接口的具体要求:
- 是接收
application/json格式的请求体(直接传JSON字符串),还是需要用multipart/form-data上传JSON文件? - 如果是后者,你可以尝试把MultipartEntity转换为InputStream:
不过这种场景非常少见,绝大多数JSON接口都是直接接收JSON请求体。MultipartFormEntity entity = (MultipartFormEntity) entity.build(); exchange.getIn().setBody(entity.getContent()); // 获取实体对应的InputStream
3. 路由配置优化
你的路由里先调用jsonMapper处理,再进入uploadProcessor,建议确保jsonMapper处理后,body已经是JSON字符串或字节数组,这样在uploadProcessor里只需设置正确的Content-Type即可,不需要额外的序列化操作。
总结
核心问题就是JSON上传误用了CSV的multipart格式,只要针对JSON场景切换为直接发送JSON请求体,并设置Content-Type: application/json,就能解决这个类型转换异常。
内容的提问来源于stack exchange,提问作者GLMills

