How can I avoid RestAssured to multiply my request params when using RequestSpecification?

Author: wedlamelozupCreated Mar 12, 2026Updated Mar 12, 2026

Hello, all! I confess I did some research on this issue, but didn't find anything substancial on the topic to solve my problem.

I have a global configuration for all my tests, that I'm setting in a @BeforeAll tag using JUnit 5, as you can see below:

// Build request specification
        RequestSpecification requestSpec = new RequestSpecBuilder()
                .setBaseUri(EnvironmentConfig.get("base.url"))
                .addHeaders(getHeaders())
                .addHeader("Authorization", "Bearer " + getKeycloakToken())
                .setUrlEncodingEnabled(false)
                .setConfig(config()
                        .objectMapperConfig(
                                io.restassured.config.ObjectMapperConfig.objectMapperConfig()
                                        .defaultObjectMapperType(ObjectMapperType.JACKSON_2)
                                        .jackson2ObjectMapperFactory((cls, charset) -> objectMapper)
                        )
                        .encoderConfig(
                                encoderConfig().appendDefaultContentCharsetToContentTypeIfUndefined(false)
                        ))
                .build();

The headers should be the same for all requests, so I coded a sendRequest method that does what follows:

public Response executeRequest(RequestParameters requestParameters, RequestSpecification specification) {
        if (requestParameters.getQueryParams() != null) {
            prepareRequestQueryParams(requestParameters, specification);
        }

        if (requestParameters.getBody() != null) {
            prepareRequestBody(requestParameters, specification);
        }

        if (requestParameters.getPathParams() != null && !requestParameters.getPathParams().isEmpty()) {
            for (Map.Entry<String, String> entry : requestParameters.getPathParams().entrySet()) {
                System.out.println("key: " + entry.getKey() + "value: " + entry.getValue());
                specification.pathParam(entry.getKey(), entry.getValue());
            }
        }

        //TO DO: Remover quando a API estiver deployada no Gateway
        RestAssured.useRelaxedHTTPSValidation();

        specification.log().all();

        Response response = switch (requestParameters.getMethod()) {
            case Method.GET ->
                    requestParameters.getEndpoint() != null ? specification.when().get(requestParameters.getEndpoint()) : specification.when().get();
            case Method.POST ->
                    requestParameters.getEndpoint() != null ? specification.when().post(requestParameters.getEndpoint()) : specification.when().post();
            case Method.PUT ->
                    requestParameters.getEndpoint() != null ? specification.when().put(requestParameters.getEndpoint()) : specification.when().put();
            case Method.PATCH ->
                    requestParameters.getEndpoint() != null ? specification.when().patch(requestParameters.getEndpoint()) : specification.when().patch();
            case Method.DELETE ->
                    requestParameters.getEndpoint() != null ? specification.when().delete(requestParameters.getEndpoint()) : specification.when().delete();
            default -> throw new IllegalArgumentException("Unsupported HTTP method: " + requestParameters.getMethod());
        };

        response.then().log().all();
        return response;
    }

As you can see, I'm sending the RequestSpecification as one of the method input parameters, because, beyond the global RequestSpecification, I have another one to generate the KeyCloak token. The first problem is... when the tests are run, I get the following exception from this method:

Before All/After All failed
java.lang.NullPointerException: Cannot invoke method log() on null object
	at org.codehaus.groovy.runtime.NullObject.invokeMethod(NullObject.java:115)
	at org.codehaus.groovy.vmplugin.v8.IndyGuardsFiltersAndSignatures.invokeGroovyObjectInvoker(IndyGuardsFiltersAndSignatures.java:151)
	at org.codehaus.groovy.vmplugin.v8.IndyInterface.fromCache(IndyInterface.java:344)
	at io.restassured.internal.RequestSpecificationImpl.applyPathParamsAndSendRequest(RequestSpecificationImpl.groovy:1770)
	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
	at java.base/java.lang.reflect.Method.invoke(Method.java:580)
	at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:338)
	at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:274)

So, to bypass this problem, I did the following changes in the method:

RequestSpecification local = RestAssured.given(specification);

        if (requestParameters.getQueryParams() != null) {
            prepareRequestQueryParams(requestParameters, local);
        }

        if (requestParameters.getBody() != null) {
            prepareRequestBody(requestParameters, local);
        }

        if (requestParameters.getPathParams() != null && !requestParameters.getPathParams().isEmpty()) {
            for (Map.Entry<String, String> entry : requestParameters.getPathParams().entrySet()) {
                System.out.println("key: " + entry.getKey() + "value: " + entry.getValue());
                local.pathParam(entry.getKey(), entry.getValue());
            }
        }

        //TO DO: Remover quando a API estiver deployada no Gateway
        RestAssured.useRelaxedHTTPSValidation();

        local.log().all();

        Response response = switch (requestParameters.getMethod()) {
            case Method.GET ->
                    requestParameters.getEndpoint() != null ? local.when().get(requestParameters.getEndpoint()) : local.when().get();
            case Method.POST ->
                    requestParameters.getEndpoint() != null ? local.when().post(requestParameters.getEndpoint()) : local.when().post();
            case Method.PUT ->
                    requestParameters.getEndpoint() != null ? local.when().put(requestParameters.getEndpoint()) : local.when().put();
            case Method.PATCH ->
                    requestParameters.getEndpoint() != null ? local.when().patch(requestParameters.getEndpoint()) : local.when().patch();
            case Method.DELETE ->
                    requestParameters.getEndpoint() != null ? local.when().delete(requestParameters.getEndpoint()) : local.when().delete();
            default -> throw new IllegalArgumentException("Unsupported HTTP method: " + requestParameters.getMethod());
        };

        response.then().log().all();
        return response;
    }

The problem now is that my headers are duplicated! I have two copies for each header that I added previously.

Can you guys help me solve this problem?! What can I do to avoid RestAssured of duplicating my request headers?!

Source: rest-assured/rest-assured