'How to add HTTP headers in Microprofile REST client dynamically?

I am developing application, which uses microprofile rest client. And that rest client should send REST request with various http header. Some headers names changes dynamically. My microprofile rest client should be generic, but I did not find how to implement such behaviour. According to the documentation you need to specify all header names in the implementation via annotations and that is not generic. Is there any way how to "hack" it and add HTTP headers programatically?

Thanks in advance

 GenericRestClient genericRestClient = null;
 Map<String, Object> appConfig = context.appConfigs();
 String baseUrl = (String) appConfig.get("restClient.baseUrl");
 path = (String) appConfig.get("restClient.path");
 try {
     genericRestClient = RestClientBuilder.newBuilder()
                .baseUri(new URI(baseUrl)).build(GenericRestClient.class);
 }catch(URISyntaxException e){
      logger.error("",e);
      throw e;
 }

Response response = genericRestClient.sendMessage(path, value);
logger.info("Status: "+response.getStatus());
logger.info("Response body: "+response.getEntity().toString());

Generic rest client code:

@RegisterRestClient
public interface GenericRestClient {
    @POST
    @Path("{path}")
    @Produces("application/json")
    @Consumes("application/json")
    public Response sendMessage(<here should go any map of custom headers>, @PathParam("path") String pathParam, String jsonBody);
}


Solution 1:[1]

According to the spec, you can use a ClientHeadersFactory. Something like this:

public class CustomClientHeadersFactory implements ClientHeadersFactory {
    @Override public MultivaluedMap<String, String> update(
        MultivaluedMap<String, String> incomingHeaders,
        MultivaluedMap<String, String> clientOutgoingHeaders
    ) {
        MultivaluedMap<String, String> returnVal = new MultivaluedHashMap<>();
        returnVal.putAll(clientOutgoingHeaders);
        returnVal.putSingle("MyHeader", "generated");
        return returnVal;
    }
}

@RegisterRestClient
@RegisterClientHeaders(CustomClientHeadersFactory.class)
public interface GenericRestClient {
    ...
}

You can't pass values directly to the ClientHeadersFactory; but you can directly access the headers of an incoming request, if your own service is called via JAX-RS. You can also @Inject anything you need. If this is still not sufficient and you really need to pass things from the service call, you can use a custom @RequestScope bean, e.g.:

@RequestScope
class CustomHeader {
    private String name;
    private String value;

    // getters/setters
}

public class CustomClientHeadersFactory implements ClientHeadersFactory {
    @Inject CustomHeader customHeader;

    @Override public MultivaluedMap<String, String> update(
        MultivaluedMap<String, String> incomingHeaders,
        MultivaluedMap<String, String> clientOutgoingHeaders
    ) {
        MultivaluedMap<String, String> returnVal = new MultivaluedHashMap<>();
        returnVal.putAll(clientOutgoingHeaders);
        returnVal.putSingle(customHeader.getName(), customHeader.getValue());
        return returnVal;
    }
}

class Client {
    @Inject CustomHeader customHeader;

    void call() {
        customHeader.setName("MyHeader");
        customHeader.setValue("generated");

        ...

        Response response = genericRestClient.sendMessage(path, value);
    }
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 rĂ¼-