You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WireMock是否支持针对指定请求运行自定义代码实现状态存储?

WireMock自定义请求处理实现说明

首先可以明确:WireMock完全支持针对特定请求运行自定义代码,核心通过ResponseDefinitionTransformer响应转换器、RequestListener请求监听器等扩展机制实现,你提到的跨请求状态维护场景可以直接通过「自定义扩展+全局内存存储」的方案实现。

具体实现步骤

  • 1. 定义全局线程安全存储

    首先用单例模式实现一个全局存储容器,用于跨请求维护条目集合,Java示例代码如下:

    import java.util.Collections;
    import java.util.List;
    import java.util.Map;
    import java.util.concurrent.CopyOnWriteArrayList;
    
    public enum ItemDataStore {
        INSTANCE;
        // 用CopyOnWriteArrayList保证多请求并发写入的线程安全
        private final List<Map<String, Object>> itemList = new CopyOnWriteArrayList<>();
    
        public void addItem(Map<String, Object> item) {
            itemList.add(item);
        }
    
        public List<Map<String, Object>> getAllItems() {
            return itemList;
        }
    }
    

    这里用枚举实现单例,避免多线程环境下的实例初始化安全问题。

  • 2. 实现POST接口自定义处理扩展

    继承WireMock的ResponseDefinitionTransformer抽象类,实现POST请求的业务逻辑:解析请求体写入全局存储,返回创建成功响应。

    import com.fasterxml.jackson.core.type.TypeReference;
    import com.fasterxml.jackson.databind.ObjectMapper;
    import com.github.tomakehurst.wiremock.client.ResponseDefinitionBuilder;
    import com.github.tomakehurst.wiremock.common.FileSource;
    import com.github.tomakehurst.wiremock.extension.Parameters;
    import com.github.tomakehurst.wiremock.extension.ResponseDefinitionTransformer;
    import com.github.tomakehurst.wiremock.http.Request;
    import com.github.tomakehurst.wiremock.http.ResponseDefinition;
    
    public class PostItemTransformer extends ResponseDefinitionTransformer {
        private final ObjectMapper objectMapper = new ObjectMapper();
    
        @Override
        public ResponseDefinition transform(Request request, ResponseDefinition responseDefinition, FileSource fileSource, Parameters parameters) {
            try {
                // 解析POST请求的JSON body
                Map<String, Object> item = objectMapper.readValue(request.getBodyAsString(), new TypeReference<Map<String, Object>>() {});
                // 写入全局存储
                ItemDataStore.INSTANCE.addItem(item);
                // 构造201创建成功响应
                return ResponseDefinitionBuilder.responseDefinition()
                        .withStatus(201)
                        .withHeader("Content-Type", "application/json")
                        .withBody("{\"status\":\"success\",\"message\":\"条目添加完成\"}")
                        .build();
            } catch (Exception e) {
                // 参数异常返回400错误
                return ResponseDefinitionBuilder.responseDefinition()
                        .withStatus(400)
                        .withHeader("Content-Type", "application/json")
                        .withBody("{\"status\":\"fail\",\"message\":\"请求参数格式错误\"}")
                        .build();
            }
        }
    
        // 扩展名称,后续Stub配置时引用
        @Override
        public String getName() {
            return "add-item-transformer";
        }
    }
    
  • 3. 实现GET接口自定义处理扩展

    同样继承ResponseDefinitionTransformer,实现GET请求逻辑:直接读取全局存储的所有条目,序列化后返回。

    import com.fasterxml.jackson.databind.ObjectMapper;
    import com.github.tomakehurst.wiremock.client.ResponseDefinitionBuilder;
    import com.github.tomakehurst.wiremock.common.FileSource;
    import com.github.tomakehurst.wiremock.extension.Parameters;
    import com.github.tomakehurst.wiremock.extension.ResponseDefinitionTransformer;
    import com.github.tomakehurst.wiremock.http.Request;
    import com.github.tomakehurst.wiremock.http.ResponseDefinition;
    
    public class GetItemsTransformer extends ResponseDefinitionTransformer {
        private final ObjectMapper objectMapper = new ObjectMapper();
    
        @Override
        public ResponseDefinition transform(Request request, ResponseDefinition responseDefinition, FileSource fileSource, Parameters parameters) {
            try {
                // 读取全局存储所有条目,序列化为JSON
                String responseBody = objectMapper.writeValueAsString(ItemDataStore.INSTANCE.getAllItems());
                return ResponseDefinitionBuilder.responseDefinition()
                        .withStatus(200)
                        .withHeader("Content-Type", "application/json")
                        .withBody(responseBody)
                        .build();
            } catch (Exception e) {
                return ResponseDefinitionBuilder.responseDefinition()
                        .withStatus(500)
                        .withHeader("Content-Type", "application/json")
                        .withBody("{\"status\":\"fail\",\"message\":\"服务内部错误\"}")
                        .build();
            }
        }
    
        @Override
        public String getName() {
            return "list-items-transformer";
        }
    }
    
  • 4. 注册扩展并配置Stub规则

    1. 如果你使用独立运行的WireMock:将上述实现的类打为jar包,放到WireMock根目录的extensions文件夹下,启动时指定扩展类全限定名:
      java -jar wiremock-jre8-standalone-2.35.0.jar --extensions com.example.PostItemTransformer,com.example.GetItemsTransformer
      
    2. 如果你在单元测试中使用WireMock:构造WireMockServer实例时直接传入扩展类即可。
    3. 最后配置两个接口的Stub规则,绑定对应转换器:
      POST /items接口规则:
      {
        "request": {
          "method": "POST",
          "url": "/items"
        },
        "response": {
          "transformers": ["add-item-transformer"]
        }
      }
      
      GET /items接口规则:
      {
        "request": {
          "method": "GET",
          "url": "/items"
        },
        "response": {
          "transformers": ["list-items-transformer"]
        }
      }
      

如果需要多实例部署WireMock,只需要把全局内存存储替换为Redis、MySQL等共享存储即可实现跨实例的数据同步。

内容的提问来源于stack exchange,提问作者dotNET

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 04:36:08