I have a @Provider which should replace a path variable like this:
@Provider
@Priority(value = 1)
public class SecurityCheckRequestFilter implements ContainerRequestFilter
{
@Override
public void filter(ContainerRequestContext requestContext) throws IOException
{
//CODE
requestContext.getUriInfo().getPathParameters().putSingle("userId", someNewUserId);
}
}
When I debug it, the path variable "userId" seems to be replaced, but at the endpoint later in the workflow (for example /user/{userId}
), the old value appears again. Nothing was replaced. No information about this behaviour in the latest RestEasy doc, but in a very old Resteasy doc, there is an information, that getPathParameters()
returns an unmodifiable list. If it is unmodifiable, why can I replace the value within the provider then?
Nevertheless, the value is not replaced. How can I overwrite an existing path parameter with a new value?
(Sure, I could add the new userId as some header parameter and fetch the information later in the endpoint, but that's not a good solution)
I have a solution now.
It's a little bit cumbersome but it works. First of all, I had to add an additional annotation @PreMatching
. This causes the provider to be executed much earlier in request, so you can manipulate the path before it will be processed. The disadvantage is that I was not able to use PathParameters
anymore, because the placeholder {userId}
was not set at this time. Instead I had to somehow extract the information from the path by path segments:
List<PathSegment> pathSegments = requestContext.getUriInfo().getPathSegments();
Unfortunately, I had the rebuild the whole path from new (including the query parameters!) to change the userId.
String fullPath = requestContext.getUriInfo().getPath();
MultivaluedMap<String, String> queryParameters = requestContext.getUriInfo().getQueryParameters(true);
String modifiedPath = fullPath.replaceFirst(obfuscationId, userId);
UriBuilder uriBuilder = UriBuilder.fromPath(modifiedPath);
queryParameters.forEach((k,v) -> { uriBuilder.queryParam(k, v.get(0)); } );
requestContext.setRequestUri(uriBuilder.build());