问题
In my unit tests we find
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"))));
cf. Spring REST Docs documentation
This generates build/generated-snippets/preprocessed-request/http-request.adoc
with the content
[source,http]
----
POST /authenticate HTTP/1.1
Content-Type: application/x-www-form-urlencoded
username=user%40example.com&password=superSecretPassword
----
But I expect the password to be masked because of replacePattern():
[source,http]
----
POST /authenticate HTTP/1.1
Content-Type: application/x-www-form-urlencoded
username=user%40example.com&password=XXX
----
What can I do?
回答1:
The pattern replacement has no effect due to an unfortunate side-effect of how MockMvc handles request parameters. replacePattern
acts on the content, i.e. body of the request, but MockMvc doesn't actually include the form-encoded parameters in the body.
Spring REST Docs is smart enough to deal with this when it's generating the snippets, e.g. for a form URL encoded POST
request it looks at the parameters to figure out what the request's body should be. It doesn't apply these same smarts when applying replacePattern
.
You can still mask the password by using your own OperationPreprocessor
that changes the parameter map. For example:
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;
}
}
You can then use this new preprocessor in place of 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())));
来源:https://stackoverflow.com/questions/33281509/spring-rest-docs-how-to-replace-parameters