【问题标题】:How to enable Response Templating on a Wiremock Servlet?如何在 Wiremock Servlet 上启用响应模板?
【发布时间】:2018-05-16 00:41:32
【问题描述】:

我正在从https://github.com/tomakehurst/wiremock/tree/master/sample-war 实现这个项目的 servlet 上运行 Wiremock

我能够将它部署到 Tomcat 中并运行它。

现在,我想在此服务器上启用Response Templating,以便我可以使用把手模板来调整响应正文。我看到了一些与 Junit 规则、directly setting this up from the code 以及独立服务器相关的解决方案,但找不到从 servlet 启用响应模板的解决方案。

如何从wiremock servlet 启用此功能?

【问题讨论】:

  • 您找到解决方案了吗? servlet 的wiremock 最多是半生不熟。

标签: java tomcat servlets wiremock


【解决方案1】:

如果您想在 docker 中使用wiremock,我在这里有一个示例 docker-compose.yaml,其中包含详细的日志记录和模板。

使用 docker-compose up 在 docker 容器中启动 Wiremock。

docker-compose.yaml 示例:

version: "3"
services:
 wiremock:
  image: rodolpheche/wiremock:latest
  ports:
    - "8181:8080"
  volumes:
    - ./__files/:/./home/wiremock/__files/
    - ./mappings/:/./home/wiremock/mappings/
  command:
    - -verbose
    - -global-response-templating

docker-compose up(在您保存 yaml 的目录中,并接受文件系统访问请求) 那么你应该准备好了。

Wiremock 网址将是 http://localhost:8181

然后用真实数据记录 (http://localhost:8181/__admin/recorder)

将正文拆分为一个单独的文件,并将其放在 __files 文件夹中。 指向请求文件中带有“bodyFileName”的文件(映射)

我在这里有一些建议。 mobileera_wiremock_kb

【讨论】:

  • 谢谢!为我节省了很多时间!
【解决方案2】:

好吧,我终于找到了答案, 您需要创建自定义侦听器扩展 ServletContextListener,然后以编程方式设置响应模板。

public class CustomListener implements ServletContextListener {

private static final String APP_CONTEXT_KEY = "WireMockApp";

@Override
public void contextInitialized(ServletContextEvent sce) {
    ServletContext context = sce.getServletContext();

    boolean verboseLoggingEnabled = Boolean.parseBoolean(
            firstNonNull(context.getInitParameter("verboseLoggingEnabled"), "true"));
    WarConfiguration warConfiguration = new WarConfiguration(context);
    warConfiguration.extensionsOfType(MockTokenTemplate.class);
    final WireMockConfiguration wireMockConfiguration =WireMockConfiguration.wireMockConfig();
    wireMockConfiguration.extensions("com.test.MockTokenTemplate","com.test.MockTokenInqTemplate");
    //wireMockConfiguration.jettySettings();
    wireMockConfiguration.containerThreads(Integer.valueOf(200));
    wireMockConfiguration.disableRequestJournal()
            .containerThreads(Integer.valueOf(200))
            .jettyAcceptors(Integer.valueOf(-1))
            .jettyAcceptQueueSize(Integer.valueOf(1000))
            .jettyHeaderBufferSize(Integer.valueOf(8192));
    String fileSourceRoot = context.getInitParameter("WireMockFileSourceRoot");
 final FileSource fileSource = new ServletContextFileSource(context, fileSourceRoot);
    wireMockConfiguration.fileSource(fileSource);
    //wireMockConfiguration.usingFilesUnderDirectory("/WEB-INF/wiremock/");

    //wireMockConfiguration =(WireMockConfiguration) warConfiguration;
    WireMockApp wireMockApp = new WireMockApp(wireMockConfiguration, new NotImplementedContainer());
    context.setAttribute(APP_CONTEXT_KEY, wireMockApp);
    context.setAttribute(StubRequestHandler.class.getName(), wireMockApp.buildStubRequestHandler());
    context.setAttribute(AdminRequestHandler.class.getName(), wireMockApp.buildAdminRequestHandler());
    context.setAttribute(Notifier.KEY, new Slf4jNotifier(verboseLoggingEnabled));
}

/**
 * @param context Servlet context for parameter reading
 * @return Maximum number of entries or absent
 */
private Optional<Integer> readMaxRequestJournalEntries(ServletContext context) {
    String str = context.getInitParameter("maxRequestJournalEntries");
    if(str == null) {
        return Optional.absent();
    }
    return Optional.of(Integer.parseInt(str));
}

@Override
public void contextDestroyed(ServletContextEvent sce) {
}

}

如果您在创建自定义响应模板方面需要帮助,请告诉我。

【讨论】:

  • 这是很久以前的事了,我不得不转向不同的优先事项,所以无法测试它。希望这对面临这种情况的人有所帮助。
【解决方案3】:

我通过扩展和覆盖 WireMockWebContextListener

definitionTransformer 添加到 ServletListener

这会尽可能多地保留配置库存,并使用 Spring 功能自动注册新的 Transformers,而无需任何其他配置更改。使用最新的 wiremock 工件 2.26.3

以下是完整的设置配置和实现。

public abstract class AbstractResponseDefinitionTransformer extends ResponseDefinitionTransformer implements Extension {

    @Override
    public String getName() {

    return WordUtils.uncapitalize(getClass().getSimpleName());
    }
}

@Component
public class CustomResponseDefinitionTransformer extends AbstractResponseDefinitionTransformer {

    @Override
    public ResponseDefinition transform(Request request, ResponseDefinition responseDefinition, FileSource files,
                                        Parameters parameters) {

        System.out.println("Hello World !!!");

        return responseDefinition;
    }
}

public class CustomWireMockWebContextListener extends WireMockWebContextListener {

    private static final String APP_CONTEXT_KEY = "WireMockApp";

    private final List<? extends AbstractResponseDefinitionTransformer> abstractResponseDefinitionTransformers;

    public CustomWireMockWebContextListener() {
        this(Collections.emptyList());
    }

    public CustomWireMockWebContextListener(
            List<? extends AbstractResponseDefinitionTransformer> abstractResponseDefinitionTransformers) {
        this.abstractResponseDefinitionTransformers = abstractResponseDefinitionTransformers;
    }

        @Override
        public void contextInitialized(ServletContextEvent sce) {

            super.contextInitialized(sce);

            final ServletContext context = sce.getServletContext();

            final WarConfiguration warConfiguration = buildCustomWarConfiguration(context);
            final WireMockApp wireMockApp = new WireMockApp(warConfiguration, new NotImplementedContainer());

            context.setAttribute(APP_CONTEXT_KEY, wireMockApp);
            context.setAttribute(StubRequestHandler.class.getName(), wireMockApp.buildStubRequestHandler());
            context.setAttribute(AdminRequestHandler.class.getName(), wireMockApp.buildAdminRequestHandler());
        }

        private WarConfiguration buildCustomWarConfiguration(final ServletContext context) {

            final Map<String, Extension> map = abstractResponseDefinitionTransformers.stream()
                    .collect(Collectors.toMap(AbstractResponseDefinitionTransformer::getName, transformer -> transformer));

            return new WarConfiguration(context) {
                @Override
                public <T extends Extension> Map<String, T> extensionsOfType(Class<T> extensionType) {

                    return (Map<String, T>) Maps.filterEntries(map, valueAssignableFrom(extensionType));
                }
            };
        }
}

@Configuration
public class WireMockConfiguration {

    @Autowired
    private List<? extends AbstractResponseDefinitionTransformer> abstractResponseDefinitionTransformers;

    @Bean
    public ServletListenerRegistrationBean wireMockWebContextListener() {
        final ServletListenerRegistrationBean bean = new ServletListenerRegistrationBean();
        bean.setEnabled(true);
        bean.setListener(new CustomWireMockWebContextListener(abstractResponseDefinitionTransformers));
        return bean;
    }
}

【讨论】:

  • 这个答案从@user1697113 stackoverflow.com/a/54860279/2015965的上述答案中获得了一些灵感
  • 正如我在上述答案的评论中提到的,这是很久以前的事了。但希望它可以帮助某人。也许我在以后的时间。谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多