WSO2 APIM 3.2自定义Handler条件加载及二进制响应处理问题
WSO2 APIM 3.2 自定义Handler开发问题解决方案
1. Velocity模板配置异常修复
你遇到的Handler不加载、属性占位符不解析问题,由两个配置错误导致:
- 条件判断语法错误:原配置中
#if($apiObj.additionalProperties.get('encrypted') == "true"))末尾多了1个右括号,Velocity语法解析直接失败,整个条件块不会被渲染,Handler自然无法加载 - 属性取值逻辑错误:APIM 3.2的velocity_template渲染Handler配置时,不支持在property的value属性中直接调用additionalProperties的get方法,需要提前将属性值赋值给Velocity临时变量再引用,同时要增加空值判断,避免空指针导致渲染中断
修正后的配置片段如下:
#set($isEncrypted = $apiObj.additionalProperties.get("encrypted")) #if($isEncrypted && $isEncrypted.toString() == "true") <handler class="org.rudi.wso2.mediation.EncryptedMediaHandler"> #set($configEncryptedMime = $apiObj.additionalProperties.get("encrypted_mime_type")) #set($configNormalMime = $apiObj.additionalProperties.get("mime_type")) <property name="encryptedMimeType" value="$configEncryptedMime"/> <property name="mimeType" value="$configNormalMime"/> <property name="providerUuid" value="dummy"/> </handler> #end
注意:修改完velocity_template.xml后需要重启APIM节点,再重新发布对应API触发Synapse配置重新生成,不要直接修改runtime目录下已生成的API配置文件,否则下次发布时配置会被覆盖。
2. 二进制响应处理与Content-Type修改
你当前实现的replaceBody方法逻辑在小文件场景下是可行的,补充几个必要的处理点:
- 响应处理逻辑必须写在自定义Handler的
handleResponse()方法中,不要写在handleRequest()方法内 - 解密完成后修改Content-Type的实现代码:
// 获取传输头映射 Map<String, Object> transportHeaders = (Map<String, Object>) axis2MC.getProperty( org.apache.axis2.context.MessageContext.TRANSPORT_HEADERS ); // 替换为解密后的MIME类型 transportHeaders.put("Content-Type", 你从Handler配置中读取的mimeType值); // 移除原Content-Length头,避免长度不匹配导致客户端收包异常,APIM后续流程会自动重新计算长度 transportHeaders.remove("Content-Length");
3. 大文件、分块传输场景优化建议
当前实现强制构建全量消息的逻辑会在大文件场景下触发内存溢出,需要做以下调整:
- 移除
RelayUtils.buildMessage(axis2MC, true)和axis2MC.setProperty(RelayConstants.FORCE_RESPONSE_EARLY_BUILD, Boolean.TRUE)两行代码,这两个配置会强制把整个分块响应全量缓冲到内存,GB级文件场景会直接触发OOM - 解密逻辑必须实现流式处理:不要在
modify方法中把整个输入流读成byte数组再处理,每次从原流读取固定大小缓冲区(推荐8KB~16KB),分段解密后写入输出流,全程不持有全量文件的字节数据 - 确保你使用的
StreamingOnRequestDataSource实现支持流式读取,不要在DataSource内部缓存全量内容 - 分块传输场景下,将axis2上下文的
DISABLE_CHUNKING属性设为false,保持分块传输逻辑,不要强制聚合全量响应后再返回给客户端 - 节点替换完成后,不要调用OM树的序列化、clone方法,避免触发全量内容加载到内存
- 增加流异常兜底逻辑:解密过程中如果出现流读取、解密错误,要及时关闭打开的输入输出流,直接返回500错误状态,避免连接泄漏
内容的提问来源于stack exchange,提问作者Fni18300
相关产品推荐
相关产品推荐

