java - Spring REST 文档 : how to replace parameters

标签 java spring spring-mvc spring-restdocs

在我的单元测试中我们发现

this.mockMvc
  .perform(post("/authenticate")
    .contentType(MediaType.APPLICATION_FORM_URLENCODED)
    .param("username", "<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="196c6a7c6b597c61787469757c377a7674" rel="noreferrer noopener nofollow">[email protected]</a>")
    .param("password", "superSecretPassword"))
  .andExpect(status().isOk())
  .andDo(document("preprocessed-request",
    preprocessRequest(replacePattern(Pattern.compile("superSecretPassword"), "XXX"))));

比照。 Spring REST Docs documentation

这会生成包含内容的build/generated-snippets/preprocessed-request/http-request.adoc

[source,http]
----
POST /authenticate HTTP/1.1
Content-Type: application/x-www-form-urlencoded

username=user%40example.com&password=superSecretPassword
----

但我希望由于replacePattern()而屏蔽密码:

[source,http]
----
POST /authenticate HTTP/1.1
Content-Type: application/x-www-form-urlencoded

username=user%40example.com&password=XXX
----

我能做什么?

最佳答案

由于 MockMvc 处理请求参数的方式存在不幸的副作用,模式替换没有任何效果。 replacePattern 作用于内容,即请求的主体,但 MockMvc 实际上并不在主体中包含表单编码的参数。

Spring REST Docs 足够聪明,可以在生成片段时处理这个问题,例如对于表单 URL 编码的 POST 请求,它会查看参数来确定请求的正文应该是什么。应用 replacePattern 时,它不会应用这些相同的智能。

您仍然可以使用自己的 OperationPreprocessor 来更改参数映射来屏蔽密码。例如:

private OperationPreprocessor maskPassword() {
    return new PasswordMaskingPreprocessor();
}

private static class PasswordMaskingPreprocessor implements OperationPreprocessor {

    @Override
    public OperationRequest preprocess(OperationRequest request) {
        Parameters parameters = new Parameters();
        parameters.putAll(request.getParameters());
        parameters.set("password", "XXX");
        return new OperationRequestFactory().create(request.getUri(),
                request.getMethod(), request.getContent(), request.getHeaders(),
                parameters, request.getParts());
    }

    @Override
    public OperationResponse preprocess(OperationResponse response) {
        return response;
    }

}

然后您可以使用这个新的预处理器来代替 replacePattern:

this.mockMvc
  .perform(post("/authenticate")
    .contentType(MediaType.APPLICATION_FORM_URLENCODED)
    .param("username", "<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="a2d7d1c7d0e2c7dac3cfd2cec78cc1cdcf" rel="noreferrer noopener nofollow">[email protected]</a>")
    .param("password", "superSecretPassword"))
  .andExpect(status().isOk())
  .andDo(document("preprocessed-request",
    preprocessRequest(maskPassword())));

关于java - Spring REST 文档 : how to replace parameters,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33281509/

相关文章:

java - 从 Java 程序运行时 Adb 权限被拒绝

java - 在网络级别合并的 TCP 数据包

java - 数据库的 SQLiteConnection 对象被泄露!请修复您的应用程序

java - 只是想知道 spring mvc 与 django 之间的区别

java - Spring MVC @RequestBody 进入接口(interface)而不是类

java - 数组自增语法

java - Spring Cloud Dataflow Local Server需要连接zookeeper吗?

java - 处理 Spring/Tomcat 初始化失败

java - Spring-boot用jackson改变json响应结构

java - 想要创建一个过滤器来检查 cookie,然后从 Controller 保存对象和引用