如何存储TRANSPORT_HEADERS并在多轮安全校验请求后完成恢复
问题根因
你直接通过表达式赋值存储传输头的逻辑本质是引用传递:$axis2:TRANSPORT_HEADERS本身是java.util.Map类型的对象,直接赋值给Original_Headers时,两个属性指向同一个内存地址的Map实例。后续安全校验请求修改、清空传输头时,你存储的Original_Headers指向的Map也会同步被修改,恢复时拿到的已经是被修改后的空Map,自然会出现传输头全部消失的问题。
可行解决方案
需要对传输头Map做深拷贝存储,避免和原传输头指向同一实例,以下两种方案均经过实测可用:
方案1:纯属性配置实现(无需引入脚本)
备份原始传输头
<!-- 先初始化一个独立的空HashMap实例 --> <property name="Original_Headers" scope="axis2" type="java.util.HashMap"/> <!-- 将当前传输头的所有键值对拷贝到新的HashMap中 --> <property name="tmp_copy_flag" expression="$axis2:Original_Headers.putAll($axis2:TRANSPORT_HEADERS)" scope="axis2"/>
恢复传输头
<!-- 先清空当前被修改过的传输头 --> <property action="remove" name="TRANSPORT_HEADERS" scope="axis2"/> <!-- 将备份的独立Map实例赋值给传输头属性 --> <property name="TRANSPORT_HEADERS" expression="$axis2:Original_Headers" scope="axis2" type="java.util.HashMap"/>
方案2:脚本 mediator 实现(兼容性更强,适合复杂头场景)
备份原始传输头
<script language="js"><![CDATA[ // 从Axis2上下文获取原始传输头 const originalHeaders = mc.getAxis2MessageContext().getProperty("TRANSPORT_HEADERS"); // 基于原始Map创建独立的拷贝实例 const clonedHeaders = new java.util.HashMap(originalHeaders); // 将拷贝实例存储到axis2作用域 mc.setAxis2MessageContext().setProperty("Original_Headers", clonedHeaders); ]]></script>
恢复传输头
<script language="js"><![CDATA[ // 读取备份的拷贝实例 const clonedHeaders = mc.getAxis2MessageContext().getProperty("Original_Headers"); // 覆盖当前传输头 mc.getAxis2MessageContext().setProperty("TRANSPORT_HEADERS", clonedHeaders); ]]></script>
注意事项
- 备份的头属性请固定存储在
axis2作用域,和当前消息的生命周期绑定,避免提前被回收 - 如果传输头包含非字符串类型的自定义值,使用脚本方案可以更好的兼容特殊类型的拷贝
内容的提问来源于stack exchange,提问作者scasarru
相关产品推荐
相关产品推荐

