Spring REST 文档:如何替换参数
Spring REST Docs: how to replace parameters
在我的单元测试中我们发现
this.mockMvc
.perform(post("/authenticate")
.contentType(MediaType.APPLICATION_FORM_URLENCODED)
.param("username", "user@example.com")
.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", "user@example.com")
.param("password", "superSecretPassword"))
.andExpect(status().isOk())
.andDo(document("preprocessed-request",
preprocessRequest(maskPassword())));
在我的单元测试中我们发现
this.mockMvc
.perform(post("/authenticate")
.contentType(MediaType.APPLICATION_FORM_URLENCODED)
.param("username", "user@example.com")
.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", "user@example.com")
.param("password", "superSecretPassword"))
.andExpect(status().isOk())
.andDo(document("preprocessed-request",
preprocessRequest(maskPassword())));