Spring Boot OpenFeign headers ignored

349 Views Asked by At

I am trying to create a feign client so my project can communicate with my company's microservice. I have added the required headers using the @Headers annotation but Spring seems to ignore them. Code:

@FeignClient(
        name = "test-client",
        url = "https://example-api-development.dev.company.ai"
)

public interface TestClient {
    @Headers({
            "Content-Type: application/json",
            "Accept: application/json",
            "Authorization: My-Auth-Key",
            "X-TenantID: test"
    })
    @PostMapping("/")
    String sendFiles();
}

On the above example I am getting response code 401, unauthorized. As a workaround I can add the headers in a map and pass them as an argument like this: @RequestHeader Map<String, String> headerMap. Another workaround is creating a feignConfig class and adding the request headers there using a RequestInterceptor. But why is the @Headers annotation not working?

Edit: I am using Java 17 and Spring Boot 3.0.2

1

There are 1 best solutions below

0
On

Because the Contract that handles feign's native annotations has been replaced by spring's SpringMvcContract to handle spring's own annotations, you can use the RequestHeader annotation to pass header parameters.

If you must use Headers annotations, you can customize a SpringMvcContract bean as below

@Component
public class CustomSpringMvcContract extends SpringMvcContract {

    @Override
    protected void processAnnotationOnMethod(MethodMetadata data, Annotation methodAnnotation, Method method) {
        super.processAnnotationOnMethod(data, methodAnnotation, method);
        if (methodAnnotation instanceof Headers headers) {
            data.template().headers(toMap(headers.value()));
        }
    }

    private static Map<String, Collection<String>> toMap(String[] input) {
        Map<String, Collection<String>> result = new LinkedHashMap<>(input.length);
        for (String header : input) {
            int colon = header.indexOf(':');
            String name = header.substring(0, colon);
            if (!result.containsKey(name)) {
                result.put(name, new ArrayList<String>(1));
            }
            result.get(name).add(header.substring(colon + 1).trim());
        }
        return result;
    }
}