如何用WireMock动态修改XML响应元素并部署自定义转换器?
WireMock动态修改XML响应、依赖问题及Docker部署方案
一、动态生成XML元素值的实现方法
要实现运行时计算值并修改XML响应,核心是编写自定义响应转换器,具体步骤如下:
- 编写类实现
ResponseDefinitionTransformerV2接口,重写transform方法,在方法内完成XML解析、值计算、元素修改的逻辑。 - 示例代码(给
<orderId>元素生成随机UUID作为动态值):
import com.github.tomakehurst.wiremock.common.FileSource; import com.github.tomakehurst.wiremock.extension.Parameters; import com.github.tomakehurst.wiremock.extension.ResponseDefinitionTransformerV2; import com.github.tomakehurst.wiremock.http.Request; import com.github.tomakehurst.wiremock.http.ResponseDefinition; import org.w3c.dom.Document; import org.w3c.dom.Element; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import java.io.StringReader; import java.io.StringWriter; import java.util.UUID; public class DynamicXmlTransformer extends ResponseDefinitionTransformerV2 { @Override public ResponseDefinition transform(Request request, ResponseDefinition responseDefinition, FileSource files, Parameters parameters) { String originalXml = responseDefinition.getBody(); try { // 解析原始XML DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = factory.newDocumentBuilder(); Document doc = builder.parse(new StringReader(originalXml)); // 定位要修改的元素 Element orderIdElement = (Element) doc.getElementsByTagName("orderId").item(0); if (orderIdElement != null) { // 运行时计算值(替换为你的业务规则逻辑) String dynamicValue = UUID.randomUUID().toString(); orderIdElement.setTextContent(dynamicValue); } // 将修改后的DOM转回XML字符串 Transformer transformer = TransformerFactory.newInstance().newTransformer(); StringWriter writer = new StringWriter(); transformer.transform(new DOMSource(doc), new StreamResult(writer)); String modifiedXml = writer.toString(); // 返回修改后的响应 return ResponseDefinition.copyOf(responseDefinition) .withBody(modifiedXml) .build(); } catch (Exception e) { throw new RuntimeException("修改XML响应失败", e); } } @Override public String getName() { return "dynamic-xml-transformer"; // 此名称需与后续映射配置保持一致 } }
二、ResponseDefinitionTransformerV2的依赖问题
你当前使用的WireMock 3.0.4核心依赖已包含该类,无需额外添加依赖。若找不到类,排查以下几点:
- 确认导入路径为
com.github.tomakehurst.wiremock.extension.ResponseDefinitionTransformerV2,避免包名拼写错误 - 若转换器写在主代码目录,但依赖的
scope为test,会导致主代码无法引用,需调整scope或把转换器移至测试目录 - 清理Maven/Gradle本地缓存,重新同步依赖
三、Docker部署自定义转换器的步骤
WireMock Docker镜像支持加载外部扩展,操作步骤如下:
- 打包转换器JAR:用Maven/Gradle将转换器类打成JAR包。若用Maven,可配置
maven-jar-plugin确保生成合法JAR,执行mvn clean package即可得到包文件。 - 挂载JAR并启动容器:启动时将JAR挂载到容器的
/var/wiremock/extensions目录,同时指定启用你的扩展类。示例命令:
docker run -d \ -p 8080:8080 \ -v $(pwd)/dynamic-xml-transformer.jar:/var/wiremock/extensions/dynamic-xml-transformer.jar \ -v $(pwd)/mappings:/var/wiremock/mappings \ wiremock/wiremock:3.0.4 \ --extensions com.your.package.DynamicXmlTransformer
- 配置映射文件:在
mappings目录下创建响应映射,指定使用自定义转换器。示例order-mapping.json:
{ "request": { "method": "GET", "url": "/api/order" }, "response": { "status": 200, "body": "<order><orderId>PLACEHOLDER</orderId><amount>100</amount></order>", "headers": { "Content-Type": "application/xml" }, "transformers": ["dynamic-xml-transformer"] // 对应转换器getName()返回的名称 } }
内容的提问来源于stack exchange,提问作者Kelly Goedert
相关产品推荐
相关产品推荐

